GMX v2 - Trading (#7)

* Move PrivateKeys.cs

* Update gitignore

* Update gitignore

* updt

* Extract GmxServiceTests.cs

* Refact

* update todo

* Update code

* Fix hashdata

* Replace static token hashed datas

* Set allowance

* Add get orders

* Add get orders tests

* Add ignore

* add close orders

* revert

* Add get gas limit

* Start increasePosition. Todo: Finish GetExecutionFee and estimateGas

* little refact

* Update gitignore

* Fix namespaces and clean repo

* Add tests samples

* Add execution fee

* Add increase position

* Handle backtest on the frontend

* Add tests

* Update increase

* Test increase

* fix increase

* Fix size

* Start get position

* Update get positions

* Fix get position

* Update rpc and trade mappers

* Finish close position

* Fix leverage
This commit is contained in:
Oda
2025-01-30 23:06:22 +07:00
committed by GitHub
parent ecaa89c67b
commit 65bdb8e34f
156 changed files with 11253 additions and 4073 deletions

View File

@@ -22,6 +22,8 @@ const LogIn = () => {
const message = 'wagmi'
const signature = await signMessageAsync({ message })
const t = new Toast('Creating token')
console.log(t)
if (signature && address) {
const userClient = new UserClient({}, apiUrl)
@@ -38,7 +40,7 @@ const LogIn = () => {
location.reload()
})
.catch((err: any) => {
t.update('error', 'Error :' + err.message)
t.update('error', 'Error : Some thing bad happen')
})
}else{
t.update('error', 'Error : No signature')

View File

@@ -53,6 +53,7 @@ function daysBetween(date: Date) {
}
const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
console.log(list)
const { apiUrl } = useApiUrlStore()
const [showMoneyManagementModal, setShowMoneyManagementModal] =
React.useState(false)
@@ -118,7 +119,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
return (
<div className="flex flex-wrap m-4 -mx-4">
{list.map((backtest: Backtest, index) => (
{list?.map((backtest: Backtest, index) => (
<div
key={index.toString()}
className="sm:w-1/2 md:w-1/2 xl:w-1/2 w-full p-2"

View File

@@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react'
import { useForm, type SubmitHandler } from 'react-hook-form'
import useApiUrlStore from '../../../app/store/apiStore'
import type {
import {
Backtest,
MoneyManagement,
Ticker,
@@ -125,13 +125,14 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
}
function onMoneyManagementChange(e: any) {
console.log(e.target.value)
if (e.target.value == 'Custom') {
setShowCustomMoneyManagement(true)
setSelectedMoneyManagement(e.target.value)
} else {
setShowCustomMoneyManagement(false)
setCustomMoneyManagement(undefined)
setSelectedMoneyManagement(undefined)
setSelectedMoneyManagement(e.target.value)
}
}
@@ -156,7 +157,8 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
enabled: !!selectedAccount && !!selectedTimeframe,
queryFn: () => {
if (selectedAccount && selectedTimeframe) {
return dataClient.data_GetTickers(selectedAccount, selectedTimeframe)
// return dataClient.data_GetTickers(selectedAccount, selectedTimeframe)
return [Ticker.BTC]
}
},
queryKey: ['tickers', selectedAccount, selectedTimeframe],

View File

@@ -4,9 +4,9 @@ import type {
UsePaginationState,
UseSortByInstanceProps,
} from 'react-table'
import type { Edge, Node, Position } from 'reactflow'
import type { Edge, Node } from 'reactflow'
import type { Account, AccountType, Backtest, Balance, BotType, Candle, FlowOutput, FlowType, IFlow, KeyValuePairOfDateTimeAndDecimal, MoneyManagement, RiskLevel, Scenario, Signal, Ticker, Timeframe, TradeDirection, TradingBot, TradingExchanges } from '../generated/ManagingApi'
import type { Account, AccountType, Backtest, Balance, BotType, Candle, FlowOutput, FlowType, IFlow, KeyValuePairOfDateTimeAndDecimal, MoneyManagement, Position, RiskLevel, Scenario, Signal, Ticker, Timeframe, TradeDirection, TradingBot, TradingExchanges } from '../generated/ManagingApi'
import { ReactNode, FC } from 'react'
export type TabsType = {
label: string

View File

@@ -13,17 +13,6 @@ const LayoutMain = (): JSX.Element => {
<Outlet />
</div>
</main>
<ToastContainer
position="top-right"
autoClose={10000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</>
)
}

View File

@@ -11,6 +11,7 @@ import App from './app'
import 'react-grid-layout/css/styles.css'
import 'react-resizable/css/styles.css'
import 'react-toastify/dist/ReactToastify.css'
import { ToastContainer } from 'react-toastify'
const config = createConfig(
getDefaultConfig({
@@ -31,6 +32,17 @@ root.render(
<ConnectKitProvider theme="auto">
<BrowserRouter>
<App />
<ToastContainer
position="top-right"
autoClose={10000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</BrowserRouter>
</ConnectKitProvider>
</WagmiConfig>

View File

@@ -7,6 +7,7 @@ import type { TabsType } from '../../global/type'
import BacktestLoop from './backtestLoop'
import BacktestPlayground from './backtestPlayground'
import BacktestScanner from './backtestScanner'
import BacktestUpload from './backtestUpload'
// Tabs Array
const tabs: TabsType = [
@@ -25,6 +26,11 @@ const tabs: TabsType = [
index: 3,
label: 'Loop',
},
{
Component: BacktestUpload,
index: 4,
label: 'Upload',
},
]
const Backtest: React.FC = () => {

View File

@@ -0,0 +1,102 @@
import React, { useState } from 'react'
import { BacktestCards } from '../../components/organism'
import type { Backtest, Candle, Position, Trade } from '../../generated/ManagingApi'
import { Toast } from '../../components/mollecules'
const BacktestUpload: React.FC = () => {
const [backtestingResult, setBacktests] = useState<Backtest[]>([])
const handleFileUpload = (event: any) => {
let t = new Toast('Uploading backtest file')
const file = event.target.files[0];
const reader = new FileReader();
if (file == null)
return;
reader.onload = (event) => {
try {
const json = JSON.parse(event.target.result);
let backtest = MapBacktest(json)
console.log(backtest)
setBacktests((arr) => [...arr, backtest]);
t.update("success", 'Backtest uploaded')
} catch (error) {
console.error('Error parsing JSON file:', error);
t.update('error', 'Cannot parse file')
}
};
reader.readAsText(file);
};
return (
<div className="container mx-auto">
<input type="file" accept=".json" onChange={handleFileUpload} />
<BacktestCards list={backtestingResult} setBacktests={setBacktests} />
</div>
)
}
function MapBacktest(json: any){
let backtest = {} as Backtest
backtest.candles = MapCandles(json.Candles)
backtest.accountName = json.AccountName
backtest.botType = json.BotType
backtest.fees = json.Fees
backtest.finalPnl = json.FinalPnl
backtest.growthPercentage = json.GrowthPercentage
backtest.hodlPercentage = json.HodlPercentage
backtest.moneyManagement = json.MoneyManagement
backtest.optimizedMoneyManagement = json.OptimizedMoneyManagement
backtest.positions = MapPositions(json.Positions)
backtest.scenario = json.Scenario
backtest.signals = json.Signals
backtest.statistics = json.Statistics
backtest.ticker = json.Ticker
backtest.timeframe = json.Timeframe
backtest.walletBalances = json.WalletBalances
backtest.winRate = json.WinRate
backtest.statistics = json.Statistics
return backtest
}
function MapCandles(candlesInput: any): Candle[] {
let candles = [] as Candle[]
candlesInput.forEach( (c: any) => {
let candle = {} as Candle
candle.close = c.Close
candle.high = c.High
candle.low = c.Low
candle.open = c.Open,
candle.openTime = c.OpenTime
candles.push(candle)
});
return candles
}
function MapPositions(positionsInput: any): Position[]{
let positions = [] as Position[]
positionsInput.forEach(
(p: any) => {
let position = {} as Position
position.date = p.Date
position.identifier = p.Identifier
position.open = MapTrade(p.Open)
position.originDirection = p.OriginDirection
position.stopLoss = MapTrade(p.StopLoss)
position.takeProfit1 = MapTrade(p.TakeProfit1)
});
return positions
}
function MapTrade(openInput: any): Trade{
let open = {} as Trade
open.price = openInput.Price
return open
}
export default BacktestUpload

View File

@@ -44,6 +44,11 @@ const MoneyManagementTable: React.FC<IMoneyManagementList> = ({ list }) => {
const columns = React.useMemo(
() => [
{
Header: 'Name',
accessor: 'name',
disableSortBy: true,
},
{
Filter: SelectColumnFilter,
Header: 'Timeframe',