Add progression and new method of selection/mutation/crossover
This commit is contained in:
@@ -3771,6 +3771,8 @@ export interface GeneticRequest {
|
||||
generations: number;
|
||||
mutationRate: number;
|
||||
selectionMethod: GeneticSelectionMethod;
|
||||
crossoverMethod: GeneticCrossoverMethod;
|
||||
mutationMethod: GeneticMutationMethod;
|
||||
elitismPercentage: number;
|
||||
maxTakeProfit: number;
|
||||
eligibleIndicators: IndicatorType[];
|
||||
@@ -3793,9 +3795,36 @@ export enum GeneticRequestStatus {
|
||||
}
|
||||
|
||||
export enum GeneticSelectionMethod {
|
||||
Tournament = "Tournament",
|
||||
Elite = "Elite",
|
||||
Roulette = "Roulette",
|
||||
FitnessWeighted = "FitnessWeighted",
|
||||
StochasticUniversalSampling = "StochasticUniversalSampling",
|
||||
Tournament = "Tournament",
|
||||
Truncation = "Truncation",
|
||||
}
|
||||
|
||||
export enum GeneticCrossoverMethod {
|
||||
AlternatingPosition = "AlternatingPosition",
|
||||
CutAndSplice = "CutAndSplice",
|
||||
Cycle = "Cycle",
|
||||
OnePoint = "OnePoint",
|
||||
OrderBased = "OrderBased",
|
||||
Ordered = "Ordered",
|
||||
PartiallyMapped = "PartiallyMapped",
|
||||
PositionBased = "PositionBased",
|
||||
ThreeParent = "ThreeParent",
|
||||
TwoPoint = "TwoPoint",
|
||||
Uniform = "Uniform",
|
||||
VotingRecombination = "VotingRecombination",
|
||||
}
|
||||
|
||||
export enum GeneticMutationMethod {
|
||||
Displacement = "Displacement",
|
||||
FlipBit = "FlipBit",
|
||||
Insertion = "Insertion",
|
||||
PartialShuffle = "PartialShuffle",
|
||||
ReverseSequence = "ReverseSequence",
|
||||
Twors = "Twors",
|
||||
Uniform = "Uniform",
|
||||
}
|
||||
|
||||
export interface RunGeneticRequest {
|
||||
@@ -3808,6 +3837,8 @@ export interface RunGeneticRequest {
|
||||
generations?: number;
|
||||
mutationRate?: number;
|
||||
selectionMethod?: GeneticSelectionMethod;
|
||||
crossoverMethod?: GeneticCrossoverMethod;
|
||||
mutationMethod?: GeneticMutationMethod;
|
||||
elitismPercentage?: number;
|
||||
maxTakeProfit?: number;
|
||||
eligibleIndicators?: IndicatorType[] | null;
|
||||
|
||||
@@ -674,6 +674,8 @@ export interface GeneticRequest {
|
||||
generations: number;
|
||||
mutationRate: number;
|
||||
selectionMethod: GeneticSelectionMethod;
|
||||
crossoverMethod: GeneticCrossoverMethod;
|
||||
mutationMethod: GeneticMutationMethod;
|
||||
elitismPercentage: number;
|
||||
maxTakeProfit: number;
|
||||
eligibleIndicators: IndicatorType[];
|
||||
@@ -696,9 +698,36 @@ export enum GeneticRequestStatus {
|
||||
}
|
||||
|
||||
export enum GeneticSelectionMethod {
|
||||
Tournament = "Tournament",
|
||||
Elite = "Elite",
|
||||
Roulette = "Roulette",
|
||||
FitnessWeighted = "FitnessWeighted",
|
||||
StochasticUniversalSampling = "StochasticUniversalSampling",
|
||||
Tournament = "Tournament",
|
||||
Truncation = "Truncation",
|
||||
}
|
||||
|
||||
export enum GeneticCrossoverMethod {
|
||||
AlternatingPosition = "AlternatingPosition",
|
||||
CutAndSplice = "CutAndSplice",
|
||||
Cycle = "Cycle",
|
||||
OnePoint = "OnePoint",
|
||||
OrderBased = "OrderBased",
|
||||
Ordered = "Ordered",
|
||||
PartiallyMapped = "PartiallyMapped",
|
||||
PositionBased = "PositionBased",
|
||||
ThreeParent = "ThreeParent",
|
||||
TwoPoint = "TwoPoint",
|
||||
Uniform = "Uniform",
|
||||
VotingRecombination = "VotingRecombination",
|
||||
}
|
||||
|
||||
export enum GeneticMutationMethod {
|
||||
Displacement = "Displacement",
|
||||
FlipBit = "FlipBit",
|
||||
Insertion = "Insertion",
|
||||
PartialShuffle = "PartialShuffle",
|
||||
ReverseSequence = "ReverseSequence",
|
||||
Twors = "Twors",
|
||||
Uniform = "Uniform",
|
||||
}
|
||||
|
||||
export interface RunGeneticRequest {
|
||||
@@ -711,6 +740,8 @@ export interface RunGeneticRequest {
|
||||
generations?: number;
|
||||
mutationRate?: number;
|
||||
selectionMethod?: GeneticSelectionMethod;
|
||||
crossoverMethod?: GeneticCrossoverMethod;
|
||||
mutationMethod?: GeneticMutationMethod;
|
||||
elitismPercentage?: number;
|
||||
maxTakeProfit?: number;
|
||||
eligibleIndicators?: IndicatorType[] | null;
|
||||
|
||||
@@ -6,6 +6,8 @@ import useApiUrlStore from '../../app/store/apiStore'
|
||||
import {
|
||||
type Backtest,
|
||||
BacktestClient,
|
||||
GeneticCrossoverMethod,
|
||||
GeneticMutationMethod,
|
||||
type GeneticRequest,
|
||||
GeneticSelectionMethod,
|
||||
IndicatorType,
|
||||
@@ -52,6 +54,8 @@ interface GeneticBundleFormData {
|
||||
generations: number
|
||||
mutationRate: number
|
||||
selectionMethod: GeneticSelectionMethod
|
||||
crossoverMethod: GeneticCrossoverMethod
|
||||
mutationMethod: GeneticMutationMethod
|
||||
elitismPercentage: number
|
||||
maxTakeProfit: number
|
||||
eligibleIndicators: IndicatorType[]
|
||||
@@ -70,6 +74,7 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
const [isViewModalOpen, setIsViewModalOpen] = useState(false)
|
||||
const [backtests, setBacktests] = useState<Backtest[]>([])
|
||||
const [isLoadingBacktests, setIsLoadingBacktests] = useState(false)
|
||||
const [isFormCollapsed, setIsFormCollapsed] = useState(false)
|
||||
|
||||
// Form setup
|
||||
const {register, handleSubmit, watch, setValue, formState: {errors}} = useForm<GeneticBundleFormData>({
|
||||
@@ -83,6 +88,8 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
generations: 5,
|
||||
mutationRate: 0.3,
|
||||
selectionMethod: GeneticSelectionMethod.Tournament,
|
||||
crossoverMethod: GeneticCrossoverMethod.Uniform,
|
||||
mutationMethod: GeneticMutationMethod.Uniform,
|
||||
elitismPercentage: 10,
|
||||
maxTakeProfit: 2.0,
|
||||
eligibleIndicators: ALL_INDICATORS,
|
||||
@@ -139,6 +146,8 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
generations: data.generations,
|
||||
mutationRate: data.mutationRate,
|
||||
selectionMethod: data.selectionMethod,
|
||||
crossoverMethod: data.crossoverMethod,
|
||||
mutationMethod: data.mutationMethod,
|
||||
elitismPercentage: data.elitismPercentage,
|
||||
maxTakeProfit: data.maxTakeProfit,
|
||||
eligibleIndicators: selectedIndicators,
|
||||
@@ -161,6 +170,8 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
setValue('generations', 5)
|
||||
setValue('mutationRate', 0.3)
|
||||
setValue('selectionMethod', GeneticSelectionMethod.Tournament)
|
||||
setValue('crossoverMethod', GeneticCrossoverMethod.Uniform)
|
||||
setValue('mutationMethod', GeneticMutationMethod.Uniform)
|
||||
setValue('elitismPercentage', 10)
|
||||
setValue('maxTakeProfit', 2.0)
|
||||
setSelectedIndicators(ALL_INDICATORS)
|
||||
@@ -228,13 +239,6 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
|
||||
// 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',
|
||||
@@ -243,6 +247,49 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
Header: 'Timeframe',
|
||||
accessor: 'timeframe',
|
||||
},
|
||||
{
|
||||
Header: 'Progress',
|
||||
accessor: 'currentGeneration',
|
||||
Cell: ({value, row}: { value: number, row: any }) => {
|
||||
const generations = row.original.generations
|
||||
const currentGen = value || 0
|
||||
const percentage = generations > 0 ? Math.round((currentGen / generations) * 100) : 0
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="text-xs">
|
||||
{currentGen} / {generations}
|
||||
</div>
|
||||
<progress
|
||||
className="progress progress-primary w-full h-2"
|
||||
value={percentage}
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
Header: 'Selection',
|
||||
accessor: 'selectionMethod',
|
||||
Cell: ({value}: { value: string }) => (
|
||||
<span className="text-xs">{value}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
Header: 'Crossover',
|
||||
accessor: 'crossoverMethod',
|
||||
Cell: ({value}: { value: string }) => (
|
||||
<span className="text-xs">{value}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
Header: 'Mutation',
|
||||
accessor: 'mutationMethod',
|
||||
Cell: ({value}: { value: string }) => (
|
||||
<span className="text-xs">{value}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
accessor: 'status',
|
||||
@@ -252,20 +299,6 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
</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',
|
||||
@@ -301,14 +334,52 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
<div className="space-y-6">
|
||||
<div className="card bg-base-100 shadow-xl">
|
||||
<div className="card-body">
|
||||
<h2 className="card-title">Genetic Algorithm Bundle</h2>
|
||||
<p className="text-sm text-gray-600 mb-4">
|
||||
Create a genetic algorithm request that will be processed in the background.
|
||||
The algorithm will optimize trading parameters and indicator combinations.
|
||||
</p>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<div>
|
||||
<h2 className="card-title">Genetic Algorithm Bundle</h2>
|
||||
<p className="text-sm text-gray-600">
|
||||
Create a genetic algorithm request that will be processed in the background.
|
||||
The algorithm will optimize trading parameters and indicator combinations.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setIsFormCollapsed(!isFormCollapsed)}
|
||||
className="btn btn-sm btn-outline"
|
||||
>
|
||||
{isFormCollapsed ? 'Show Form' : 'Hide Form'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className={`space-y-4 ${isFormCollapsed ? 'hidden' : ''}`}>
|
||||
{isFormCollapsed && (
|
||||
<div className="space-y-4">
|
||||
<div className="bg-base-200 p-4 rounded-lg">
|
||||
<h4 className="font-semibold mb-2">Current Settings</h4>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 text-sm">
|
||||
<div><strong>Ticker:</strong> {formValues.ticker}</div>
|
||||
<div><strong>Timeframe:</strong> {formValues.timeframe}</div>
|
||||
<div><strong>Population:</strong> {formValues.populationSize}</div>
|
||||
<div><strong>Generations:</strong> {formValues.generations}</div>
|
||||
<div><strong>Selection:</strong> {formValues.selectionMethod}</div>
|
||||
<div><strong>Crossover:</strong> {formValues.crossoverMethod}</div>
|
||||
<div><strong>Mutation:</strong> {formValues.mutationMethod}</div>
|
||||
<div><strong>Indicators:</strong> {selectedIndicators.length}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSubmit(onSubmit)}
|
||||
disabled={isSubmitting}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
{isSubmitting ? 'Creating...' : 'Create Request with Current Settings'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="form-control">
|
||||
<label className="label">
|
||||
<span className="label-text">Ticker</span>
|
||||
@@ -414,14 +485,57 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
<label className="label">
|
||||
<span className="label-text">Selection Method</span>
|
||||
</label>
|
||||
<select
|
||||
className="select select-bordered w-full"
|
||||
{...register('selectionMethod')}
|
||||
>
|
||||
<option value={GeneticSelectionMethod.Tournament}>Tournament Selection</option>
|
||||
<option value={GeneticSelectionMethod.Roulette}>Roulette Wheel</option>
|
||||
<option value={GeneticSelectionMethod.FitnessWeighted}>Fitness Weighted</option>
|
||||
</select>
|
||||
<select
|
||||
className="select select-bordered w-full"
|
||||
{...register('selectionMethod')}
|
||||
>
|
||||
<option value={GeneticSelectionMethod.Elite}>Elite Selection</option>
|
||||
<option value={GeneticSelectionMethod.Roulette}>Roulette Wheel</option>
|
||||
<option value={GeneticSelectionMethod.StochasticUniversalSampling}>Stochastic Universal Sampling</option>
|
||||
<option value={GeneticSelectionMethod.Tournament}>Tournament Selection</option>
|
||||
<option value={GeneticSelectionMethod.Truncation}>Truncation Selection</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-control">
|
||||
<label className="label">
|
||||
<span className="label-text">Crossover Method</span>
|
||||
</label>
|
||||
<select
|
||||
className="select select-bordered w-full"
|
||||
{...register('crossoverMethod')}
|
||||
>
|
||||
<option value={GeneticCrossoverMethod.AlternatingPosition}>Alternating Position (AP)</option>
|
||||
<option value={GeneticCrossoverMethod.CutAndSplice}>Cut and Splice</option>
|
||||
<option value={GeneticCrossoverMethod.Cycle}>Cycle (CX)</option>
|
||||
<option value={GeneticCrossoverMethod.OnePoint}>One-Point (C1)</option>
|
||||
<option value={GeneticCrossoverMethod.OrderBased}>Order-based (OX2)</option>
|
||||
<option value={GeneticCrossoverMethod.Ordered}>Ordered (OX1)</option>
|
||||
<option value={GeneticCrossoverMethod.PartiallyMapped}>Partially Mapped (PMX)</option>
|
||||
<option value={GeneticCrossoverMethod.PositionBased}>Position-based (POS)</option>
|
||||
<option value={GeneticCrossoverMethod.ThreeParent}>Three Parent</option>
|
||||
<option value={GeneticCrossoverMethod.TwoPoint}>Two-Point (C2)</option>
|
||||
<option value={GeneticCrossoverMethod.Uniform}>Uniform</option>
|
||||
<option value={GeneticCrossoverMethod.VotingRecombination}>Voting Recombination (VR)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-control">
|
||||
<label className="label">
|
||||
<span className="label-text">Mutation Method</span>
|
||||
</label>
|
||||
<select
|
||||
className="select select-bordered w-full"
|
||||
{...register('mutationMethod')}
|
||||
>
|
||||
<option value={GeneticMutationMethod.Displacement}>Displacement</option>
|
||||
<option value={GeneticMutationMethod.FlipBit}>Flip Bit</option>
|
||||
<option value={GeneticMutationMethod.Insertion}>Insertion</option>
|
||||
<option value={GeneticMutationMethod.PartialShuffle}>Partial Shuffle (PSM)</option>
|
||||
<option value={GeneticMutationMethod.ReverseSequence}>Reverse Sequence (RSM)</option>
|
||||
<option value={GeneticMutationMethod.Twors}>Twors</option>
|
||||
<option value={GeneticMutationMethod.Uniform}>Uniform</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="form-control">
|
||||
@@ -535,6 +649,15 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
<div>
|
||||
<strong>Timeframe:</strong> {selectedRequest.timeframe}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Selection Method:</strong> {selectedRequest.selectionMethod}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Crossover Method:</strong> {selectedRequest.crossoverMethod}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Mutation Method:</strong> {selectedRequest.mutationMethod}
|
||||
</div>
|
||||
<div>
|
||||
<strong>Status:</strong>
|
||||
<span className={`badge ${getStatusBadgeColor(selectedRequest.status)} ml-2`}>
|
||||
@@ -549,6 +672,23 @@ const BacktestGeneticBundle: React.FC = () => {
|
||||
<strong>Completed:</strong> {new Date(selectedRequest.completedAt).toLocaleString()}
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<strong>Progress:</strong> {selectedRequest.currentGeneration || 0} / {selectedRequest.generations}
|
||||
{selectedRequest.currentGeneration && selectedRequest.generations > 0 && (
|
||||
<div className="mt-1">
|
||||
<progress
|
||||
className="progress progress-primary w-full h-2"
|
||||
value={Math.round(((selectedRequest.currentGeneration || 0) / selectedRequest.generations) * 100)}
|
||||
max="100"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{selectedRequest.bestFitnessSoFar && (
|
||||
<div>
|
||||
<strong>Best Fitness:</strong> {selectedRequest.bestFitnessSoFar.toFixed(4)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
|
||||
Reference in New Issue
Block a user