refactor: split large files and clean up project structure

- Rename experience/ to telemetry/ for clarity
- Split 15+ large Go files (800-2200 lines) into focused modules:
  kernel/engine.go, backtest/runner.go, market/data.go, store/position.go,
  api/handler_trader.go, trader/auto_trader_grid.go, and 9 exchange traders
- Split frontend monoliths: types.ts, api.ts, AITradersPage.tsx, BacktestPage.tsx
  into domain-specific modules with barrel re-exports
- Remove stale files: screenshots, .yml.old, pyproject.toml
- Remove unused scripts/ and cmd/ directories
- Remove broken/outdated test files (network-dependent, stale expectations)
This commit is contained in:
tinkle-community
2026-03-12 12:53:57 +08:00
parent 8e294a5eed
commit cb31782be4
113 changed files with 20423 additions and 25733 deletions

167
web/src/types/backtest.ts Normal file
View File

@@ -0,0 +1,167 @@
// Backtest types
export interface BacktestRunSummary {
symbol_count: number;
decision_tf: string;
processed_bars: number;
progress_pct: number;
equity_last: number;
max_drawdown_pct: number;
liquidated: boolean;
liquidation_note?: string;
}
export interface BacktestRunMetadata {
run_id: string;
label?: string;
user_id?: string;
last_error?: string;
version: number;
state: string;
created_at: string;
updated_at: string;
summary: BacktestRunSummary;
}
export interface BacktestRunsResponse {
total: number;
items: BacktestRunMetadata[];
}
// Position status for real-time display during backtest
export interface BacktestPositionStatus {
symbol: string;
side: string;
quantity: number;
entry_price: number;
mark_price: number;
leverage: number;
unrealized_pnl: number;
unrealized_pnl_pct: number;
margin_used: number;
}
export interface BacktestStatusPayload {
run_id: string;
state: string;
progress_pct: number;
processed_bars: number;
current_time: number;
decision_cycle: number;
equity: number;
unrealized_pnl: number;
realized_pnl: number;
positions?: BacktestPositionStatus[];
note?: string;
last_error?: string;
last_updated_iso: string;
}
export interface BacktestEquityPoint {
ts: number;
equity: number;
available: number;
pnl: number;
pnl_pct: number;
dd_pct: number;
cycle: number;
}
export interface BacktestTradeEvent {
ts: number;
symbol: string;
action: string;
side?: string;
qty: number;
price: number;
fee: number;
slippage: number;
order_value: number;
realized_pnl: number;
leverage?: number;
cycle: number;
position_after: number;
liquidation: boolean;
note?: string;
}
export interface BacktestMetrics {
total_return_pct: number;
max_drawdown_pct: number;
sharpe_ratio: number;
profit_factor: number;
win_rate: number;
trades: number;
avg_win: number;
avg_loss: number;
best_symbol: string;
worst_symbol: string;
liquidated: boolean;
symbol_stats?: Record<
string,
{
total_trades: number;
winning_trades: number;
losing_trades: number;
total_pnl: number;
avg_pnl: number;
win_rate: number;
}
>;
}
export interface BacktestStartConfig {
run_id?: string;
ai_model_id?: string;
strategy_id?: string; // Optional: use saved strategy from Strategy Studio
symbols: string[];
timeframes: string[];
decision_timeframe: string;
decision_cadence_nbars: number;
start_ts: number;
end_ts: number;
initial_balance: number;
fee_bps: number;
slippage_bps: number;
fill_policy: string;
prompt_variant?: string;
prompt_template?: string;
custom_prompt?: string;
override_prompt?: boolean;
cache_ai?: boolean;
replay_only?: boolean;
checkpoint_interval_bars?: number;
checkpoint_interval_seconds?: number;
replay_decision_dir?: string;
shared_ai_cache_path?: string;
ai?: {
provider?: string;
model?: string;
key?: string;
secret_key?: string;
base_url?: string;
};
leverage?: {
btc_eth_leverage?: number;
altcoin_leverage?: number;
};
}
// Kline data for backtest chart
export interface BacktestKline {
time: number;
open: number;
high: number;
low: number;
close: number;
volume: number;
}
export interface BacktestKlinesResponse {
symbol: string;
timeframe: string;
start_ts: number;
end_ts: number;
count: number;
klines: BacktestKline[];
run_id: string;
}

112
web/src/types/config.ts Normal file
View File

@@ -0,0 +1,112 @@
export interface AIModel {
id: string
name: string
provider: string
enabled: boolean
apiKey?: string
customApiUrl?: string
customModelName?: string
}
export interface TelegramConfig {
token_masked: string // Masked token like "123456:ABC***XYZ"
is_bound: boolean // Whether a user has sent /start
bound_chat_id?: number // The bound chat ID (if any)
model_id?: string // AI model selected for Telegram replies
}
export interface Exchange {
id: string // UUID (empty for supported exchange templates)
exchange_type: string // "binance", "bybit", "okx", "hyperliquid", "aster", "lighter"
account_name: string // User-defined account name
name: string // Display name
type: 'cex' | 'dex'
enabled: boolean
apiKey?: string
secretKey?: string
passphrase?: string // OKX specific
testnet?: boolean
// Hyperliquid specific
hyperliquidWalletAddr?: string
// Aster specific
asterUser?: string
asterSigner?: string
asterPrivateKey?: string
// LIGHTER specific
lighterWalletAddr?: string
lighterPrivateKey?: string
lighterApiKeyPrivateKey?: string
lighterApiKeyIndex?: number
}
export interface CreateExchangeRequest {
exchange_type: string // "binance", "bybit", "okx", "hyperliquid", "aster", "lighter"
account_name: string // User-defined account name
enabled: boolean
api_key?: string
secret_key?: string
passphrase?: string
testnet?: boolean
hyperliquid_wallet_addr?: string
aster_user?: string
aster_signer?: string
aster_private_key?: string
lighter_wallet_addr?: string
lighter_private_key?: string
lighter_api_key_private_key?: string
lighter_api_key_index?: number
}
export interface CreateTraderRequest {
name: string
ai_model_id: string
exchange_id: string
strategy_id?: string // 策略ID新版使用保存的策略配置
initial_balance?: number // 可选:创建时由后端自动获取,编辑时可手动更新
scan_interval_minutes?: number
is_cross_margin?: boolean
show_in_competition?: boolean // 是否在竞技场显示
// 以下字段为向后兼容保留,新版使用策略配置
btc_eth_leverage?: number
altcoin_leverage?: number
trading_symbols?: string
custom_prompt?: string
override_base_prompt?: boolean
system_prompt_template?: string
use_ai500?: boolean
use_oi_top?: boolean
}
export interface UpdateModelConfigRequest {
models: {
[key: string]: {
enabled: boolean
api_key: string
custom_api_url?: string
custom_model_name?: string
}
}
}
export interface UpdateExchangeConfigRequest {
exchanges: {
[key: string]: {
enabled: boolean
api_key: string
secret_key: string
passphrase?: string
testnet?: boolean
// Hyperliquid 特定字段
hyperliquid_wallet_addr?: string
// Aster 特定字段
aster_user?: string
aster_signer?: string
aster_private_key?: string
// LIGHTER 特定字段
lighter_wallet_addr?: string
lighter_private_key?: string
lighter_api_key_private_key?: string
lighter_api_key_index?: number
}
}
}

4
web/src/types/index.ts Normal file
View File

@@ -0,0 +1,4 @@
export * from './trading'
export * from './backtest'
export * from './strategy'
export * from './config'

185
web/src/types/strategy.ts Normal file
View File

@@ -0,0 +1,185 @@
// Strategy Studio Types
export interface Strategy {
id: string;
name: string;
description: string;
is_active: boolean;
is_default: boolean;
is_public: boolean; // 是否在策略市场公开
config_visible: boolean; // 配置参数是否公开可见
config: StrategyConfig;
created_at: string;
updated_at: string;
}
// 策略使用统计
export interface StrategyStats {
clone_count: number; // 被克隆次数
active_users: number; // 当前使用人数
top_performers?: StrategyPerformer[]; // 收益排行
}
// 策略使用者收益排行
export interface StrategyPerformer {
user_id: string;
user_name: string; // 脱敏后的用户名
total_pnl_pct: number; // 总收益率
total_pnl: number; // 总收益金额
win_rate: number; // 胜率
trade_count: number; // 交易次数
using_since: string; // 使用开始时间
rank: number; // 排名
}
export interface PromptSectionsConfig {
role_definition?: string;
trading_frequency?: string;
entry_standards?: string;
decision_process?: string;
}
export interface StrategyConfig {
// Strategy type: "ai_trading" (default) or "grid_trading"
strategy_type?: 'ai_trading' | 'grid_trading';
// Language setting: "zh" for Chinese, "en" for English
// Determines the language used for data formatting and prompt generation
language?: 'zh' | 'en';
coin_source: CoinSourceConfig;
indicators: IndicatorConfig;
custom_prompt?: string;
risk_control: RiskControlConfig;
prompt_sections?: PromptSectionsConfig;
// Grid trading configuration (only used when strategy_type is 'grid_trading')
grid_config?: GridStrategyConfig;
}
// Grid trading specific configuration
export interface GridStrategyConfig {
// Trading pair (e.g., "BTCUSDT")
symbol: string;
// Number of grid levels (5-50)
grid_count: number;
// Total investment in USDT
total_investment: number;
// Leverage (1-20)
leverage: number;
// Upper price boundary (0 = auto-calculate from ATR)
upper_price: number;
// Lower price boundary (0 = auto-calculate from ATR)
lower_price: number;
// Use ATR to auto-calculate bounds
use_atr_bounds: boolean;
// ATR multiplier for bound calculation (default 2.0)
atr_multiplier: number;
// Position distribution: "uniform" | "gaussian" | "pyramid"
distribution: 'uniform' | 'gaussian' | 'pyramid';
// Maximum drawdown percentage before emergency exit
max_drawdown_pct: number;
// Stop loss percentage per position
stop_loss_pct: number;
// Daily loss limit percentage
daily_loss_limit_pct: number;
// Use maker-only orders for lower fees
use_maker_only: boolean;
// Enable automatic grid direction adjustment based on box breakouts
enable_direction_adjust?: boolean;
// Direction bias ratio for long_bias/short_bias modes (default 0.7 = 70%/30%)
direction_bias_ratio?: number;
}
export interface CoinSourceConfig {
source_type: 'static' | 'ai500' | 'oi_top' | 'oi_low' | 'mixed';
static_coins?: string[];
excluded_coins?: string[]; // 排除的币种列表
use_ai500: boolean;
ai500_limit?: number;
use_oi_top: boolean;
oi_top_limit?: number;
use_oi_low: boolean;
oi_low_limit?: number;
// Note: API URLs are now built automatically using nofxos_api_key from IndicatorConfig
}
export interface IndicatorConfig {
klines: KlineConfig;
// Raw OHLCV kline data - required for AI analysis
enable_raw_klines: boolean;
// Technical indicators (optional)
enable_ema: boolean;
enable_macd: boolean;
enable_rsi: boolean;
enable_atr: boolean;
enable_boll: boolean;
enable_volume: boolean;
enable_oi: boolean;
enable_funding_rate: boolean;
ema_periods?: number[];
rsi_periods?: number[];
atr_periods?: number[];
boll_periods?: number[];
external_data_sources?: ExternalDataSource[];
// ========== NofxOS 数据源统一配置 ==========
// Unified NofxOS API Key - used for all NofxOS data sources
nofxos_api_key?: string;
// 量化数据源(资金流向、持仓变化、价格变化)
enable_quant_data?: boolean;
enable_quant_oi?: boolean;
enable_quant_netflow?: boolean;
// OI 排行数据(市场持仓量增减排行)
enable_oi_ranking?: boolean;
oi_ranking_duration?: string; // "1h", "4h", "24h"
oi_ranking_limit?: number;
// NetFlow 排行数据(机构/散户资金流向排行)
enable_netflow_ranking?: boolean;
netflow_ranking_duration?: string; // "1h", "4h", "24h"
netflow_ranking_limit?: number;
// Price 排行数据(涨跌幅排行)
enable_price_ranking?: boolean;
price_ranking_duration?: string; // "1h", "4h", "24h" or "1h,4h,24h"
price_ranking_limit?: number;
}
export interface KlineConfig {
primary_timeframe: string;
primary_count: number;
longer_timeframe?: string;
longer_count?: number;
enable_multi_timeframe: boolean;
// 新增:支持选择多个时间周期
selected_timeframes?: string[];
}
export interface ExternalDataSource {
name: string;
type: 'api' | 'webhook';
url: string;
method: string;
headers?: Record<string, string>;
data_path?: string;
refresh_secs?: number;
}
export interface RiskControlConfig {
// Max number of coins held simultaneously (CODE ENFORCED)
max_positions: number;
// Trading Leverage - exchange leverage for opening positions (AI guided)
btc_eth_max_leverage: number; // BTC/ETH max exchange leverage
altcoin_max_leverage: number; // Altcoin max exchange leverage
// Position Value Ratio - single position notional value / account equity (CODE ENFORCED)
// Max position value = equity × this ratio
btc_eth_max_position_value_ratio?: number; // default: 5 (BTC/ETH max position = 5x equity)
altcoin_max_position_value_ratio?: number; // default: 1 (Altcoin max position = 1x equity)
// Risk Parameters
max_margin_usage: number; // Max margin utilization, e.g. 0.9 = 90% (CODE ENFORCED)
min_position_size: number; // Min position size in USDT (CODE ENFORCED)
min_risk_reward_ratio: number; // Min take_profit / stop_loss ratio (AI guided)
min_confidence: number; // Min AI confidence to open position (AI guided)
}

250
web/src/types/trading.ts Normal file
View File

@@ -0,0 +1,250 @@
export interface SystemStatus {
trader_id: string
trader_name: string
ai_model: string
is_running: boolean
start_time: string
runtime_minutes: number
call_count: number
initial_balance: number
scan_interval: string
stop_until: string
last_reset_time: string
ai_provider: string
strategy_type?: 'ai_trading' | 'grid_trading'
grid_symbol?: string
}
export interface AccountInfo {
total_equity: number
wallet_balance: number
unrealized_profit: number // 未实现盈亏交易所API官方值
available_balance: number
total_pnl: number
total_pnl_pct: number
initial_balance: number
daily_pnl: number
position_count: number
margin_used: number
margin_used_pct: number
}
export interface Position {
symbol: string
side: string
entry_price: number
mark_price: number
quantity: number
leverage: number
unrealized_pnl: number
unrealized_pnl_pct: number
liquidation_price: number
margin_used: number
}
export interface DecisionAction {
action: string
symbol: string
quantity: number
leverage: number
price: number
stop_loss?: number // Stop loss price
take_profit?: number // Take profit price
confidence?: number // AI confidence (0-100)
reasoning?: string // Brief reasoning
order_id: number
timestamp: string
success: boolean
error?: string
}
export interface AccountSnapshot {
total_balance: number
available_balance: number
total_unrealized_profit: number
position_count: number
margin_used_pct: number
}
export interface DecisionRecord {
timestamp: string
cycle_number: number
system_prompt: string
input_prompt: string
cot_trace: string
decision_json: string
account_state: AccountSnapshot
positions: any[]
candidate_coins: string[]
decisions: DecisionAction[]
execution_log: string[]
success: boolean
error_message?: string
}
export interface Statistics {
total_cycles: number
successful_cycles: number
failed_cycles: number
total_open_positions: number
total_close_positions: number
}
// AI Trading相关类型
export interface TraderInfo {
trader_id: string
trader_name: string
ai_model: string
exchange_id?: string
is_running?: boolean
show_in_competition?: boolean
strategy_id?: string
strategy_name?: string
custom_prompt?: string
use_ai500?: boolean
use_oi_top?: boolean
system_prompt_template?: string
}
// Competition related types
export interface CompetitionTraderData {
trader_id: string
trader_name: string
ai_model: string
exchange: string
total_equity: number
total_pnl: number
total_pnl_pct: number
position_count: number
margin_used_pct: number
is_running: boolean
}
export interface CompetitionData {
traders: CompetitionTraderData[]
count: number
}
// Trader Configuration Data for View Modal
export interface TraderConfigData {
trader_id?: string
trader_name: string
ai_model: string
exchange_id: string
strategy_id?: string // 策略ID
strategy_name?: string // 策略名称
is_cross_margin: boolean
show_in_competition: boolean // 是否在竞技场显示
scan_interval_minutes: number
initial_balance: number
is_running: boolean
// 以下为旧版字段(向后兼容)
btc_eth_leverage?: number
altcoin_leverage?: number
trading_symbols?: string
custom_prompt?: string
override_base_prompt?: boolean
system_prompt_template?: string
use_ai500?: boolean
use_oi_top?: boolean
}
// Position History Types
export interface HistoricalPosition {
id: number
trader_id: string
exchange_id: string
exchange_type: string
symbol: string
side: string
quantity: number
entry_quantity: number
entry_price: number
entry_order_id: string
entry_time: string
exit_price: number
exit_order_id: string
exit_time: string
realized_pnl: number
fee: number
leverage: number
status: string
close_reason: string
created_at: string
updated_at: string
}
// Matches Go TraderStats struct exactly
export interface TraderStats {
total_trades: number
win_trades: number
loss_trades: number
win_rate: number
profit_factor: number
sharpe_ratio: number
total_pnl: number
total_fee: number
avg_win: number
avg_loss: number
max_drawdown_pct: number
}
// Matches Go SymbolStats struct exactly
export interface SymbolStats {
symbol: string
total_trades: number
win_trades: number
win_rate: number
total_pnl: number
avg_pnl: number
avg_hold_mins: number
}
// Matches Go DirectionStats struct exactly
export interface DirectionStats {
side: string
trade_count: number
win_rate: number
total_pnl: number
avg_pnl: number
}
export interface PositionHistoryResponse {
positions: HistoricalPosition[]
stats: TraderStats | null
symbol_stats: SymbolStats[]
direction_stats: DirectionStats[]
}
// Grid Risk Information for frontend display
export interface GridRiskInfo {
// Leverage info
current_leverage: number
effective_leverage: number
recommended_leverage: number
// Position info
current_position: number
max_position: number
position_percent: number
// Liquidation info
liquidation_price: number
liquidation_distance: number
// Market state
regime_level: string
// Box state
short_box_upper: number
short_box_lower: number
mid_box_upper: number
mid_box_lower: number
long_box_upper: number
long_box_lower: number
current_price: number
// Breakout state
breakout_level: string
breakout_direction: string
}