Synth api (#28)

* Add synthApi

* Put confidence for Synth proba

* Update the code

* Update readme

* Fix bootstraping

* fix github build

* Update the endpoints for scenario

* Add scenario and update backtest modal

* Update bot modal

* Update interfaces for synth

* add synth to backtest

* Add Kelly criterion and better signal

* Update signal confidence

* update doc

* save leaderboard and prediction

* Update nswag to generate ApiClient in the correct path

* Unify the trading modal

* Save miner and prediction

* Update messaging and block new signal until position not close when flipping off

* Rename strategies to indicators

* Update doc

* Update chart + add signal name

* Fix signal direction

* Update docker webui

* remove crypto npm

* Clean

* Fix mobile a bit
This commit is contained in:
Oda
2025-07-03 15:00:59 +07:00
committed by GitHub
parent a547c4a040
commit 88f195c0ca
11 changed files with 141 additions and 58 deletions

View File

@@ -1,9 +1,9 @@
import { create } from 'zustand' import {create} from 'zustand'
import type { MoneyManagement } from '../../generated/ManagingApi' import type {MoneyManagement} from '../../generated/ManagingApi'
type CustomMoneyManagementStore = { type CustomMoneyManagementStore = {
setCustomMoneyManagement: (custom: MoneyManagement) => void setCustomMoneyManagement: (custom: MoneyManagement | null) => void
moneyManagement: MoneyManagement | null moneyManagement: MoneyManagement | null
} }

View File

@@ -3,7 +3,7 @@ import {create} from 'zustand'
import type {Scenario} from '../../generated/ManagingApi' import type {Scenario} from '../../generated/ManagingApi'
type CustomScenarioStore = { type CustomScenarioStore = {
setCustomScenario: (custom: Scenario) => void setCustomScenario: (custom: Scenario | null) => void
scenario: Scenario | null scenario: Scenario | null
} }

View File

@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import type {IModalProps} from '../../../global/type' import type {IModalProps} from '../../../global/type.tsx'
import ModalHeader from './ModalHeader' import ModalHeader from './ModalHeader'

View File

@@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import type { IModalProps } from '../../../global/type' import type {IModalProps} from '../../../global/type.tsx'
const ModalHeader: React.FC<IModalProps> = ({ onClose, titleHeader }: any) => { const ModalHeader: React.FC<IModalProps> = ({ onClose, titleHeader }: any) => {
return ( return (

View File

@@ -9,10 +9,11 @@ import type {
MoneyManagement, MoneyManagement,
RunBacktestRequest, RunBacktestRequest,
StartBotRequest, StartBotRequest,
TradingBotConfig TradingBotConfig,
TradingBotConfigRequest
} from '../../../generated/ManagingApi' } from '../../../generated/ManagingApi'
import {BacktestClient, BotClient, MoneyManagementClient} from '../../../generated/ManagingApi' import {BacktestClient, BotClient, MoneyManagementClient} from '../../../generated/ManagingApi'
import type {IBacktestCards} from '../../../global/type' import type {IBacktestCards} from '../../../global/type.tsx'
import MoneyManagementModal from '../../../pages/settingsPage/moneymanagement/moneyManagementModal' import MoneyManagementModal from '../../../pages/settingsPage/moneymanagement/moneyManagementModal'
import {CardPosition, CardText, Toast} from '../../mollecules' import {CardPosition, CardText, Toast} from '../../mollecules'
import CardPositionItem from '../Trading/CardPositionItem' import CardPositionItem from '../Trading/CardPositionItem'
@@ -119,9 +120,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
}; };
const request: StartBotRequest = { const request: StartBotRequest = {
config: tradingBotConfig, config: tradingBotConfig as unknown as TradingBotConfigRequest,
// Only use the money management name if it's not a custom money management
moneyManagementName: isCustomMoneyManagement ? undefined : moneyManagementName
} }
await client await client
@@ -165,21 +164,19 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
} }
const request: RunBacktestRequest = { const request: RunBacktestRequest = {
config: optimizedConfig, config: optimizedConfig as unknown as TradingBotConfigRequest,
startDate: startDate, startDate: startDate,
endDate: endDate, endDate: endDate,
balance: backtest.walletBalances[0].value, balance: backtest.walletBalances[0].value,
watchOnly: false, watchOnly: false,
save: false, save: false,
moneyManagementName: undefined, // We're passing the moneyManagement object directly
moneyManagement: optimizedConfig.moneyManagement
} }
await client await client
.backtest_Run(request) .backtest_Run(request)
.then((backtest: Backtest) => { .then((backtest: Backtest) => {
t.update('success', `${backtest.config.ticker} Backtest Succeeded`) t.update('success', `${backtest.config.ticker} Backtest Succeeded`)
setBacktests((arr) => [...arr, backtest]) setBacktests((arr: Backtest[]) => [...arr, backtest])
}) })
.catch((err) => { .catch((err) => {
t.update('error', 'Error :' + err) t.update('error', 'Error :' + err)
@@ -193,7 +190,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
return ( return (
<div className="flex flex-wrap m-4 -mx-4"> <div className="flex flex-wrap m-4 -mx-4">
{list?.map((backtest: Backtest, index) => ( {list?.map((backtest: Backtest, index: number) => (
<div <div
key={index.toString()} key={index.toString()}
className="sm:w-1/2 md:w-1/2 xl:w-1/2 w-full p-2" className="sm:w-1/2 md:w-1/2 xl:w-1/2 w-full p-2"
@@ -213,7 +210,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
positions={backtest.positions} positions={backtest.positions}
walletBalances={backtest.walletBalances} walletBalances={backtest.walletBalances}
signals={backtest.signals} signals={backtest.signals}
strategiesValues={backtest.strategiesValues} indicatorsValues={backtest.indicatorsValues}
width={720} width={720}
height={512} height={512}
></TradeChart> ></TradeChart>

View File

@@ -1,8 +1,8 @@
import React, {useEffect, useState} from 'react' import React, {useEffect, useState} from 'react'
import type {Backtest, MoneyManagement} from '../../../generated/ManagingApi' import type {Backtest, MoneyManagement} from '../../../generated/ManagingApi'
import type {IModalProps} from '../../../global/type'
import {Modal} from '../../mollecules' import {Modal} from '../../mollecules'
import type {IModalProps} from '../../../global/type.tsx'
interface IBotNameModalProps extends IModalProps { interface IBotNameModalProps extends IModalProps {
backtest: Backtest backtest: Backtest

View File

@@ -258,7 +258,7 @@ const CustomScenario: React.FC<ICustomScenario> = ({
</div> </div>
{/* Dynamic parameter inputs based on indicator type */} {/* Dynamic parameter inputs based on indicator type */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-3"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3">
{getRequiredParams(indicator.type || indicatorTypes[0].type).map((param) => ( {getRequiredParams(indicator.type || indicatorTypes[0].type).map((param) => (
<FormInput key={param} label={param.charAt(0).toUpperCase() + param.slice(1)} htmlFor={`${param}-${index}`} inline={false}> <FormInput key={param} label={param.charAt(0).toUpperCase() + param.slice(1)} htmlFor={`${param}-${index}`} inline={false}>
<input <input

View File

@@ -3,6 +3,8 @@ import React, {useEffect, useState} from 'react'
import {type SubmitHandler, useForm} from 'react-hook-form' import {type SubmitHandler, useForm} from 'react-hook-form'
import useApiUrlStore from '../../../app/store/apiStore' import useApiUrlStore from '../../../app/store/apiStore'
import {useCustomMoneyManagement} from '../../../app/store/customMoneyManagement'
import {useCustomScenario} from '../../../app/store/customScenario'
import { import {
AccountClient, AccountClient,
BacktestClient, BacktestClient,
@@ -136,6 +138,8 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
const [selectedTicker, setSelectedTicker] = useState<Ticker | undefined>(undefined); const [selectedTicker, setSelectedTicker] = useState<Ticker | undefined>(undefined);
const { apiUrl } = useApiUrlStore(); const { apiUrl } = useApiUrlStore();
const { setCustomMoneyManagement: setGlobalCustomMoneyManagement } = useCustomMoneyManagement();
const { setCustomScenario: setGlobalCustomScenario } = useCustomScenario();
// API clients // API clients
const scenarioClient = new ScenarioClient({}, apiUrl); const scenarioClient = new ScenarioClient({}, apiUrl);
@@ -185,6 +189,18 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
setSelectedTicker(backtest.config.ticker); setSelectedTicker(backtest.config.ticker);
} }
setValue('scenarioName', backtest.config.scenarioName || ''); setValue('scenarioName', backtest.config.scenarioName || '');
// Handle custom scenario from backtest
if ((backtest.config as any).scenario) {
setShowCustomScenario(true);
setCustomScenario((backtest.config as any).scenario);
setGlobalCustomScenario((backtest.config as any).scenario); // Also update global store for prefilling
setSelectedScenario('custom');
} else if (backtest.config.scenarioName) {
setSelectedScenario(backtest.config.scenarioName);
setShowCustomScenario(false);
}
setValue('timeframe', backtest.config.timeframe); setValue('timeframe', backtest.config.timeframe);
setValue('botType', backtest.config.botType); setValue('botType', backtest.config.botType);
setValue('cooldownPeriod', backtest.config.cooldownPeriod); setValue('cooldownPeriod', backtest.config.cooldownPeriod);
@@ -203,11 +219,31 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
if (backtest.config.moneyManagement) { if (backtest.config.moneyManagement) {
setShowCustomMoneyManagement(true); setShowCustomMoneyManagement(true);
setCustomMoneyManagement(backtest.config.moneyManagement); setCustomMoneyManagement(backtest.config.moneyManagement);
// Convert decimal values to percentages for UI display
const formattedMoneyManagement = {
...backtest.config.moneyManagement,
stopLoss: backtest.config.moneyManagement.stopLoss * 100,
takeProfit: backtest.config.moneyManagement.takeProfit * 100,
};
setGlobalCustomMoneyManagement(formattedMoneyManagement);
} }
} else if (mode === 'backtest' && backtest) { } else if (mode === 'backtest' && backtest) {
// Initialize from existing backtest for re-running // Initialize from existing backtest for re-running
setValue('accountName', backtest.config.accountName); setValue('accountName', backtest.config.accountName);
setValue('scenarioName', backtest.config.scenarioName || ''); setValue('scenarioName', backtest.config.scenarioName || '');
// Handle custom scenario from backtest
if ((backtest.config as any).scenario) {
setShowCustomScenario(true);
setCustomScenario((backtest.config as any).scenario);
setGlobalCustomScenario((backtest.config as any).scenario); // Also update global store for prefilling
setSelectedScenario('custom');
} else if (backtest.config.scenarioName) {
setSelectedScenario(backtest.config.scenarioName);
setShowCustomScenario(false);
}
setValue('timeframe', backtest.config.timeframe); setValue('timeframe', backtest.config.timeframe);
setValue('botType', backtest.config.botType); setValue('botType', backtest.config.botType);
setValue('cooldownPeriod', backtest.config.cooldownPeriod); setValue('cooldownPeriod', backtest.config.cooldownPeriod);
@@ -243,6 +279,14 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
if (backtest.config.moneyManagement) { if (backtest.config.moneyManagement) {
setShowCustomMoneyManagement(true); setShowCustomMoneyManagement(true);
setCustomMoneyManagement(backtest.config.moneyManagement); setCustomMoneyManagement(backtest.config.moneyManagement);
// Convert decimal values to percentages for UI display
const formattedMoneyManagement = {
...backtest.config.moneyManagement,
stopLoss: backtest.config.moneyManagement.stopLoss * 100,
takeProfit: backtest.config.moneyManagement.takeProfit * 100,
};
setGlobalCustomMoneyManagement(formattedMoneyManagement);
} }
// Handle risk management // Handle risk management
@@ -274,6 +318,33 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
setValue('useForSignalFiltering', config.useForSignalFiltering ?? true); setValue('useForSignalFiltering', config.useForSignalFiltering ?? true);
setValue('useForDynamicStopLoss', config.useForDynamicStopLoss ?? true); setValue('useForDynamicStopLoss', config.useForDynamicStopLoss ?? true);
// Handle money management - if it exists, treat as custom for update mode
if (config.moneyManagement) {
setShowCustomMoneyManagement(true);
setCustomMoneyManagement(config.moneyManagement);
// Convert decimal values to percentages for UI display
const formattedMoneyManagement = {
...config.moneyManagement,
stopLoss: config.moneyManagement.stopLoss * 100,
takeProfit: config.moneyManagement.takeProfit * 100,
};
setGlobalCustomMoneyManagement(formattedMoneyManagement);
setSelectedMoneyManagement('custom'); // Set dropdown to show "custom"
}
// Handle scenario - check if we have scenario data or just a name reference
if ((config as any).scenario) {
setShowCustomScenario(true);
setCustomScenario((config as any).scenario);
setGlobalCustomScenario((config as any).scenario); // Also update global store for prefilling
setSelectedScenario('custom'); // Set dropdown to show "custom"
} else if (config.scenarioName) {
setValue('scenarioName', config.scenarioName);
setSelectedScenario(config.scenarioName);
setShowCustomScenario(false);
}
// Handle risk management // Handle risk management
if (config.riskManagement) { if (config.riskManagement) {
setValue('useCustomRiskManagement', true); setValue('useCustomRiskManagement', true);
@@ -373,9 +444,11 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
if (e.target.value === 'custom') { if (e.target.value === 'custom') {
setShowCustomMoneyManagement(true); setShowCustomMoneyManagement(true);
setCustomMoneyManagement(undefined); setCustomMoneyManagement(undefined);
setGlobalCustomMoneyManagement(null); // Clear global store when creating new custom
} else { } else {
setShowCustomMoneyManagement(false); setShowCustomMoneyManagement(false);
setCustomMoneyManagement(undefined); setCustomMoneyManagement(undefined);
setGlobalCustomMoneyManagement(null); // Clear global store when switching away from custom
setSelectedMoneyManagement(e.target.value); setSelectedMoneyManagement(e.target.value);
} }
}; };
@@ -384,9 +457,11 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
if (e.target.value === 'custom') { if (e.target.value === 'custom') {
setShowCustomScenario(true); setShowCustomScenario(true);
setCustomScenario(undefined); setCustomScenario(undefined);
setGlobalCustomScenario(null); // Clear global store when creating new custom
} else { } else {
setShowCustomScenario(false); setShowCustomScenario(false);
setCustomScenario(undefined); setCustomScenario(undefined);
setGlobalCustomScenario(null); // Clear global store when switching away from custom
setSelectedScenario(e.target.value); setSelectedScenario(e.target.value);
setValue('scenarioName', e.target.value); setValue('scenarioName', e.target.value);
} }
@@ -612,7 +687,7 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
)} )}
{/* First Row: Account & Timeframe */} {/* First Row: Account & Timeframe */}
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput label="Account" htmlFor="accountName"> <FormInput label="Account" htmlFor="accountName">
<select <select
className="select select-bordered w-full" className="select select-bordered w-full"
@@ -650,10 +725,11 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
</div> </div>
{/* Second Row: Money Management & Bot Type */} {/* Second Row: Money Management & Bot Type */}
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput label="Money Management" htmlFor="moneyManagement"> <FormInput label="Money Management" htmlFor="moneyManagement">
<select <select
className="select select-bordered w-full" className="select select-bordered w-full"
value={selectedMoneyManagement || (showCustomMoneyManagement ? 'custom' : '')}
onChange={onMoneyManagementChange} onChange={onMoneyManagementChange}
> >
{moneyManagements.length === 0 ? ( {moneyManagements.length === 0 ? (
@@ -704,6 +780,7 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
<select <select
className="select select-bordered w-full" className="select select-bordered w-full"
{...register('scenarioName')} {...register('scenarioName')}
value={selectedScenario || (showCustomScenario ? 'custom' : '')}
onChange={onScenarioChange} onChange={onScenarioChange}
> >
{scenarios.length === 0 ? ( {scenarios.length === 0 ? (
@@ -854,7 +931,7 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
{/* Dates for backtests */} {/* Dates for backtests */}
{mode === 'backtest' && ( {mode === 'backtest' && (
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput label="Start Date" htmlFor="startDate"> <FormInput label="Start Date" htmlFor="startDate">
<input <input
type="date" type="date"
@@ -899,13 +976,13 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
min="1" min="1"
max="10" max="10"
value={selectedLoopQuantity.toString()} value={selectedLoopQuantity.toString()}
onChange={(e) => setLoopQuantity(Number(e.target.value))} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setLoopQuantity(Number(e.target.value))}
/> />
</FormInput> </FormInput>
)} )}
{/* Max Loss Streak & Max Position Time */} {/* Max Loss Streak & Max Position Time */}
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput <FormInput
label={ label={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -949,7 +1026,7 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
</div> </div>
{/* Trading Options */} {/* Trading Options */}
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput <FormInput
label={ label={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -1179,7 +1256,7 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
</FormInput> </FormInput>
{/* Risk Management Parameters Grid */} {/* Risk Management Parameters Grid */}
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput <FormInput
label={ label={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -1350,7 +1427,7 @@ const UnifiedTradingModal: React.FC<UnifiedTradingModalProps> = ({
</div> </div>
{/* Checkboxes for Kelly and Expected Utility */} {/* Checkboxes for Kelly and Expected Utility */}
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormInput <FormInput
label={ label={
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">

View File

@@ -133,7 +133,7 @@ export type IFormInput = {
} }
export type IModalProps = { export type IModalProps = {
showModal?: boolean | undefined showModal: boolean
onSubmit?: React.FormEventHandler onSubmit?: React.FormEventHandler
onClose?: React.FormEventHandler onClose?: React.FormEventHandler
titleHeader?: string titleHeader?: string

View File

@@ -8,11 +8,11 @@ import TradesModal from '../../components/mollecules/TradesModal/TradesModal'
import {TradeChart, UnifiedTradingModal} from '../../components/organism' import {TradeChart, UnifiedTradingModal} from '../../components/organism'
import type {BotType, MoneyManagement, Position, TradingBotResponse} from '../../generated/ManagingApi' import type {BotType, MoneyManagement, Position, TradingBotResponse} from '../../generated/ManagingApi'
import {BotClient} from '../../generated/ManagingApi' import {BotClient} from '../../generated/ManagingApi'
import type {IBotList} from '../../global/type' import type {IBotList} from '../../global/type.tsx'
import MoneyManagementModal from '../settingsPage/moneymanagement/moneyManagementModal' import MoneyManagementModal from '../settingsPage/moneymanagement/moneyManagementModal'
function baseBadgeClass(isOutlined = false) { function baseBadgeClass(isOutlined = false) {
let classes = 'text-xs badge ' let classes = 'text-xs badge badge-sm transition-all duration-200 hover:scale-105 '
if (isOutlined) { if (isOutlined) {
classes += 'badge-outline ' classes += 'badge-outline '
@@ -240,7 +240,7 @@ const BotList: React.FC<IBotList> = ({ list }) => {
</div> </div>
</div> </div>
{list.map((bot: TradingBotResponse, index) => ( {list.map((bot: TradingBotResponse, index: number) => (
<div <div
key={index.toString()} key={index.toString()}
className="sm:w-1 md:w-1/2 xl:w-1/2 w-full p-2" className="sm:w-1 md:w-1/2 xl:w-1/2 w-full p-2"
@@ -258,23 +258,36 @@ const BotList: React.FC<IBotList> = ({ list }) => {
} }
</figure> </figure>
<div className="card-body"> <div className="card-body">
<h2 className="card-title text-sm"> <div className="mb-4">
{/* Bot Name - Always on its own line */}
<h2 className="card-title text-sm mb-3">
{bot.config.ticker} {bot.config.ticker}
</h2>
{/* Badge Container - Responsive */}
<div className="flex flex-wrap gap-1 sm:gap-2">
{/* Info Badges */}
<div className="flex flex-wrap gap-1">
{getMoneyManagementBadge(bot.config.moneyManagement)} {getMoneyManagementBadge(bot.config.moneyManagement)}
{getIsForWatchingBadge(bot.config.isForWatchingOnly, bot.identifier)} {getIsForWatchingBadge(bot.config.isForWatchingOnly, bot.identifier)}
</div>
{/* Action Badges */}
<div className="flex flex-wrap gap-1">
{getToggleBotStatusBadge(bot.status, bot.identifier, bot.config.botType)} {getToggleBotStatusBadge(bot.status, bot.identifier, bot.config.botType)}
{getUpdateBotBadge(bot)} {getUpdateBotBadge(bot)}
{getManualPositionBadge(bot.identifier)} {getManualPositionBadge(bot.identifier)}
{getDeleteBadge(bot.identifier)} {getDeleteBadge(bot.identifier)}
</h2> </div>
</div>
</div>
<div className="columns-2"> <div className="columns-2">
<div> <div>
<div> <div>
<CardText <CardText
title="Scenario" title="Scenario"
content={bot.config.scenarioName} content={bot.config.scenarioName ?? bot.config.scenario?.name}
></CardText> ></CardText>
</div> </div>
</div> </div>

View File

@@ -1,16 +1,12 @@
import { useState } from 'react' import {useState} from 'react'
import type { SubmitHandler } from 'react-hook-form' import type {SubmitHandler} from 'react-hook-form'
import { useForm } from 'react-hook-form' import {useForm} from 'react-hook-form'
import useApiUrlStore from '../../../app/store/apiStore' import useApiUrlStore from '../../../app/store/apiStore'
import { Modal, Toast } from '../../../components/mollecules' import {Modal, Toast} from '../../../components/mollecules'
import type { Account } from '../../../generated/ManagingApi' import type {Account} from '../../../generated/ManagingApi'
import { import {AccountClient, AccountType, TradingExchanges,} from '../../../generated/ManagingApi'
AccountType, import type {IAccountFormInput, IModalProps} from '../../../global/type.tsx'
AccountClient,
TradingExchanges,
} from '../../../generated/ManagingApi'
import type { IAccountFormInput, IModalProps } from '../../../global/type'
const AccountModal: React.FC<IModalProps> = ({ showModal, toggleModal }) => { const AccountModal: React.FC<IModalProps> = ({ showModal, toggleModal }) => {
const [selectedExchange, setSelectedExchange] = useState<TradingExchanges>() const [selectedExchange, setSelectedExchange] = useState<TradingExchanges>()