avatar of 发明者量化-小小梦 发明者量化-小小梦
关注 私信
4
关注
1271
关注者

AlphaArena AI Model Battle: A Hands-On Guide to Replicating DeepSeek's Leading AI Quantitative Trading System

创建于: 2025-10-23 15:11:42, 更新于: 2025-10-23 16:24:48
comments   0
hits   239

AlphaArena AI Model Battle: A Hands-On Guide to Replicating DeepSeek’s Leading AI Quantitative Trading System

1. Introduction: Insights from the AI Trading Arena

Recently, American AI lab nof1ai launched a compelling experiment—giving six top AI models (Claude, DeepSeek, Gemini, GPT-5, Grok, and Tongyi Qianwen) $10,000 each to compete in the real cryptocurrency perpetual futures market. This wasn’t a simulation, but actual trading with real money. The results were surprising: China’s DeepSeek consistently led the pack, while both GPT-5 and Gemini crashed and burned. The greatest value of this competition lies in the team’s decision to open-source all the prompts, data structures, and decision-making processes they used, providing us with an excellent blueprint for studying AI quantitative trading.

AlphaArena AI Model Battle: A Hands-On Guide to Replicating DeepSeek’s Leading AI Quantitative Trading System

This article will provide a detailed breakdown of every node and logic element in an AI quantitative trading workflow based on this publicly available architecture, helping you understand how AI makes trading decisions in real markets.


2. Overall Architecture: A Three-Stage Perception-Decision-Execution System

This AI quantitative trading system employs the classic “Perception-Decision-Execution” three-stage architecture, with the entire workflow composed of multiple core nodes:

AlphaArena AI Model Battle: A Hands-On Guide to Replicating DeepSeek’s Leading AI Quantitative Trading System

Core Node Descriptions:

  • 1. Timer Trigger - System heartbeat, triggered every 3 minutes
  • 2. Parameter Reset - Account status monitoring and performance statistics
  • 3. Market Data Acquisition - Multi-dimensional data retrieval and indicator calculation
  • 4. Position Data Acquisition - Current position status tracking
  • 5. Data Merging - Integration of account and market information
  • 6. AI Agent - Core decision-making engine
  • 7. Trade Execution - Signal parsing and order processing

Let’s dive deep into the design logic of each node one by one.

3. Node 1: Timer Trigger

Functional Positioning

The timer trigger is the initiator of the entire workflow, similar to the human heartbeat, periodically driving the system’s operation.

Design Considerations:

  • 3-minute cycle: Balances data freshness with API call limitations
  • Fixed intervals: Ensures stability and predictability of strategy execution

4. Node 2: Parameter Reset (Account Status Management)

Functional Positioning

This is a critical state management node responsible for initializing, tracking, and calculating various core account metrics.

Core Code Analysis

// Set Binance testnet API base URL
api_base = "https://testnet.binancefuture.com"
exchange.SetBase(api_base)

// Initialization check - set baseline values on first run
if (_G('invoketime') === null) {
  _G('invoketime', 0);
  _G('STARTTIME', Date.now());
  const initAccount = exchange.GetAccount();
  _G('initmoney', initAccount.Equity);
}

// Accumulate invocation count
const invoketime = _G('invoketime') + 1;
_G('invoketime', invoketime);

// Calculate runtime duration (minutes)
const duringtime = Math.floor((Date.now() - _G('STARTTIME')) / 60000);

// Get current account information
const currentAccount = exchange.GetAccount();
const currentAccountValue = currentAccount.Equity;

// Calculate total return percentage
const initMoney = _G('initmoney');
const totalReturnPercent = ((currentAccountValue - initMoney) / initMoney * 100).toFixed(2);

// Log profit to system
LogProfit(currentAccountValue - initMoney, "&")

// Return 5 core metrics
return [{
  json: {
    invoketime: invoketime,
    duringtime: duringtime,
    totalReturnPercent: totalReturnPercent + '%',
    availableCash: currentAccount.Balance.toFixed(2),
    currentAccountValue: currentAccountValue.toFixed(2)
  }
}];

Output Data Structure

{
  "invoketime": 42,                 // System invocation count
  "duringtime": 126,                // Runtime duration (minutes)
  "totalReturnPercent": "3.45%",    // Total return percentage
  "availableCash": "10345.67",      // Available cash
  "currentAccountValue": "10345.00" // Total account value
}

Design Highlights

  • 1. Persistent State Management: Uses the _G() function to achieve cross-cycle data persistence
  • 2. Baseline Anchoring: Records initial capital initmoney as the benchmark for profit calculation
  • 3. Performance Visualization: Provides real-time profit feedback to system charts through the LogProfit() function
  • 4. Defensive Programming: Automatically initializes on first run to avoid null value errors

5. Node 3: Market Data Acquisition

Functional Positioning

This is the “eyes” of the entire system, responsible for collecting, processing, and calculating various market data and technical indicators.

Core Logic Architecture

The market data acquisition node’s functionality can be divided into three levels:

Level 1: Coin List Parsing and Loop Collection

// Parse coin list
const coins = $vars.coinList ? 
  ($vars.coinList.includes(',') ? $vars.coinList.split(',') : [$vars.coinList]) : [];
if (coins.length === 0) {
  return {};
}

// Fetch market data for each coin
const allCoinsData = {};
for (let i = 0; i < coins.length; i++) {
  const coin = coins[i].trim();
  try {
    allCoinsData[coin] = getMarketDataForCoin(coin);
  } catch (e) {
    allCoinsData[coin] = { error: e.toString() };
  }
}
return { data: allCoinsData };

Level 2: Multi-Timeframe Candlestick Data Acquisition and Indicator Calculation

function getMarketDataForCoin(symbol) {
  // Switch to the corresponding coin's perpetual contract
  exchange.SetCurrency(symbol + "_USDT");
  exchange.SetContractType("swap");
  
  // Fetch 3-minute and 4-hour candlestick data
  const kline3m = exchange.GetRecords(60 * 3);      // 3-minute timeframe
  const kline4h = exchange.GetRecords(60 * 60 * 4); // 4-hour timeframe
  
  // Data validity check
  if (!kline3m || kline3m.length < 50 || !kline4h || kline4h.length < 50) {
    return { error: "Insufficient candlestick data" };
  }
  
  // Calculate 3-minute timeframe technical indicators
  const ema20_3m = TA.EMA(kline3m, 20);      // 20-period Exponential Moving Average
  const macd_3m = TA.MACD(kline3m, 12, 26, 9); // MACD indicator
  const rsi7_3m = TA.RSI(kline3m, 7);        // 7-period RSI
  const rsi14_3m = TA.RSI(kline3m, 14);      // 14-period RSI
  
  // Calculate 4-hour timeframe technical indicators
  const ema20_4h = TA.EMA(kline4h, 20);      // 20-period EMA
  const ema50_4h = TA.EMA(kline4h, 50);      // 50-period EMA
  const macd_4h = TA.MACD(kline4h, 12, 26, 9); // MACD indicator
  const rsi14_4h = TA.RSI(kline4h, 14);      // 14-period RSI
  const atr3_4h = TA.ATR(kline4h, 3);        // 3-period ATR (volatility)
  const atr14_4h = TA.ATR(kline4h, 14);      // 14-period ATR
  
  // Get latest candlestick and recent 10 candlesticks
  const latest3m = kline3m[kline3m.length - 1];
  const latest4h = kline4h[kline4h.length - 1];
  const recent10_3m = kline3m.slice(-10);
  const recent10_4h = kline4h.slice(-10);
  
  // Calculate average volume
  const volumes4h = recent10_4h.map(k => k.Volume);
  const avgVolume4h = volumes4h.reduce((a, b) => a + b, 0) / volumes4h.length;
  
  // Return structured data...
}

Dual Timeframe Strategy:

  • 3-minute short timeframe: Captures short-term fluctuations for precise entry and exit timing
  • 4-hour long timeframe: Determines major trend direction to avoid counter-trend trading

This multi-timeframe analysis is a standard configuration in professional quantitative trading, essentially providing the AI with both a “microscope” and a “telescope” perspective simultaneously.

Level 3: Structured Data Output

return {
  symbol: symbol,
  current_price: latest3m.Close,
  current_ema20: ema20_3m[ema20_3m.length - 1],
  current_macd: macd_3m[2][macd_3m[2].length - 1],
  current_rsi_7: rsi7_3m[rsi7_3m.length - 1],
  funding_rate: fundingRate,
  intraday_3min: {
    mid_prices: recent10_3m.map(k => k.Close),
    ema_20_series: recent10_3m.map((k, i) => ema20_3m[ema20_3m.length - 10 + i]),
    macd_series: recent10_3m.map((k, i) => macd_3m[2][macd_3m[2].length - 10 + i]),
    rsi_7_series: recent10_3m.map((k, i) => rsi7_3m[rsi7_3m.length - 10 + i]),
    rsi_14_series: recent10_3m.map((k, i) => rsi14_3m[rsi14_3m.length - 10 + i])
  },
  longer_term_4hour: {
    ema_20: ema20_4h[ema20_4h.length - 1],
    ema_50: ema50_4h[ema50_4h.length - 1],
    atr_3: atr3_4h[atr3_4h.length - 1],
    atr_14: atr14_4h[atr14_4h.length - 1],
    current_volume: latest4h.Volume,
    average_volume: avgVolume4h,
    macd_series: recent10_4h.map((k, i) => macd_4h[2][macd_4h[2].length - 10 + i]),
    rsi_14_series: recent10_4h.map((k, i) => rsi14_4h[rsi14_4h.length - 10 + i])
  }
};

Technical Indicator Explanations

  1. EMA (Exponential Moving Average)
  • Purpose: Determine trend direction and support/resistance levels
  • Price above EMA20 → Short-term bullish
  • EMA20 crosses above EMA50 → Golden cross, buy signal
  1. MACD (Moving Average Convergence Divergence)
  • Purpose: Determine momentum and trend reversals
  • MACD histogram turns from negative to positive → Momentum strengthening
  • DIF line crosses above DEA line → Golden cross signal
  1. RSI (Relative Strength Index)
  • Purpose: Identify overbought/oversold conditions
  • RSI > 70 → Overbought, possible pullback
  • RSI < 30 → Oversold, possible rebound
  1. ATR (Average True Range)
  • Purpose: Measure market volatility, used to adjust stop-loss distance

6. Node 4: Position Data Acquisition

Functional Positioning

The position data acquisition node is responsible for tracking the current position status of each coin, providing the AI with complete position information.

Core Code (Key Sections)

function getAllPositions() {
  // Get current account equity
  const curequity = exchange.GetAccount().Equity;
  
  // Get coin list
  const coins = $vars.coinList ? 
    ($vars.coinList.includes(',') ? $vars.coinList.split(',') : [$vars.coinList]) : [];
  
  // Calculate risk amount per coin = account equity / number of coins
  const risk_usd = coins.length > 0 ? curequity / coins.length : 0;
  
  // Get all actual positions
  const rawPositions = exchange.GetPositions();
  
  // Create position mapping table (coin symbol -> position object)
  const positionMap = {};
  
  if (rawPositions && rawPositions.length > 0) {
    for (let pos of rawPositions) {
      if (pos.Amount && Math.abs(pos.Amount) > 0) {
        // Extract coin symbol (e.g., BTC_USDT.swap -> BTC)
        const coinSymbol = pos.Symbol.replace('_USDT.swap', '')
                                     .replace('.swap', '')
                                     .replace('_USDT', '');
        positionMap[coinSymbol] = pos;
      }
    }
  }
  
  // Create position information for each coin
  const allPositions = [];
  
  for (let i = 0; i < coins.length; i++) {
    const coin = coins[i].trim();
    const pos = positionMap[coin];
    
    if (pos) {
      // When position exists - build complete position information
      // Get take-profit and stop-loss order IDs
      const { tpOrderId, slOrderId } = getTPSLOrderIds(pos.Symbol, currentPrice, pos.Type);
      
      // Get exit plan
      const exitPlan = _G(`exit_plan_${pos.Symbol}`) || {
        profit_target: null,
        stop_loss: null,
        invalidation_condition: ""
      };
      
      allPositions.push({
        symbol: coin,
        quantity: Math.abs(pos.Amount),        // Position size
        entry_price: pos.Price,                // Entry price
        current_price: currentPrice,           // Current price
        liquidation_price: /* Liquidation price calculation */,
        unrealized_pnl: _N(pos.Profit, 2),    // Unrealized P&L
        leverage: pos.MarginLevel || 1,        // Leverage multiplier
        exit_plan: exitPlan,                   // Exit plan
        confidence: exitPlan?.confidence || null,
        risk_usd: risk_usd,                    // Risk amount
        sl_oid: slOrderId,                     // Stop-loss order ID
        tp_oid: tpOrderId,                     // Take-profit order ID
        wait_for_fill: false,
        entry_oid: pos.Info?.posId || -1,
        notional_usd: _N(Math.abs(pos.Amount) * currentPrice, 2)
      });
    } else {
      // When no position exists - set all fields to null
      allPositions.push({
        symbol: coin,
        quantity: null,            // Key field: null indicates no position
        entry_price: null,
        current_price: null,
        liquidation_price: null,
        unrealized_pnl: null,
        leverage: null,
        exit_plan: null,
        confidence: null,
        risk_usd: risk_usd,        // Still return risk_usd for opening position calculations
        sl_oid: null,
        tp_oid: null,
        wait_for_fill: false,
        entry_oid: null,
        notional_usd: null
      });
    }
  }
  
  return allPositions;
}
const positions = getAllPositions();
return {positions};

Key Design

Critical role of the quantity field:

  • quantity = null: No position, AI can consider opening a position
  • quantity ≠ null: Position exists, AI can only hold or close, cannot add to position

This design avoids the risk of “pyramid position sizing” and ensures each coin has only one active position.

7. Node 5: Data Merging

Functional Positioning

Merges market data and position data into the complete context required for AI decision-making.

Source Code Implementation

// Get input data
const inputData = $input.all();
// First input is market data, second is position data
const marketData = inputData[0].json.data;
const positions = inputData[1].json;
// Return organized data
return [{
  json: {
    marketData: marketData,
    positions: positions
  }
}];

Simple and efficient data integration, providing a unified data interface for the AI.

8. Node 6: AI Agent (Core Decision Engine)

Functional Positioning

This is the core of the entire system—the AI decision engine. It receives complete market and account information and outputs specific trading instructions.

AlphaArena AI Model Battle: A Hands-On Guide to Replicating DeepSeek’s Leading AI Quantitative Trading System

Prompt Architecture Explanation

The AI agent’s decision-making relies on two types of prompts:

  1. System Prompt (System Message):
  • Source: Not publicly disclosed by NOF1 website, reverse-engineered from results
  • Purpose: Defines the AI’s role, behavioral rules, and decision-making framework, essentially the AI’s “operating manual”
  • Characteristics: Fixed and unchanging, identical for every call
  • Position: Passed in as a system message when calling the AI model
  1. User Prompt (Text Prompt):
  • Source: Publicly available from NOF1 website
  • Purpose: Provides dynamic market data and account status, essentially the AI’s “real-time information input”
  • Characteristics: Different for each call, contains the latest market data and position information
  • Position: Passed in as a user message when calling the AI model

This dual-prompt architecture of “fixed rules + dynamic data” allows the AI to maintain a stable decision-making framework while responding flexibly to real-time market conditions.

System Prompt Detailed Explanation

The system prompt defines the AI’s behavioral rules and decision-making framework, which can be divided into four core parts:

Part 1: Hard Constraint Rules

## HARD CONSTRAINTS

### Position Limits
- Tradable coins: {{$vars.coinList}}
- Maximum {{$vars.coinList.split(',').length}} concurrent positions
- No pyramiding or adding to existing positions
- Must be flat before re-entering a coin

### Risk Management
- Maximum risk per trade: 5% of account value
- Leverage range: 5x to 40x
- Minimum risk-reward ratio: 2:1
- Every position must have:
  - Stop loss (specific price level)
  - Profit target (specific price level)  
  - Invalidation condition (format: "If price closes below/above [PRICE] on a [TIMEFRAME] candle")

Design Philosophy:

  • Position Limit: Each coin holds a unidirectional position, forcing risk diversification
  • No Position Adding: Avoids the trap of “averaging down”
  • Risk Cap: Maximum 5% of account value at risk per trade
  • Risk-Reward Ratio: At least 2:1, meaning profit target must be at least 2x the stop-loss distance

Part 2: Decision Framework

## DECISION FRAMEWORK

### Identifying Position Status
A coin has an **active position** if `quantity` is NOT null.
A coin has **no position** if `quantity` is null.

### For Coins WITH Active Positions
Check each position in this order:
1. Invalidation condition triggered? → Close immediately
2. Stop loss or profit target hit? → Close
3. Technical setup still valid? → Hold
4. If uncertain → Hold (trust your exit plan)

Available signals: "hold" or "close" ONLY

### For Coins WITHOUT Positions
Only consider if:
- Current active positions < 6
- Available cash > $1000  
- You see a high-probability setup

Available signal: "entry" ONLY

Logic Clarity:

  • Strict distinction between “with position” and “no position” states
  • With position: Can only choose “hold” or “close”
  • No position: Can only choose “open” or “skip”
  • This design prevents the AI from generating logically conflicting instructions

Part 3: Output Format Specification

{
  "BTC": {
    "trade_signal_args": {
      "coin": "BTC",
      "signal": "entry|hold|close",
      "profit_target": 115000.0,
      "stop_loss": 112000.0,
      "invalidation_condition": "If price closes below 112500 on a 3-minute candle",
      "leverage": 15,
      "confidence": 0.75,
      "risk_usd": 624.38,
      "justification": "Reason for this decision"
    }
  }
}

Field Descriptions:

  • signal: Trading signal (entry/hold/close)
  • profit_target: Take-profit price
  • stop_loss: Stop-loss price
  • invalidation_condition: Invalidation condition (natural language description)
  • leverage: Leverage multiplier (5-40)
  • confidence: AI’s confidence in this signal (0-1)
  • risk_usd: Risk amount willing to take
  • justification: Decision rationale (for auditing and debugging)

Part 4: Thought Process Guidance

## THINKING PROCESS

Before outputting JSON, think through your decisions step by step:

1. Identify position status for each coin
2. Review coins WITH active positions
3. Review coins WITHOUT positions  
4. Output final decisions in JSON

This “Chain of Thought” prompting makes the AI analyze before outputting, improving decision stability and interpretability.

User Prompt Detailed Explanation (Dynamic Data Input)

Source Explanation: The user prompt uses template syntax to dynamically inject real-time data.

The user prompt is dynamically generated with the latest market conditions and account information on each call:

It has been {{ duringtime }} minutes since you started trading.
The current time is {{ $now.toISO() }} 
You've been invoked {{ invoketime }} times.

ALL OF THE PRICE OR SIGNAL DATA BELOW IS ORDERED: OLDEST - NEWEST

Timeframes note: Unless stated otherwise in a section title, intraday series 
are provided at 3 minute intervals. If a coin uses a different interval, it is 
explicitly stated in that coin's section.

**CURRENT MARKET STATE FOR ALL COINS**
{{ JSON.stringify(marketData) }}

**HERE IS YOUR ACCOUNT INFORMATION & PERFORMANCE**
Current Total Return (percent): {{ totalReturnPercent }}
Available Cash: {{ availableCash }}
Current Account Value: {{ currentAccountValue }}

Current live positions & performance:
{{ JSON.stringify(positions) }}

Prompt Data Flow Detailed Explanation

This design ensures the AI receives complete decision-making context each time:

  1. Time Awareness
  • Runtime duration (duringtime minutes)
  • Current timestamp ($now.toISO())
  • Invocation count (invoketime times)
  1. Market Data (from “Market Data Acquisition” node)
  • 3-minute and 4-hour candlestick data for each coin
  • Technical indicator series for the most recent 10 candlesticks
  • Real-time indicators like current price, EMA, MACD, RSI, etc.
  1. Account Status (from “Parameter Reset” node)
  • Total return percentage (totalReturnPercent)
  • Available cash (availableCash)
  • Total account value (currentAccountValue)
  1. Position Details (from “Position Data Acquisition” node)
  • Position quantity for each coin (quantity field)
  • Entry price, current price, unrealized P&L
  • Take-profit/stop-loss plans, risk amount

Complete Prompt Workflow

┌─────────────────────────────────────────────────────────────┐
│                    AI Model Invocation Moment                │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  System Prompt (Fixed)                                       │
│  ┌────────────────────────────────────────────┐             │
│  │ You are an expert cryptocurrency trader... │             │
│  │ ## HARD CONSTRAINTS                        │             │
│  │ - Maximum 6 positions                      │             │
│  │ - Risk per trade: 5% max                   │             │
│  │ ## DECISION FRAMEWORK                      │             │
│  │ - For coins WITH positions: hold/close     │             │
│  │ - For coins WITHOUT positions: entry       │             │
│  │ ## OUTPUT FORMAT                           │             │
│  │ - JSON with trade_signal_args              │             │
│  └────────────────────────────────────────────┘             │
│                       ↓                                      │
│  User Prompt (Dynamic, different each time)                  │
│  ┌────────────────────────────────────────────┐             │
│  │ Running for 126 minutes, invoked 42 times  │             │
│  │ Current Total Return: 3.45%                │             │
│  │ Available Cash: $10,345.67                 │             │
│  │                                            │             │
│  │ Market Data:                               │             │
│  │ {                                          │             │
│  │   "BTC": {                                 │             │
│  │     "current_price": 67234.5,              │             │
│  │     "current_ema20": 67150.2,              │             │
│  │     "current_macd": -141.87,               │             │
│  │     "current_rsi_7": 52.93,                │             │
│  │     "intraday_3min": {...},                │             │
│  │     "longer_term_4hour": {...}             │             │
│  │   },                                       │             │
│  │   "ETH": {...}, ...                        │             │
│  │ }                                          │             │
│  │                                            │             │
│  │ Positions:                                 │             │
│  │ [                                          │             │
│  │   {                                        │             │
│  │     "symbol": "BTC",                       │             │
│  │     "quantity": 0.5,                       │             │
│  │     "entry_price": 66800.0,                │             │
│  │     "unrealized_pnl": 217.25,              │             │
│  │     "exit_plan": {                         │             │
│  │       "stop_loss": 66000.0,                │             │
│  │       "profit_target": 68500.0             │             │
│  │     }                                      │             │
│  │   },                                       │             │
│  │   {                                        │             │
│  │     "symbol": "ETH",                       │             │
│  │     "quantity": null,  // No position      │             │
│  │     ...                                    │             │
│  │   }                                        │             │
│  │ ]                                          │             │
│  └────────────────────────────────────────────┘             │
│                       ↓                                      │
│              AI Model Processing and Reasoning               │
│                       ↓                                      │
│  AI Output (JSON Format)                                     │
│  ┌────────────────────────────────────────────┐             │
│  │ {                                          │             │
│  │   "BTC": {                                 │             │
│  │     "trade_signal_args": {                 │             │
│  │       "signal": "hold",                    │             │
│  │       "justification": "Position valid..." │             │
│  │     }                                      │             │
│  │   },                                       │             │
│  │   "ETH": {                                 │             │
│  │     "trade_signal_args": {                 │             │
│  │       "signal": "entry",                   │             │
│  │       "profit_target": 2800.0,             │             │
│  │       "stop_loss": 2600.0,                 │             │
│  │       "leverage": 15,                      │             │
│  │       "risk_usd": 833.33,                  │             │
│  │       "justification": "Bullish setup..."  │             │
│  │     }                                      │             │
│  │   }                                        │             │
│  │ }                                          │             │
│  └────────────────────────────────────────────┘             │
│                                                              │
└─────────────────────────────────────────────────────────────┘
                         ↓
              Passed to "Trade Execution" Node

Advantages of This Dual-Prompt Architecture:

  1. Rule Stability: System prompt is fixed, ensuring the AI’s behavioral rules remain consistent
  2. Data Timeliness: User prompt updates dynamically, ensuring the AI makes decisions based on the latest market conditions
  3. Separation of Concerns: Rule definition and data input are separated, facilitating debugging and optimization
  4. Scalability: System prompt can be modified at any time to optimize strategy without affecting data flow
  5. Auditability: Complete input and output of each AI call can be logged and traced back

9. Node 7: Trade Execution

Functional Positioning

This is the “hands” of the workflow, responsible for translating AI decisions into actual exchange orders and continuously monitoring take-profit and stop-loss conditions.

Core Execution Logic

The trade execution node is divided into five functional modules:

Module 1: Signal Parsing and Validation

// ========== Utility Functions ==========
function parseAIOutput(output) {
  try {
    // Clean code block markers from output
    const cleaned = output.replace(/```[a-z]*\n?/gi, '').trim();
    const start = cleaned.indexOf('{');
    const end = cleaned.lastIndexOf('}');
    return JSON.parse(cleaned.substring(start, end + 1));
  } catch (e) {
    return {};
  }
}

// Main logic
const signals = parseAIOutput($input.first().json.output);
Log(signals)
Exception Handling:
  • Catches JSON parsing errors
  • Cleans markdown formatting from AI output
  • Prevents system crashes due to AI output format issues

Module 2: Precision Management and Position Calculation

// Get trading pair precision information
function getPrecision(coin) {
  try {
    const symbol = coin + '_USDT.swap';
    const markets = exchange.GetMarkets();
    
    if (markets && markets[symbol]) {
      return {
        price: markets[symbol].PricePrecision || 0,
        amount: markets[symbol].AmountPrecision || 0,
        minQty: markets[symbol].MinQty || 5
      };
    }
    
    return { price: 0, amount: 0, minQty: 5 };
  } catch (e) {
    Log(`⚠️ Failed to get ${coin} precision, using default values`);
    return { price: 0, amount: 0, minQty: 5 };
  }
}

// Calculate position size
function calculateQuantity(entryPrice, stopLoss, riskUsd, leverage, precision) {
  const riskPerContract = Math.abs(entryPrice - stopLoss);
  if (riskPerContract <= 0) return 0;
  
  // Calculate quantity based on risk amount
  const quantity = riskUsd / riskPerContract;
  
  // Limit maximum position = (account balance × leverage / 6) / entry price
  const maxQuantity = (exchange.GetAccount().Balance * leverage / 6) / entryPrice;
  
  let finalQuantity = Math.min(quantity, maxQuantity);
  
  // Apply precision and minimum quantity limits
  if (precision) {
    finalQuantity = _N(finalQuantity, precision.amount);
    
    if (finalQuantity < precision.minQty) {
      Log(`⚠️ Calculated quantity ${finalQuantity} is less than minimum order quantity ${precision.minQty}`);
      return 0;
    }
  }
  
  return finalQuantity;
}
Position Calculation Formula:
Risk Distance = |Entry Price - Stop Loss Price|
Position Size = Risk Amount ÷ Risk Distance
Maximum Position = (Account Balance × Leverage ÷ 6) ÷ Entry Price
Final Position = min(Position Size, Maximum Position)

This calculation method ensures:

  • Regardless of price level, the risk amount remains constant
  • When stop-loss is triggered, the loss equals exactly the preset risk amount
  • Prevents excessive position size due to high leverage

Module 3: Opening Position Execution

function executeEntry(coin, args) {
  exchange.SetCurrency(coin + '_USDT');
  exchange.SetContractType("swap");
  
  const ticker = exchange.GetTicker();
  if (!ticker) return;
  
  const currentPrice = ticker.Last;
  if (!validateEntry(coin, currentPrice, args.profit_target, args.stop_loss)) return;
  
  const leverage = args.leverage || 10;
  exchange.SetMarginLevel(leverage);
  
  precision = getPrecision(coin);
  quantity = calculateQuantity(currentPrice, args.stop_loss, args.risk_usd, leverage, precision);
  
  if (quantity <= 0) {
    Log(`⚠️ ${coin}: Calculated quantity invalid, skipping entry`);
    return;
  }
  
  const isLong = args.profit_target > args.stop_loss;
  exchange.SetDirection(isLong ? "buy" : "sell");
  
  const orderId = isLong ? exchange.Buy(-1, quantity) : exchange.Sell(-1, quantity);
  
  if (orderId) {
    Sleep(1000);
    Log(`✅ ${coin}: Opened ${isLong ? 'Long' : 'Short'} Quantity=${quantity} Leverage=${leverage}x Precision=${precision.amount}`);
  } else {
    Log(`❌ ${coin}: Failed to open position`, precision.amount);
  }
}

Module 4: Closing Position Execution

function executeClose(coin) {
  exchange.SetCurrency(coin + '_USDT');
  exchange.SetContractType("swap");
  
  // Cancel all pending orders
  const orders = exchange.GetOrders();
  orders?.forEach(o => exchange.CancelOrder(o.Id));
  
  // Get position information
  const pos = exchange.GetPositions().find(p => 
    p.Symbol.includes(coin) && Math.abs(p.Amount) > 0
  );
  if (!pos) return;
  
  const isLong = pos.Type === PD_LONG || pos.Type === 0;
  const precision = getPrecision(coin);
  // Apply precision to closing quantity
  const closeAmount = _N(Math.abs(pos.Amount), precision.amount);
  
  exchange.SetDirection(isLong ? "closebuy" : "closesell");
  
  const orderId = isLong ? 
    exchange.Sell(-1, closeAmount) : 
    exchange.Buy(-1, closeAmount);
  
  if (orderId) {
    Log(`✅ ${coin}: Successfully closed ${isLong ? 'Long' : 'Short'}, Quantity=${closeAmount}`);
    _G(`exit_plan_${coin}_USDT.swap`, null);
  }
}

Module 5: Take-Profit and Stop-Loss Monitoring

function monitorPosition(coin) {
  exchange.SetCurrency(coin + '_USDT');
  exchange.SetContractType("swap");
  
  const pos = exchange.GetPositions().find(p => 
    p.Symbol.includes(coin) && Math.abs(p.Amount) > 0
  );
  if (!pos) return;
  
  const ticker = exchange.GetTicker();
  if (!ticker) return;
  
  const isLong = pos.Type === PD_LONG || pos.Type === 0;
  const currentPrice = ticker.Last;
  
  // Calculate profit/loss percentage
  const pnl = (currentPrice - pos.Price) * (isLong ? 1 : -1) / pos.Price;
  
  // Get exit plan
  const exitPlan = _G(`exit_plan_${coin}_USDT.swap`);
  if (!exitPlan?.profit_target || !exitPlan?.stop_loss) {
    // If no exit plan is set, use default values
    if (pnl >= 0.03) return closePosition(coin, pos, isLong, "Take Profit", pnl);
    if (pnl <= -0.01) return closePosition(coin, pos, isLong, "Stop Loss", pnl);
    return;
  }
  
  // Check take-profit condition
  const shouldTP = isLong ? 
    currentPrice >= exitPlan.profit_target : 
    currentPrice <= exitPlan.profit_target;
    
  // Check stop-loss condition
  const shouldSL = isLong ? 
    currentPrice <= exitPlan.stop_loss : 
    currentPrice >= exitPlan.stop_loss;
  
  if (shouldTP) return closePosition(coin, pos, isLong, "Take Profit", pnl);
  if (shouldSL) return closePosition(coin, pos, isLong, "Stop Loss", pnl);
}

function closePosition(coin, pos, isLong, reason, pnl) {
  const precision = getPrecision(coin);
  const closeAmount = _N(Math.abs(pos.Amount), precision.amount);
  
  exchange.SetDirection(isLong ? "closebuy" : "closesell");
  isLong ? exchange.Sell(-1, closeAmount) : exchange.Buy(-1, closeAmount);
  
  Log(`${reason === 'Take Profit' ? '✅' : '❌'} ${coin} ${reason} ${(pnl*100).toFixed(2)}%`);
  _G(`exit_plan_${coin}_USDT.swap`, null);
}

Module 6: Visualization Design

To facilitate understanding of the AI trading operation logic, the AI trading signal analysis and position status are presented visually.

图片

10. Key Design Highlights

1. The Power of Multi-Timeframe Analysis

The system simultaneously uses 3-minute and 4-hour timeframes, which is not simple data redundancy:

Example Scenario:

  • 4-hour chart shows BTC in an uptrend (price above EMA20)
  • 3-minute chart shows a pullback (short-term price decline)
  • Decision: This is a “pullback within a trend,” representing an opportunity to add positions rather than a risk signal

Dual Timeframe Coordination:

  • 4-hour determines direction (long or short)
  • 3-minute identifies entry points (when to enter)

2. Three Lines of Defense in Risk Management

First Line: Capital Allocation

Maximum risk per trade = Account value ÷ Number of coins
Maximum 6 positions = Theoretical maximum total risk 30%
Actual maximum risk < 30% (not all 6 stop-losses will trigger simultaneously)

Second Line: Stop-Loss Setup

Stop-loss distance = |Entry price - Stop-loss price| / Entry price
Typical setting: 2-5%
Combined with leverage: At 10x leverage, 5% price movement = 50% principal movement

Third Line: Invalidation Conditions

javascriptExample: "If price closes below $66,500 on the 3-minute candlestick"
Purpose: Exit even if stop-loss hasn't triggered when technical pattern breaks

3. Engineering of AI Output Format

Why require JSON format?

  • Structured data is easy to parse
  • Avoids ambiguity of natural language
  • Facilitates automated validation and processing

Why enforce field consistency?

  • Ensures all signals contain the same field structure
  • Simplifies parsing code logic
  • Avoids errors due to missing fields

11. System Limitations and Improvement Directions

Current Limitations

  1. Cannot Handle Sudden Events
  • AI only looks at technical indicators, doesn’t consider news or policy
  • Cannot respond to black swan events (e.g., exchange hacks)
  1. Fixed Cycle Limitations
  • 3-minute trigger may miss rapid fluctuations
  • May also generate excessive trades in calm markets
  1. Leverage Risk
  • 5-40x leverage can lead to rapid liquidation in extreme market conditions
  • Even with stop-loss, slippage may cause losses beyond expectations
  1. AI Model Stability
  • Large language model outputs have randomness
  • Same input may yield different decisions

Possible Improvement Directions

  1. Introduce News Sentiment Analysis
  • Integrate cryptocurrency news sources
  • Use NLP to analyze market sentiment
  1. Dynamically Adjust Trigger Frequency
  • Increase check frequency during high volatility
  • Decrease frequency during low volatility to save resources
  1. Multi-Model Voting Mechanism
  • Run multiple AI models simultaneously
  • Make decisions based on consensus from multiple models
  1. Add Backtesting Validation
  • Validate strategy on historical data
  • Optimize prompts and parameters

12. Conclusion

This AI quantitative trading system demonstrates how to apply large language models to real financial trading scenarios. Its core advantages include:

  • Modular Design: Each node has clear responsibilities, easy to maintain and extend
  • Strict Risk Control: Multi-layer protection mechanisms to avoid single major losses
  • Engineered AI Integration: Structured input/output, reliable signal parsing
  • Complete Closed Loop: Full automation from data collection to order execution

Key Insights:

  • AI is not omnipotent; it requires strict constraints and rules
  • Risk management is more important than prediction accuracy
  • System reliability is more critical than strategy complexity

I hope this detailed technical breakdown helps you understand the operational logic of AI quantitative trading and make wiser decisions in your own practice.

Appendix: Complete Source Code and Resources

Complete Source Code and Live Trading Records:

Risk Warning:

  • This article is for technical learning only and does not constitute investment advice
  • Cryptocurrency trading carries extremely high risks and may result in total loss of principal
  • Always conduct thorough testing before using real funds
相关推荐