Balance for bot (#20)
* Add bot balance * Update amount to trade * fix initial trading balance * Update MM modal * fix backtest * stop bot if no more balance * Add constant for minimum trading * Add constant
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
|
||||
import type { Backtest, MoneyManagement } from '../../../generated/ManagingApi'
|
||||
import type { IModalProps } from '../../../global/type'
|
||||
import type {Backtest, MoneyManagement} from '../../../generated/ManagingApi'
|
||||
import type {IModalProps} from '../../../global/type'
|
||||
|
||||
import Modal from './Modal'
|
||||
|
||||
interface IBotNameModalProps extends IModalProps {
|
||||
backtest: Backtest
|
||||
isForWatchOnly: boolean
|
||||
onSubmitBotName: (botName: string, backtest: Backtest, isForWatchOnly: boolean, moneyManagementName: string) => void
|
||||
onSubmitBotName: (botName: string, backtest: Backtest, isForWatchOnly: boolean, moneyManagementName: string, initialTradingBalance: number) => void
|
||||
moneyManagements: MoneyManagement[]
|
||||
selectedMoneyManagement: string
|
||||
setSelectedMoneyManagement: (name: string) => void
|
||||
@@ -25,6 +25,7 @@ const BotNameModal: React.FC<IBotNameModalProps> = ({
|
||||
setSelectedMoneyManagement,
|
||||
}) => {
|
||||
const [botName, setBotName] = useState<string>('')
|
||||
const [initialTradingBalance, setInitialTradingBalance] = useState<number>(1000)
|
||||
|
||||
// Initialize botName when backtest changes
|
||||
useEffect(() => {
|
||||
@@ -35,8 +36,8 @@ const BotNameModal: React.FC<IBotNameModalProps> = ({
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
if (botName.trim()) {
|
||||
onSubmitBotName(botName, backtest, isForWatchOnly, selectedMoneyManagement)
|
||||
if (botName.trim() && initialTradingBalance > 0) {
|
||||
onSubmitBotName(botName, backtest, isForWatchOnly, selectedMoneyManagement, initialTradingBalance)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +86,22 @@ const BotNameModal: React.FC<IBotNameModalProps> = ({
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-control w-full mb-4">
|
||||
<label className="label">
|
||||
<span className="label-text">Initial Trading Balance ($)</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="Enter initial trading balance"
|
||||
className="input input-bordered w-full"
|
||||
value={initialTradingBalance}
|
||||
onChange={(e) => setInitialTradingBalance(Number(e.target.value))}
|
||||
min="10"
|
||||
step="0.01"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-gray-500 mt-2 mb-4">
|
||||
{isForWatchOnly
|
||||
? 'The bot will run in watch-only mode and will not execute trades.'
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
import { DotsVerticalIcon, TrashIcon } from '@heroicons/react/solid'
|
||||
import {DotsVerticalIcon, TrashIcon} from '@heroicons/react/solid'
|
||||
import moment from 'moment'
|
||||
import React from 'react'
|
||||
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import type {
|
||||
Backtest,
|
||||
MoneyManagement,
|
||||
StartBotRequest,
|
||||
Ticker,
|
||||
} from '../../../generated/ManagingApi'
|
||||
import {
|
||||
BacktestClient,
|
||||
BotClient,
|
||||
BotType,
|
||||
} from '../../../generated/ManagingApi'
|
||||
import type { IBacktestCards } from '../../../global/type'
|
||||
import type {Backtest, MoneyManagement, StartBotRequest, Ticker,} from '../../../generated/ManagingApi'
|
||||
import {BacktestClient, BotClient, BotType,} from '../../../generated/ManagingApi'
|
||||
import type {IBacktestCards} from '../../../global/type'
|
||||
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 TradeChart from '../Trading/TradeChart/TradeChart'
|
||||
|
||||
@@ -73,6 +64,7 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
|
||||
scenario: backtest.scenario,
|
||||
ticker: backtest.ticker as Ticker,
|
||||
timeframe: backtest.timeframe,
|
||||
initialTradingBalance: 1000,
|
||||
}
|
||||
|
||||
await client
|
||||
@@ -89,6 +81,10 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
|
||||
const t = new Toast('Optimized backtest is running')
|
||||
const client = new BacktestClient({}, apiUrl)
|
||||
|
||||
// Calculate dates for the API call
|
||||
const startDate = backtest.candles[0].date
|
||||
const endDate = backtest.candles[backtest.candles.length - 1].date
|
||||
|
||||
await client
|
||||
.backtest_Run(
|
||||
backtest.accountName,
|
||||
@@ -96,12 +92,13 @@ const BacktestCards: React.FC<IBacktestCards> = ({ list, setBacktests }) => {
|
||||
backtest.ticker as Ticker,
|
||||
backtest.scenario,
|
||||
backtest.timeframe,
|
||||
false,
|
||||
daysBetween(backtest.candles[0].date),
|
||||
backtest.walletBalances[0].value,
|
||||
'',
|
||||
false,
|
||||
backtest.optimizedMoneyManagement
|
||||
false, // watchOnly
|
||||
backtest.walletBalances[0].value, // balance
|
||||
'', // moneyManagementName (empty since we're passing the optimized moneyManagement object)
|
||||
startDate, // startDate
|
||||
endDate, // endDate
|
||||
false, // save
|
||||
backtest.optimizedMoneyManagement // moneyManagement object
|
||||
)
|
||||
.then((backtest: Backtest) => {
|
||||
t.update('success', `${backtest.ticker} Backtest Succeeded`)
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useForm, type SubmitHandler } from 'react-hook-form'
|
||||
import {useQuery} from '@tanstack/react-query'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {type SubmitHandler, useForm} from 'react-hook-form'
|
||||
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import {
|
||||
Backtest,
|
||||
MoneyManagement,
|
||||
Ticker,
|
||||
AccountClient,
|
||||
Backtest,
|
||||
BacktestClient,
|
||||
BotType,
|
||||
DataClient,
|
||||
MoneyManagement,
|
||||
MoneyManagementClient,
|
||||
ScenarioClient,
|
||||
Ticker,
|
||||
Timeframe,
|
||||
} from '../../../generated/ManagingApi'
|
||||
import {
|
||||
AccountClient,
|
||||
BacktestClient,
|
||||
BotType,
|
||||
DataClient,
|
||||
MoneyManagementClient,
|
||||
ScenarioClient,
|
||||
Timeframe,
|
||||
} from '../../../generated/ManagingApi'
|
||||
import type {
|
||||
BacktestModalProps,
|
||||
IBacktestsFormInput,
|
||||
} from '../../../global/type'
|
||||
import { Loader, Slider } from '../../atoms'
|
||||
import { Modal, Toast } from '../../mollecules'
|
||||
import type {BacktestModalProps, IBacktestsFormInput,} from '../../../global/type'
|
||||
import {Loader, Slider} from '../../atoms'
|
||||
import {Modal, Toast} from '../../mollecules'
|
||||
import FormInput from '../../mollecules/FormInput/FormInput'
|
||||
import CustomMoneyManagement from '../CustomMoneyManagement/CustomMoneyManagement'
|
||||
|
||||
@@ -100,6 +95,8 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
|
||||
// Use the name of the money management strategy if custom is not provided
|
||||
const moneyManagementName = customMoneyManagement ? undefined : selectedMoneyManagement
|
||||
|
||||
console.log(customMoneyManagement)
|
||||
|
||||
backtestClient
|
||||
.backtest_Run(
|
||||
form.accountName,
|
||||
@@ -122,7 +119,6 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
|
||||
if (showLoopSlider && selectedLoopQuantity > loopCount) {
|
||||
const nextCount = loopCount + 1
|
||||
const mm: MoneyManagement = {
|
||||
balanceAtRisk: backtest.optimizedMoneyManagement.balanceAtRisk,
|
||||
leverage: backtest.optimizedMoneyManagement.leverage,
|
||||
name: backtest.optimizedMoneyManagement.name + nextCount,
|
||||
stopLoss: backtest.optimizedMoneyManagement.stopLoss,
|
||||
@@ -148,6 +144,7 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
|
||||
function onMoneyManagementChange(e: any) {
|
||||
if (e.target.value === 'custom') {
|
||||
setShowCustomMoneyManagement(true)
|
||||
setCustomMoneyManagement(e.target.value)
|
||||
} else {
|
||||
setShowCustomMoneyManagement(false)
|
||||
setCustomMoneyManagement(undefined)
|
||||
@@ -280,6 +277,32 @@ const BacktestModal: React.FC<BacktestModalProps> = ({
|
||||
</select>
|
||||
</FormInput>
|
||||
|
||||
{/* Losing streak info */}
|
||||
{(() => {
|
||||
// Find the selected money management object
|
||||
let mm: MoneyManagement | undefined = undefined;
|
||||
if (showCustomMoneyManagement && customMoneyManagement) {
|
||||
mm = { ...customMoneyManagement, stopLoss: customMoneyManagement.stopLoss / 100 };
|
||||
} else if (selectedMoneyManagement) {
|
||||
mm = moneyManagements.find((m) => m.name === selectedMoneyManagement);
|
||||
}
|
||||
// Use actual initial balance and a minimum threshold
|
||||
const initialBalance = balance;
|
||||
const minBalance = 10; // You can make this configurable if needed
|
||||
if (mm && mm.leverage && mm.stopLoss && initialBalance > minBalance) {
|
||||
const perLoss = mm.leverage * mm.stopLoss;
|
||||
if (perLoss > 0 && perLoss < 1) {
|
||||
const streak = Math.floor(Math.log(minBalance / initialBalance) / Math.log(1 - perLoss));
|
||||
return (
|
||||
<div className="text-sm text-info mt-1">
|
||||
Max losing streak before balance drops below {minBalance}: <b>{streak}</b> trades (with leverage x{mm.leverage} and stop loss {Math.round(mm.stopLoss * 10000) / 100}% per trade, starting from {initialBalance})
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})()}
|
||||
|
||||
{showCustomMoneyManagement && (
|
||||
<div className="mt-6">
|
||||
<CustomMoneyManagement
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
import {
|
||||
ChevronDownIcon,
|
||||
ChevronRightIcon,
|
||||
PlayIcon,
|
||||
TrashIcon,
|
||||
EyeIcon
|
||||
} from '@heroicons/react/solid'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import {ChevronDownIcon, ChevronRightIcon, EyeIcon, PlayIcon, TrashIcon} from '@heroicons/react/solid'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {useQuery} from '@tanstack/react-query'
|
||||
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import type {
|
||||
Backtest,
|
||||
MoneyManagement,
|
||||
StartBotRequest,
|
||||
Ticker,
|
||||
} from '../../../generated/ManagingApi'
|
||||
import { BacktestClient, BotClient, MoneyManagementClient } from '../../../generated/ManagingApi'
|
||||
import type { IBacktestCards } from '../../../global/type'
|
||||
import { Toast, SelectColumnFilter, Table, CardText } from '../../mollecules'
|
||||
import type {Backtest, StartBotRequest, Ticker,} from '../../../generated/ManagingApi'
|
||||
import {BacktestClient, BotClient, MoneyManagementClient} from '../../../generated/ManagingApi'
|
||||
import type {IBacktestCards} from '../../../global/type'
|
||||
import {CardText, SelectColumnFilter, Table, Toast} from '../../mollecules'
|
||||
import BotNameModal from '../../mollecules/Modal/BotNameModal'
|
||||
|
||||
import BacktestRowDetails from './backtestRowDetails'
|
||||
@@ -50,7 +39,7 @@ const BacktestTable: React.FC<IBacktestCards> = ({ list, isFetching, setBacktest
|
||||
}
|
||||
}, [moneyManagements])
|
||||
|
||||
async function runBot(botName: string, backtest: Backtest, isForWatchOnly: boolean, moneyManagementName: string) {
|
||||
async function runBot(botName: string, backtest: Backtest, isForWatchOnly: boolean, moneyManagementName: string, initialTradingBalance: number) {
|
||||
const t = new Toast('Bot is starting')
|
||||
const client = new BotClient({}, apiUrl)
|
||||
|
||||
@@ -70,6 +59,7 @@ const BacktestTable: React.FC<IBacktestCards> = ({ list, isFetching, setBacktest
|
||||
scenario: backtest.scenario,
|
||||
ticker: backtest.ticker as Ticker,
|
||||
timeframe: backtest.timeframe,
|
||||
initialTradingBalance: initialTradingBalance,
|
||||
}
|
||||
|
||||
await client
|
||||
@@ -92,8 +82,8 @@ const BacktestTable: React.FC<IBacktestCards> = ({ list, isFetching, setBacktest
|
||||
setShowBotNameModal(false)
|
||||
}
|
||||
|
||||
const handleSubmitBotName = (botName: string, backtest: Backtest, isForWatchOnly: boolean, moneyManagementName: string) => {
|
||||
runBot(botName, backtest, isForWatchOnly, moneyManagementName)
|
||||
const handleSubmitBotName = (botName: string, backtest: Backtest, isForWatchOnly: boolean, moneyManagementName: string, initialTradingBalance: number) => {
|
||||
runBot(botName, backtest, isForWatchOnly, moneyManagementName, initialTradingBalance)
|
||||
setShowBotNameModal(false)
|
||||
}
|
||||
|
||||
@@ -364,8 +354,8 @@ const BacktestTable: React.FC<IBacktestCards> = ({ list, isFetching, setBacktest
|
||||
onClose={handleCloseBotNameModal}
|
||||
backtest={currentBacktest}
|
||||
isForWatchOnly={isForWatchOnly}
|
||||
onSubmitBotName={(botName, backtest, isForWatchOnly, moneyManagementName) =>
|
||||
handleSubmitBotName(botName, backtest, isForWatchOnly, moneyManagementName)
|
||||
onSubmitBotName={(botName, backtest, isForWatchOnly, moneyManagementName, initialTradingBalance) =>
|
||||
handleSubmitBotName(botName, backtest, isForWatchOnly, moneyManagementName, initialTradingBalance)
|
||||
}
|
||||
moneyManagements={moneyManagements}
|
||||
selectedMoneyManagement={selectedMoneyManagement}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
|
||||
import type { MoneyManagement, Timeframe } from '../../../generated/ManagingApi'
|
||||
import { Slider } from '../../atoms'
|
||||
import type {MoneyManagement, Timeframe} from '../../../generated/ManagingApi'
|
||||
import FormInput from '../../mollecules/FormInput/FormInput'
|
||||
import { useCustomMoneyManagement } from '../../../app/store/customMoneyManagement'
|
||||
import {useCustomMoneyManagement} from '../../../app/store/customMoneyManagement'
|
||||
|
||||
type ICustomMoneyManagement = {
|
||||
onCreateMoneyManagement: (moneyManagement: MoneyManagement) => void
|
||||
@@ -18,14 +17,12 @@ const CustomMoneyManagement: React.FC<ICustomMoneyManagement> = ({
|
||||
}) => {
|
||||
const { moneyManagement, setCustomMoneyManagement } = useCustomMoneyManagement()
|
||||
|
||||
const [balanceAtRisk, setBalanceAtRisk] = useState<number>(moneyManagement?.balanceAtRisk || 5)
|
||||
const [leverage, setLeverage] = useState<number>(moneyManagement?.leverage || 1)
|
||||
const [takeProfit, setTakeProfit] = useState<number>(moneyManagement?.takeProfit || 2)
|
||||
const [stopLoss, setStopLoss] = useState<number>(moneyManagement?.stopLoss || 1)
|
||||
|
||||
const handleCreateMoneyManagement = () => {
|
||||
const moneyManagement: MoneyManagement = {
|
||||
balanceAtRisk,
|
||||
leverage,
|
||||
name: 'custom',
|
||||
stopLoss,
|
||||
@@ -38,7 +35,7 @@ const CustomMoneyManagement: React.FC<ICustomMoneyManagement> = ({
|
||||
|
||||
useEffect(() => {
|
||||
handleCreateMoneyManagement()
|
||||
}, [balanceAtRisk, leverage, takeProfit, stopLoss])
|
||||
}, [leverage, takeProfit, stopLoss])
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -49,23 +46,6 @@ const CustomMoneyManagement: React.FC<ICustomMoneyManagement> = ({
|
||||
Custom MoneyManagement
|
||||
</div>
|
||||
<div className="collapse-content">
|
||||
<FormInput
|
||||
label="Balance at risk"
|
||||
htmlFor="balanceAtRisk"
|
||||
inline={false}
|
||||
>
|
||||
<input
|
||||
id="balanceAtRisk"
|
||||
value={balanceAtRisk}
|
||||
onChange={(e) => setBalanceAtRisk(parseInt(e.target.value))}
|
||||
min="1"
|
||||
max="100"
|
||||
step="1"
|
||||
type='number'
|
||||
className='input input-bordered'
|
||||
></input>
|
||||
</FormInput>
|
||||
|
||||
<FormInput label="Leverage" htmlFor="leverage" inline={false}>
|
||||
<input
|
||||
id="leverage"
|
||||
|
||||
@@ -2572,7 +2572,6 @@ export enum TradeDirection {
|
||||
export interface MoneyManagement {
|
||||
name: string;
|
||||
timeframe: Timeframe;
|
||||
balanceAtRisk: number;
|
||||
stopLoss: number;
|
||||
takeProfit: number;
|
||||
leverage: number;
|
||||
@@ -2842,6 +2841,7 @@ export interface StartBotRequest {
|
||||
scenario: string;
|
||||
accountName: string;
|
||||
moneyManagementName: string;
|
||||
initialTradingBalance: number;
|
||||
}
|
||||
|
||||
export interface TradingBot {
|
||||
|
||||
@@ -1,207 +1,183 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { SubmitHandler } from 'react-hook-form'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import {useEffect, useState} from 'react'
|
||||
import type {SubmitHandler} from 'react-hook-form'
|
||||
import {useForm} from 'react-hook-form'
|
||||
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import { Slider } from '../../../components/atoms'
|
||||
import { FormInput, Modal, Toast } from '../../../components/mollecules'
|
||||
import type { MoneyManagement } from '../../../generated/ManagingApi'
|
||||
import {
|
||||
MoneyManagementClient,
|
||||
Timeframe,
|
||||
} from '../../../generated/ManagingApi'
|
||||
import type {
|
||||
IMoneyManagementModalProps,
|
||||
IMoneyManagementFormInput,
|
||||
} from '../../../global/type'
|
||||
import {Slider} from '../../../components/atoms'
|
||||
import {FormInput, Modal, Toast} from '../../../components/mollecules'
|
||||
import type {MoneyManagement} from '../../../generated/ManagingApi'
|
||||
import {MoneyManagementClient, Timeframe,} from '../../../generated/ManagingApi'
|
||||
import type {IMoneyManagementFormInput, IMoneyManagementModalProps,} from '../../../global/type'
|
||||
|
||||
const MoneyManagementModal: React.FC<IMoneyManagementModalProps> = ({
|
||||
showModal,
|
||||
onClose,
|
||||
moneyManagement,
|
||||
disableInputs = false,
|
||||
}) => {
|
||||
const [balanceAtRisk, setBalanceAtRisk] = useState<number>(5)
|
||||
const [takeProfit, setTakeProfit] = useState<number>(20)
|
||||
const [name, setName] = useState<string>('')
|
||||
const [stopLoss, setStopLoss] = useState<number>(10)
|
||||
const [leverage, setLeverage] = useState<number>(1)
|
||||
const [timeframe, setTimeframe] = useState<Timeframe>(
|
||||
Timeframe.FifteenMinutes
|
||||
)
|
||||
const { reset, register, handleSubmit } = useForm<IMoneyManagementFormInput>()
|
||||
const { apiUrl } = useApiUrlStore()
|
||||
showModal,
|
||||
onClose,
|
||||
moneyManagement,
|
||||
disableInputs = false,
|
||||
}) => {
|
||||
const [takeProfit, setTakeProfit] = useState<number>(20)
|
||||
const [name, setName] = useState<string>('')
|
||||
const [stopLoss, setStopLoss] = useState<number>(10)
|
||||
const [leverage, setLeverage] = useState<number>(1)
|
||||
const [timeframe, setTimeframe] = useState<Timeframe>(
|
||||
Timeframe.FifteenMinutes
|
||||
)
|
||||
const {reset, register, handleSubmit} = useForm<IMoneyManagementFormInput>()
|
||||
const {apiUrl} = useApiUrlStore()
|
||||
|
||||
async function createMoneyManagement(form: IMoneyManagementFormInput) {
|
||||
const t = new Toast('Creating settings')
|
||||
const client = new MoneyManagementClient({}, apiUrl)
|
||||
const mm: MoneyManagement = {
|
||||
balanceAtRisk: balanceAtRisk / 100,
|
||||
leverage: leverage,
|
||||
name: name,
|
||||
stopLoss: stopLoss / 100,
|
||||
takeProfit: takeProfit / 100,
|
||||
timeframe: form.timeframe,
|
||||
async function createMoneyManagement(form: IMoneyManagementFormInput) {
|
||||
const t = new Toast('Creating settings')
|
||||
const client = new MoneyManagementClient({}, apiUrl)
|
||||
const mm: MoneyManagement = {
|
||||
leverage: leverage,
|
||||
name: name,
|
||||
stopLoss: stopLoss / 100,
|
||||
takeProfit: takeProfit / 100,
|
||||
timeframe: form.timeframe,
|
||||
}
|
||||
|
||||
await client
|
||||
.moneyManagement_PostMoneyManagement(mm)
|
||||
.then(() => {
|
||||
t.update('success', 'Settings created')
|
||||
})
|
||||
.catch((err) => {
|
||||
t.update('error', 'Error :' + err)
|
||||
})
|
||||
}
|
||||
|
||||
await client
|
||||
.moneyManagement_PostMoneyManagement(mm)
|
||||
.then(() => {
|
||||
t.update('success', 'Settings created')
|
||||
})
|
||||
.catch((err) => {
|
||||
t.update('error', 'Error :' + err)
|
||||
})
|
||||
}
|
||||
const onSubmit: SubmitHandler<IMoneyManagementFormInput> = async (form) => {
|
||||
// @ts-ignore
|
||||
await createMoneyManagement(form)
|
||||
onClose()
|
||||
}
|
||||
|
||||
function onChangeName(e: any) {
|
||||
setName(e.target.value)
|
||||
}
|
||||
|
||||
function onTakeProfitChange(e: any) {
|
||||
setTakeProfit(e.target.value)
|
||||
}
|
||||
|
||||
function onStopLossChange(e: any) {
|
||||
setStopLoss(e.target.value)
|
||||
}
|
||||
|
||||
function onLeverageChange(e: any) {
|
||||
setLeverage(e.target.value)
|
||||
}
|
||||
|
||||
function onBalanceAtRiskChange(e: any) {
|
||||
setBalanceAtRisk(e.target.value)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (moneyManagement) {
|
||||
console.log(moneyManagement)
|
||||
setBalanceAtRisk(moneyManagement.balanceAtRisk * 100)
|
||||
setTakeProfit(moneyManagement.takeProfit * 100)
|
||||
setStopLoss(moneyManagement.stopLoss * 100)
|
||||
setLeverage(moneyManagement.leverage)
|
||||
setTimeframe(moneyManagement.timeframe)
|
||||
setName(moneyManagement.name)
|
||||
|
||||
const defaultValues: MoneyManagement = {
|
||||
balanceAtRisk: moneyManagement.balanceAtRisk,
|
||||
leverage: moneyManagement.leverage,
|
||||
name: moneyManagement.name || '',
|
||||
stopLoss: moneyManagement.stopLoss,
|
||||
takeProfit: moneyManagement.takeProfit,
|
||||
timeframe: moneyManagement.timeframe,
|
||||
}
|
||||
reset({ ...defaultValues })
|
||||
const onSubmit: SubmitHandler<IMoneyManagementFormInput> = async (form) => {
|
||||
// @ts-ignore
|
||||
await createMoneyManagement(form)
|
||||
onClose()
|
||||
}
|
||||
}, [showModal, moneyManagement])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
titleHeader="Money Management"
|
||||
showModal={showModal}
|
||||
onClose={onClose}
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<FormInput label="Name" htmlFor="name">
|
||||
<input
|
||||
value={name}
|
||||
type="text"
|
||||
placeholder="Ex: HighRiskMoneyManagement"
|
||||
className="input input-bordered w-full max-w-xs"
|
||||
{...register('name')}
|
||||
onChange={onChangeName}
|
||||
disabled={disableInputs}
|
||||
/>
|
||||
</FormInput>
|
||||
function onChangeName(e: any) {
|
||||
setName(e.target.value)
|
||||
}
|
||||
|
||||
<FormInput label="Timeframe" htmlFor="timeframe">
|
||||
<select
|
||||
className="select w-full max-w-xs"
|
||||
{...register('timeframe', {
|
||||
disabled: disableInputs,
|
||||
value: timeframe,
|
||||
})}
|
||||
function onTakeProfitChange(e: any) {
|
||||
setTakeProfit(e.target.value)
|
||||
}
|
||||
|
||||
function onStopLossChange(e: any) {
|
||||
setStopLoss(e.target.value)
|
||||
}
|
||||
|
||||
function onLeverageChange(e: any) {
|
||||
setLeverage(e.target.value)
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (moneyManagement) {
|
||||
console.log(moneyManagement)
|
||||
setTakeProfit(moneyManagement.takeProfit * 100)
|
||||
setStopLoss(moneyManagement.stopLoss * 100)
|
||||
setLeverage(moneyManagement.leverage)
|
||||
setTimeframe(moneyManagement.timeframe)
|
||||
setName(moneyManagement.name)
|
||||
|
||||
const defaultValues: MoneyManagement = {
|
||||
leverage: moneyManagement.leverage,
|
||||
name: moneyManagement.name || '',
|
||||
stopLoss: moneyManagement.stopLoss,
|
||||
takeProfit: moneyManagement.takeProfit,
|
||||
timeframe: moneyManagement.timeframe,
|
||||
}
|
||||
reset({...defaultValues})
|
||||
}
|
||||
}, [showModal, moneyManagement])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
titleHeader="Money Management"
|
||||
showModal={showModal}
|
||||
onClose={onClose}
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
{Object.keys(Timeframe).map((item) => (
|
||||
<option key={item} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</FormInput>
|
||||
<FormInput label="Name" htmlFor="name">
|
||||
<input
|
||||
value={name}
|
||||
type="text"
|
||||
placeholder="Ex: HighRiskMoneyManagement"
|
||||
className="input input-bordered w-full max-w-xs"
|
||||
{...register('name')}
|
||||
onChange={onChangeName}
|
||||
disabled={disableInputs}
|
||||
/>
|
||||
</FormInput>
|
||||
|
||||
<FormInput label="Balance at risk" htmlFor="balanceAtRisk">
|
||||
<Slider
|
||||
id="balanceAtRisk"
|
||||
value={balanceAtRisk}
|
||||
onChange={onBalanceAtRiskChange}
|
||||
step="1"
|
||||
max="100"
|
||||
suffixValue="%"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
<FormInput label="Timeframe" htmlFor="timeframe">
|
||||
<select
|
||||
className="select w-full max-w-xs"
|
||||
{...register('timeframe', {
|
||||
disabled: disableInputs,
|
||||
value: timeframe,
|
||||
})}
|
||||
>
|
||||
{Object.keys(Timeframe).map((item) => (
|
||||
<option key={item} value={item}>
|
||||
{item}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</FormInput>
|
||||
|
||||
<FormInput label="TP%" htmlFor="takeProfit">
|
||||
<Slider
|
||||
id="takeProfit"
|
||||
value={takeProfit}
|
||||
onChange={onTakeProfitChange}
|
||||
step="0.01"
|
||||
max="15"
|
||||
suffixValue="%"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
<FormInput label="TP%" htmlFor="takeProfit">
|
||||
<Slider
|
||||
id="takeProfit"
|
||||
value={takeProfit}
|
||||
onChange={onTakeProfitChange}
|
||||
step="0.01"
|
||||
max="15"
|
||||
suffixValue="%"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
|
||||
<FormInput label="SL%" htmlFor="stopLoss">
|
||||
<Slider
|
||||
id="stopLoss"
|
||||
value={stopLoss}
|
||||
onChange={onStopLossChange}
|
||||
step="0.01"
|
||||
max="15"
|
||||
suffixValue="%"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
<FormInput label="SL%" htmlFor="stopLoss">
|
||||
<Slider
|
||||
id="stopLoss"
|
||||
value={stopLoss}
|
||||
onChange={onStopLossChange}
|
||||
step="0.01"
|
||||
max="15"
|
||||
suffixValue="%"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
|
||||
<FormInput label="Leverage" htmlFor="leverage">
|
||||
<Slider
|
||||
id="leverage"
|
||||
value={leverage}
|
||||
onChange={onLeverageChange}
|
||||
step="1"
|
||||
min="1"
|
||||
max="50"
|
||||
prefixValue="x"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
<FormInput label="Leverage" htmlFor="leverage">
|
||||
<Slider
|
||||
id="leverage"
|
||||
value={leverage}
|
||||
onChange={onLeverageChange}
|
||||
step="1"
|
||||
min="1"
|
||||
max="50"
|
||||
prefixValue="x"
|
||||
disabled={disableInputs}
|
||||
></Slider>
|
||||
</FormInput>
|
||||
|
||||
<div className="form-control mb-5">
|
||||
<div className="input-group">
|
||||
<label htmlFor="leverage" className="form-label">
|
||||
Risk reward
|
||||
</label>
|
||||
<div className="ml-4">{(takeProfit / stopLoss).toFixed(2)}</div>
|
||||
</div>
|
||||
</div>
|
||||
{disableInputs ? null : (
|
||||
<div className="modal-action">
|
||||
<button type="submit" className="btn">
|
||||
Build
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
<div className="form-control mb-5">
|
||||
<div className="input-group">
|
||||
<label htmlFor="leverage" className="form-label">
|
||||
Risk reward
|
||||
</label>
|
||||
<div className="ml-4">{(takeProfit / stopLoss).toFixed(2)}</div>
|
||||
</div>
|
||||
</div>
|
||||
{disableInputs ? null : (
|
||||
<div className="modal-action">
|
||||
<button type="submit" className="btn">
|
||||
Build
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default MoneyManagementModal
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { PencilAltIcon, TrashIcon } from '@heroicons/react/solid'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {PencilAltIcon, TrashIcon} from '@heroicons/react/solid'
|
||||
import React, {useEffect, useState} from 'react'
|
||||
|
||||
import useApiUrlStore from '../../../app/store/apiStore'
|
||||
import {
|
||||
Toast,
|
||||
SelectColumnFilter,
|
||||
Table,
|
||||
} from '../../../components/mollecules'
|
||||
import type { MoneyManagement } from '../../../generated/ManagingApi'
|
||||
import { MoneyManagementClient } from '../../../generated/ManagingApi'
|
||||
import type { IMoneyManagementList } from '../../../global/type'
|
||||
import {SelectColumnFilter, Table, Toast,} from '../../../components/mollecules'
|
||||
import type {MoneyManagement} from '../../../generated/ManagingApi'
|
||||
import {MoneyManagementClient} from '../../../generated/ManagingApi'
|
||||
import type {IMoneyManagementList} from '../../../global/type'
|
||||
|
||||
import MoneyManagementModal from './moneyManagementModal'
|
||||
|
||||
@@ -63,13 +59,7 @@ const MoneyManagementTable: React.FC<IMoneyManagementList> = ({ list }) => {
|
||||
disableSortBy: true,
|
||||
},
|
||||
{
|
||||
Cell: ({ cell }: any) => <>{cell.row.values.balanceAtRisk * 100} %</>,
|
||||
Header: 'Balance used',
|
||||
accessor: 'balanceAtRisk',
|
||||
disableFilters: true,
|
||||
},
|
||||
{
|
||||
Cell: ({ cell }) => <>{cell.row.values.stopLoss * 100} %</>,
|
||||
Cell: ({ cell }: any) => <>{cell.row.values.stopLoss * 100} %</>,
|
||||
Header: 'SL',
|
||||
accessor: 'stopLoss',
|
||||
disableFilters: true,
|
||||
|
||||
Reference in New Issue
Block a user