mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-01 10:01:21 +08:00
Remove the entire AI Debate Arena module (~5,300 lines) to simplify the codebase. This removes the multi-AI debate trading decision system including backend engine, API handlers, database store, frontend page, navigation, translations, and documentation references.
718 lines
18 KiB
TypeScript
718 lines
18 KiB
TypeScript
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
|
||
}
|
||
|
||
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
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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
|
||
}
|
||
|
||
// 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;
|
||
}
|
||
|
||
// 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)
|
||
}
|
||
|
||
// 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
|
||
}
|