Update genetic front

This commit is contained in:
2025-07-11 14:50:53 +07:00
parent e43a1af5ef
commit f720cb7321
4 changed files with 589 additions and 570 deletions

View File

@@ -674,6 +674,16 @@ public class TradingBotChromosome : ChromosomeBase
scenario.AddIndicator(indicator); scenario.AddIndicator(indicator);
} }
var mm = new MoneyManagement
{
Name = $"Genetic_{request.RequestId}_MM",
Timeframe = request.Timeframe,
StopLoss = Convert.ToDecimal(stopLoss),
TakeProfit = Convert.ToDecimal(takeProfit),
Leverage = 1.0m
};
mm.FormatPercentage();
return new TradingBotConfig return new TradingBotConfig
{ {
Name = $"Genetic_{request.RequestId}", Name = $"Genetic_{request.RequestId}",
@@ -694,14 +704,7 @@ public class TradingBotChromosome : ChromosomeBase
UseForSignalFiltering = false, UseForSignalFiltering = false,
UseForDynamicStopLoss = false, UseForDynamicStopLoss = false,
Scenario = scenario, Scenario = scenario,
MoneyManagement = new MoneyManagement MoneyManagement = mm,
{
Name = $"Genetic_{request.RequestId}_MM",
Timeframe = request.Timeframe,
StopLoss = Convert.ToDecimal(stopLoss),
TakeProfit = Convert.ToDecimal(takeProfit),
Leverage = 1.0m
},
RiskManagement = new RiskManagement RiskManagement = new RiskManagement
{ {
RiskTolerance = RiskToleranceLevel.Moderate RiskTolerance = RiskToleranceLevel.Moderate

View File

@@ -10,14 +10,42 @@ const Modal: React.FC<IModalProps> = ({
onClose, onClose,
titleHeader, titleHeader,
children, children,
size = '4xl',
}) => { }) => {
const getSizeClass = (size: string) => {
switch (size) {
case 'sm':
return '!max-w-sm'
case 'md':
return '!max-w-md'
case 'lg':
return '!max-w-lg'
case 'xl':
return '!max-w-xl'
case '2xl':
return '!max-w-2xl'
case '3xl':
return '!max-w-3xl'
case '4xl':
return '!max-w-4xl'
case '5xl':
return '!max-w-5xl'
case '6xl':
return '!max-w-6xl'
case '7xl':
return '!max-w-7xl'
default:
return '!max-w-4xl'
}
}
if (!showModal) return null
return ( return (
<div className="container mx-auto"> <>
{showModal ? ( {onSubmit ? (
onSubmit ? (
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<div className="modal modal-bottom sm:modal-middle modal-open"> <div className="modal modal-open">
<div className="modal-box !max-w-4xl !w-11/12"> <div className={`modal-box ${getSizeClass(size)} w-11/12`}>
<ModalHeader <ModalHeader
titleHeader={titleHeader} titleHeader={titleHeader}
onClose={onClose} onClose={onClose}
@@ -29,8 +57,8 @@ const Modal: React.FC<IModalProps> = ({
</div> </div>
</form> </form>
) : ( ) : (
<div className="modal modal-bottom sm:modal-middle modal-open"> <div className="modal modal-open">
<div className="modal-box !max-w-4xl !w-11/12"> <div className={`modal-box ${getSizeClass(size)} w-11/12`}>
<ModalHeader <ModalHeader
titleHeader={titleHeader} titleHeader={titleHeader}
onClose={onClose} onClose={onClose}
@@ -40,9 +68,8 @@ const Modal: React.FC<IModalProps> = ({
{children} {children}
</div> </div>
</div> </div>
) )}
) : null} </>
</div>
) )
} }

View File

@@ -147,6 +147,7 @@ export type IModalProps = {
children?: React.ReactNode children?: React.ReactNode
toggleModal?: React.MouseEventHandler<HTMLButtonElement> toggleModal?: React.MouseEventHandler<HTMLButtonElement>
moneyManagement?: MoneyManagement moneyManagement?: MoneyManagement
size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl'
} }
export type IMoneyManagementModalProps = { export type IMoneyManagementModalProps = {

View File

@@ -1,4 +1,4 @@
import React, {useState} from 'react' import React, {useMemo, useState} from 'react'
import {useForm} from 'react-hook-form' import {useForm} from 'react-hook-form'
import {useQuery} from '@tanstack/react-query' import {useQuery} from '@tanstack/react-query'
@@ -13,6 +13,9 @@ import {
Timeframe, Timeframe,
} from '../../generated/ManagingApi' } from '../../generated/ManagingApi'
import {Toast} from '../../components/mollecules' import {Toast} from '../../components/mollecules'
import Table from '../../components/mollecules/Table/Table'
import BacktestTable from '../../components/organism/Backtest/backtestTable'
import Modal from '../../components/mollecules/Modal/Modal'
// Available Indicator Types // Available Indicator Types
const ALL_INDICATORS = [ const ALL_INDICATORS = [
@@ -216,6 +219,77 @@ const BacktestGeneticBundle: React.FC = () => {
setBacktests([]) setBacktests([])
} }
// Table columns for genetic requests
const geneticRequestsColumns = useMemo(() => [
{
Header: 'ID',
accessor: 'requestId',
Cell: ({value}: { value: string }) => (
<span className="font-mono text-xs">{value.slice(0, 8)}...</span>
),
},
{
Header: 'Ticker',
accessor: 'ticker',
},
{
Header: 'Timeframe',
accessor: 'timeframe',
},
{
Header: 'Status',
accessor: 'status',
Cell: ({value}: { value: string }) => (
<span className={`badge ${getStatusBadgeColor(value)}`}>
{value}
</span>
),
},
{
Header: 'Created',
accessor: 'createdAt',
Cell: ({value}: { value: string }) => (
<span>{new Date(value).toLocaleDateString()}</span>
),
},
{
Header: 'Completed',
accessor: 'completedAt',
Cell: ({value}: { value: string | null }) => (
<span>{value ? new Date(value).toLocaleDateString() : '-'}</span>
),
},
{
Header: 'Actions',
accessor: 'actions',
Cell: ({row}: { row: any }) => (
<div className="flex gap-2">
<button
onClick={() => handleViewDetails(row.original)}
className="btn btn-sm btn-outline"
>
View
</button>
<button
onClick={async () => {
try {
await backtestClient.backtest_DeleteGeneticRequest(row.original.requestId)
new Toast('Request deleted successfully', false)
await refetchRequests()
} catch (error) {
new Toast('Failed to delete request', false)
}
}}
className="btn btn-sm btn-error"
>
Delete
</button>
</div>
),
},
], [refetchRequests])
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<div className="card bg-base-100 shadow-xl"> <div className="card bg-base-100 shadow-xl">
@@ -376,7 +450,8 @@ const BacktestGeneticBundle: React.FC = () => {
<label className="label"> <label className="label">
<span className="label-text">Eligible Indicators</span> <span className="label-text">Eligible Indicators</span>
</label> </label>
<div className="grid grid-cols-2 md:grid-cols-3 gap-2 max-h-40 overflow-y-auto border rounded-lg p-4"> <div
className="grid grid-cols-2 md:grid-cols-3 gap-2 max-h-40 overflow-y-auto border rounded-lg p-4">
{ALL_INDICATORS.map(indicator => ( {ALL_INDICATORS.map(indicator => (
<label key={indicator} className="flex items-center gap-2 cursor-pointer"> <label key={indicator} className="flex items-center gap-2 cursor-pointer">
<input <input
@@ -428,78 +503,24 @@ const BacktestGeneticBundle: React.FC = () => {
<div className="card bg-base-100 shadow-xl"> <div className="card bg-base-100 shadow-xl">
<div className="card-body"> <div className="card-body">
<h3 className="card-title">Existing Genetic Requests</h3> <h3 className="card-title">Existing Genetic Requests</h3>
<div className="overflow-x-auto"> <Table
<table className="table table-zebra"> columns={geneticRequestsColumns}
<thead> data={geneticRequests}
<tr> showPagination={true}
<th>ID</th> />
<th>Ticker</th>
<th>Timeframe</th>
<th>Status</th>
<th>Created</th>
<th>Completed</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{geneticRequests.map((request) => (
<tr key={request.requestId}>
<td className="font-mono text-xs">{request.requestId.slice(0, 8)}...</td>
<td>{request.ticker}</td>
<td>{request.timeframe}</td>
<td>
<span className={`badge ${getStatusBadgeColor(request.status)}`}>
{request.status}
</span>
</td>
<td>{new Date(request.createdAt).toLocaleDateString()}</td>
<td>
{request.completedAt
? new Date(request.completedAt).toLocaleDateString()
: '-'
}
</td>
<td>
<div className="flex gap-2">
<button
onClick={() => handleViewDetails(request)}
className="btn btn-sm btn-outline"
>
View
</button>
<button
onClick={async () => {
try {
await backtestClient.backtest_DeleteGeneticRequest(request.requestId)
new Toast('Request deleted successfully', false)
await refetchRequests()
} catch (error) {
new Toast('Failed to delete request', false)
}
}}
className="btn btn-sm btn-error"
>
Delete
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div> </div>
</div> </div>
)} )}
{/* View Details Modal */} {/* View Details Modal */}
{isViewModalOpen && selectedRequest && ( <Modal
<div className="modal modal-open"> showModal={isViewModalOpen}
<div className="modal-box w-11/12 max-w-6xl"> onClose={closeViewModal}
<h3 className="font-bold text-lg mb-4"> titleHeader={`Genetic Request Details - ${selectedRequest?.requestId?.slice(0, 8)}...`}
Genetic Request Details - {selectedRequest.requestId.slice(0, 8)}... size="7xl"
</h3> >
{selectedRequest && (
<>
<div className="grid grid-cols-2 gap-4 mb-6"> <div className="grid grid-cols-2 gap-4 mb-6">
<div> <div>
<strong>Ticker:</strong> {selectedRequest.ticker} <strong>Ticker:</strong> {selectedRequest.ticker}
@@ -530,53 +551,20 @@ const BacktestGeneticBundle: React.FC = () => {
<span className="loading loading-spinner loading-md"></span> <span className="loading loading-spinner loading-md"></span>
</div> </div>
) : backtests.length > 0 ? ( ) : backtests.length > 0 ? (
<div className="overflow-x-auto"> <BacktestTable
<table className="table table-zebra"> list={backtests}
<thead> isFetching={false}
<tr> displaySummary={false}
<th>ID</th> />
<th>Final PnL</th>
<th>Win Rate</th>
<th>Growth %</th>
<th>Score</th>
<th>Positions</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{backtests.map((backtest) => (
<tr key={backtest.id}>
<td className="font-mono text-xs">{backtest.id.slice(0, 8)}...</td>
<td className={backtest.finalPnl >= 0 ? 'text-success' : 'text-error'}>
${backtest.finalPnl.toFixed(2)}
</td>
<td>{backtest.winRate}%</td>
<td className={backtest.growthPercentage >= 0 ? 'text-success' : 'text-error'}>
{backtest.growthPercentage.toFixed(2)}%
</td>
<td>{backtest.score.toFixed(2)}</td>
<td>{backtest.positions?.length || 0}</td>
<td>{new Date(backtest.startDate).toLocaleDateString()}</td>
</tr>
))}
</tbody>
</table>
</div>
) : ( ) : (
<div className="text-center text-gray-500 py-8"> <div className="text-center text-gray-500 py-8">
No backtest results found for this request. No backtest results found for this request.
</div> </div>
)} )}
</div> </div>
</>
<div className="modal-action">
<button onClick={closeViewModal} className="btn">
Close
</button>
</div>
</div>
</div>
)} )}
</Modal>
</div> </div>
) )
} }