'use client'; import React from 'react'; import { Badge, Box, Button, Checkbox, Field, Flex, Grid, Input, Stack, Text, } from '@chakra-ui/react'; import { FiPlay, FiX } from 'react-icons/fi'; import { Segment, Select, SelectWithSearch } from '#ui'; import { useBacktestRunsController } from './useBacktestRunsController'; type BacktestRunsController = ReturnType; const PERIOD_ITEMS = [ { label: 'Days', value: 'days' }, { label: 'Date range', value: 'range' }, ]; const INTERVAL_ITEMS = [ { label: '5m', value: '5' }, { label: '15m', value: '15' }, { label: '30m', value: '30' }, { label: '1h', value: '60' }, { label: '4h', value: '240' }, ]; const CONNECTOR_ITEMS = [ { label: 'Bybit', value: 'bybit' }, { label: 'Binance', value: 'binance' }, { label: 'Coinbase', value: 'coinbase' }, ]; const controlSurface = 'rgba(255, 255, 255, 0.035)'; const controlSurfaceHover = 'rgba(255, 255, 255, 0.05)'; const inputControlProps = { bg: controlSurface, borderColor: 'gray.700', color: 'gray.100', _placeholder: { color: 'gray.500' }, _hover: { bg: controlSurfaceHover, borderColor: 'gray.600', }, _focusVisible: { borderColor: 'gray.500', boxShadow: '0 0 0 1px var(--chakra-colors-gray-500)', }, }; const SelectControl = ({ children }: { children: React.ReactNode }) => ( {children} ); interface FormSectionProps { title: string; columns: string; children: React.ReactNode; } const FormSection = ({ title, columns, children }: FormSectionProps) => ( {title} {children} ); export const BacktestRunForm = ({ controller, }: { controller: BacktestRunsController; }) => { const { state, strategyItems, configItems, selectedConfig, tickerItems, ensureTickersLoaded, updateForm, setSelectedTickers, start, } = controller; const { configs, starting, onboardingMode, form } = state; const { selectedStrategy, selectedConfigId, periodMode, days, startDate, endDate, ai, fast, interval, connector, selectedTickers, tickersLimit, testsLimit, parallel, } = form; const hasConfigs = configs.length > 0; const handleStart = (event: React.FormEvent) => { event.preventDefault(); void start(); }; return (
New run {onboardingMode ? ( First backtest preset ) : null} {selectedConfig ? ( {selectedConfig.combinationCount} combos {selectedConfig.paramCount} params ) : null} Strategy updateForm({ selectedConfigId: value[0] || '' }) } items={configItems} emptyState="No configs for strategy" width="100%" disabled={!selectedStrategy} /> Mode updateForm({ periodMode: value === 'range' ? 'range' : 'days', }) } /> {periodMode === 'days' ? ( Days updateForm({ days: event.target.value }) } /> ) : ( <> Start updateForm({ startDate: event.target.value }) } /> End updateForm({ endDate: event.target.value }) } /> )} updateForm({ ai: details.checked === true }) } > AI updateForm({ fast: details.checked === true }) } > Fast Interval { updateForm({ connector: value[0] || 'binance', selectedTickers: [], }); }} items={CONNECTOR_ITEMS} width="100%" /> Tickers { if (open) { void ensureTickersLoaded().catch(() => undefined); } }} /> {selectedTickers.length ? ( {selectedTickers.map((ticker) => ( {ticker} { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); setSelectedTickers((currentTickers) => currentTickers.filter( (currentTicker) => currentTicker !== ticker, ), ); } }} onClick={() => setSelectedTickers((currentTickers) => currentTickers.filter( (currentTicker) => currentTicker !== ticker, ), ) } > ))} ) : null} Tickers limit updateForm({ tickersLimit: event.target.value }) } /> Tests limit updateForm({ testsLimit: event.target.value }) } /> Parallel updateForm({ parallel: event.target.value }) } />
); };