--- name: pine-script description: Export backtest strategies to indicator/strategy code for major trading platforms — TradingView, 通达信, 同花顺, 东方财富, MT5. category: tool --- ## Overview This skill exports a Vibe-Trading strategy to **all major trading platforms** in one go. Output file: `artifacts/strategy.pine` (inside the run directory). Supported platforms (always generate ALL): | Group | Platforms | Language | |-------|-----------|----------| | International Charts | TradingView | Pine Script v6 | | China Equities | 通达信 / 同花顺 / 东方财富 | TDX Formula | | Forex / CFD | MetaTrader 5 | MQL5 | ## Workflow: Export from Backtest 1. `load_skill("pine-script")` — read this guide 2. `read_file("config.json")` — understand instruments, dates, parameters 3. `read_file("code/signal_engine.py")` — understand the Python strategy logic 4. **Translate** the strategy to ALL platforms using the references below 5. `write_file("artifacts/strategy.pine")` — save the combined output 6. Return the code in a code block with usage instructions per platform ## Workflow: Generate from Description 1. `load_skill("pine-script")` — read this guide 2. Write indicator/strategy code for ALL platforms based on the user's description 3. `write_file("artifacts/strategy.pine")` — save the combined output 4. Return the code with usage instructions ## Output Format The output file uses this structure (all platforms in one file): ``` ================================================================================ TRADINGVIEW — Pine Script v6 Paste into: Pine Editor → New blank indicator → Add to Chart ================================================================================ [Pine Script code here] ================================================================================ 通达信 / 同花顺 / 东方财富 (TDX Formula) Paste into: 功能 → 公式管理器 → 新建指标公式 ================================================================================ [TDX formula code here] ================================================================================ MT5 — MQL5 Save as: .mq5 file → MetaEditor → Compile → Navigator → Attach to Chart ================================================================================ [MQL5 code here] ``` --- # Platform Reference ## 1. TradingView — Pine Script v6 ### Template ```pinescript // This strategy was generated by Vibe-Trading // Paste into TradingView Pine Editor → Add to Chart //@version=6 strategy("Strategy Name", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1, initial_capital=1000000) // ============================================================================ // INPUTS // ============================================================================ // [Group inputs logically with input.int(), input.float(), input.string()] // ============================================================================ // CALCULATIONS // ============================================================================ // [Core indicator calculations] // ============================================================================ // CONDITIONS // ============================================================================ longCondition = false shortCondition = false exitLongCondition = false exitShortCondition = false // ============================================================================ // STRATEGY EXECUTION // ============================================================================ if longCondition strategy.entry("Long", strategy.long) if shortCondition strategy.entry("Short", strategy.short) if exitLongCondition strategy.close("Long") if exitShortCondition strategy.close("Short") // ============================================================================ // PLOTS // ============================================================================ // [Visual overlays: moving averages, bands, signals] // ============================================================================ // ALERTS // ============================================================================ alertcondition(longCondition, title="Long Signal", message="Long entry signal triggered") alertcondition(shortCondition, title="Short Signal", message="Short entry signal triggered") ``` ### Python → Pine Script Mapping | Python (pandas/numpy) | Pine Script v6 | |------------------------|----------------| | `df['close'].rolling(n).mean()` | `ta.sma(close, n)` | | `df['close'].ewm(span=n).mean()` | `ta.ema(close, n)` | | `ta.RSI(df['close'], n)` or manual RSI | `ta.rsi(close, n)` | | `ta.MACD(df['close'])` | `[macdLine, signalLine, hist] = ta.macd(close, 12, 26, 9)` | | `df['close'].rolling(n).std()` | `ta.stdev(close, n)` | | `df['high'].rolling(n).max()` | `ta.highest(high, n)` | | `df['low'].rolling(n).min()` | `ta.lowest(low, n)` | | `df['close'].pct_change()` | `(close - close[1]) / close[1]` | | `df['volume'].rolling(n).mean()` | `ta.sma(volume, n)` | | `df['close'] > df['close'].shift(1)` | `close > close[1]` | | Bollinger Bands | `[mid, upper, lower] = ta.bb(close, length, mult)` | | ATR | `ta.atr(length)` | | ADX | `ta.adx(high, low, close, length)` | | Stochastic | `ta.stoch(close, high, low, length, smoothK, smoothD)` | | CCI | `ta.cci(close, length)` | | Williams %R | `ta.wpr(length)` | | MFI | `ta.mfi(close, length)` | | OBV | `ta.obv` | | VWAP | `ta.vwap` | ### Data References | Python | Pine Script v6 | |--------|----------------| | `df['open']` | `open` | | `df['high']` | `high` | | `df['low']` | `low` | | `df['close']` | `close` | | `df['volume']` | `volume` | | `df.index` (datetime) | `time` | | `df['close'].shift(n)` | `close[n]` | ### Signal Logic | Python Pattern | Pine Script v6 | |---------------|----------------| | `(fast > slow) & (fast.shift(1) <= slow.shift(1))` | `ta.crossover(fast, slow)` | | `(fast < slow) & (fast.shift(1) >= slow.shift(1))` | `ta.crossunder(fast, slow)` | | `signal.where(condition, 0)` | `condition ? value : 0` | | `np.where(cond, val_true, val_false)` | `cond ? val_true : val_false` | | `signal.clip(-1, 1)` | `math.max(-1, math.min(1, signal))` | | `signal.fillna(0)` | `nz(signal, 0)` | | `pd.isna(value)` | `na(value)` | ### Position Sizing | Python Pattern | Pine Script v6 | |---------------|----------------| | Equal weight 1/N | `strategy.percent_of_equity` with `default_qty_value = 100/N` | | Full position on signal=1.0 | `default_qty_type=strategy.percent_of_equity, default_qty_value=100` | | Half position on signal=0.5 | Use `strategy.entry(..., qty=strategy.equity * 0.5 / close)` | | Stop-loss | `strategy.exit("Exit", stop=entryPrice * (1 - stopPct))` | | Take-profit | `strategy.exit("Exit", limit=entryPrice * (1 + tpPct))` | ### Syntax Rules (Critical) 1. **Version declaration must be first line**: `//@version=6` 2. **Ternary operators MUST stay on one line**: `text = condition ? "a" : "b"` 3. **Line continuation**: continuation lines must be indented MORE than the starting line 4. **No plot() in local scope** (if/for/function) — use `plot(condition ? value : na)` 5. **var**: persistent state across bars; regular assignment recalculates each bar 6. **Avoid repainting**: use `barstate.isconfirmed`, `lookahead=barmerge.lookahead_off` 7. **Limits**: max 500 bars lookback, 500 plot calls, 64 entry/exit per bar, 40 request.security() --- ## 2. 通达信 / 同花顺 / 东方财富 — TDX Formula These platforms share 95%+ identical formula syntax. Write ONE version that works on all three. ### Template ``` {Vibe-Trading 策略导出} {策略名称: XXX} {——————— 参数 ———————} N:=14; M:=6; {——————— 指标计算 ———————} RSI_VAL:=RSI(CLOSE,N); MA_FAST:=MA(CLOSE,5); MA_SLOW:=MA(CLOSE,20); {——————— 买卖信号 ———————} BUY:CROSS(MA_FAST,MA_SLOW) AND RSI_VAL<40,COLORRED; SELL:CROSS(MA_SLOW,MA_FAST) AND RSI_VAL>60,COLORGREEN; DRAWTEXT(BUY,LOW,'B'),COLORYELLOW; DRAWTEXT(SELL,HIGH,'S'),COLORWHITE; ``` ### Python → TDX Mapping | Python | TDX Formula | |--------|-------------| | `df['close'].rolling(n).mean()` | `MA(CLOSE,N)` | | `df['close'].ewm(span=n).mean()` | `EMA(CLOSE,N)` | | RSI | `RSI(CLOSE,N)` (returns 0-100) | | MACD | `MACD.DIF`, `MACD.DEA`, `MACD.MACD` or manual: `DIF:=EMA(CLOSE,12)-EMA(CLOSE,26); DEA:=EMA(DIF,9); MACD:=(DIF-DEA)*2;` | | Bollinger Bands | `BOLL(N,M)` → `BOLL.UPPER`, `BOLL.MID`, `BOLL.LOWER` or manual | | ATR | `ATR:=MA(MAX(MAX(HIGH-LOW,ABS(HIGH-REF(CLOSE,1))),ABS(LOW-REF(CLOSE,1))),N);` | | `df['close'].shift(n)` | `REF(CLOSE,N)` | | `df['high'].rolling(n).max()` | `HHV(HIGH,N)` | | `df['low'].rolling(n).min()` | `LLV(LOW,N)` | | crossover(fast, slow) | `CROSS(FAST,SLOW)` | | crossunder(fast, slow) | `CROSS(SLOW,FAST)` | | `df['volume']` | `VOL` | | `abs(x)` | `ABS(X)` | | `max(a,b)` | `MAX(A,B)` | | `min(a,b)` | `MIN(A,B)` | | conditional | `IF(COND,A,B)` | | `df['close'].pct_change()` | `(CLOSE-REF(CLOSE,1))/REF(CLOSE,1)` | | count true in N bars | `COUNT(COND,N)` | | sum over N bars | `SUM(X,N)` | | std over N bars | `STD(CLOSE,N)` | | slope / linear regression | `SLOPE(CLOSE,N)` | ### Syntax Rules 1. **Assignment**: `:=` for intermediate variables, `:` for output (plotted) lines 2. **Comments**: `{comment}` — curly braces, NOT `//` 3. **No semicolons optional**: each statement ends with `;` 4. **Colors**: `COLORRED`, `COLORGREEN`, `COLORYELLOW`, `COLORWHITE`, `COLORBLUE`, `COLORCYAN`, `COLORMAGENTA` 5. **Line styles**: `LINETHICK2`, `POINTDOT`, `STICK`, `VOLSTICK` 6. **Draw text**: `DRAWTEXT(COND, PRICE, 'TEXT'), COLOR;` 7. **Draw icon**: `DRAWICON(COND, PRICE, ICON_ID);` 8. **All function/variable names UPPERCASE** 9. **No loops / no arrays** — everything is vectorized bar-by-bar 10. **Max formula length**: ~10,000 characters per formula ### Platform Differences | Feature | 通达信 | 同花顺 | 东方财富 | |---------|--------|--------|----------| | MACD built-in | `MACD(12,26,9)` | `MACD(12,26,9)` | same | | Stochastic | `KDJ(N,M1,M2)` | same | same | | Custom color | `COLOR+RRGGBB` | `COLOR+RRGGBB` | limited | | Strategy backtest | 条件选股 only | 条件选股 only | 条件选股 only | For maximum compatibility, avoid platform-specific extensions. Stick to core functions. --- ## 3. MetaTrader 5 — MQL5 ### Template (Custom Indicator) ```mql5 //+------------------------------------------------------------------+ //| Generated by Vibe-Trading | //+------------------------------------------------------------------+ #property copyright "Vibe-Trading" #property indicator_chart_window // or indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_color1 clrDodgerBlue #property indicator_color2 clrRed input int InpPeriod = 14; // Period double BuyBuffer[]; double SellBuffer[]; int OnInit() { SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA); SetIndexBuffer(1, SellBuffer, INDICATOR_DATA); PlotIndexSetInteger(0, PLOT_ARROW, 233); // up arrow PlotIndexSetInteger(1, PLOT_ARROW, 234); // down arrow PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ARROW); PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_ARROW); return(INIT_SUCCEEDED); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int start = MathMax(prev_calculated - 1, InpPeriod); for(int i = start; i < rates_total; i++) { BuyBuffer[i] = EMPTY_VALUE; SellBuffer[i] = EMPTY_VALUE; // === YOUR LOGIC HERE === // Example: if(buyCondition) BuyBuffer[i] = low[i]; // if(sellCondition) SellBuffer[i] = high[i]; } return(rates_total); } ``` ### Python → MQL5 Mapping | Python | MQL5 | |--------|------| | `df['close'].rolling(n).mean()` | `iMA(_Symbol, PERIOD_CURRENT, n, 0, MODE_SMA, PRICE_CLOSE)` or manual loop | | EMA | `iMA(..., MODE_EMA, ...)` | | RSI | `iRSI(_Symbol, PERIOD_CURRENT, n, PRICE_CLOSE)` | | MACD | `iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE)` | | Bollinger | `iBands(_Symbol, PERIOD_CURRENT, n, 0, mult, PRICE_CLOSE)` | | ATR | `iATR(_Symbol, PERIOD_CURRENT, n)` | | Stochastic | `iStochastic(_Symbol, PERIOD_CURRENT, K, D, slowing, MODE_SMA, STO_LOWHIGH)` | | `df['close'].shift(n)` | `close[i-n]` (in OnCalculate loop) | | crossover | `buf[i] > ref[i] && buf[i-1] <= ref[i-1]` | ### Syntax Rules 1. **Indicator handles**: call `iMA()` etc. in `OnInit()`, use `CopyBuffer()` to get values 2. **Buffer direction**: MQL5 buffers are indexed 0=oldest by default; use `ArraySetAsSeries()` to reverse 3. **EMPTY_VALUE**: use for "no signal" on arrow plots 4. **Indicator vs EA**: generate indicator (`.mq5`), not Expert Advisor, to match "indicator export" purpose 5. **Handle-based API**: MQL5 uses handles — create in `OnInit`, read in `OnCalculate` --- ## Symbol Format Mapping When generating code, map Vibe-Trading instrument codes appropriately: | Vibe-Trading | TradingView | 通达信/同花顺 | MT5 | |-------------|-------------|---------------|-----| | `000001.SZ` | `SZSE:000001` | `000001` | N/A | | `600519.SH` | `SSE:600519` | `600519` | N/A | | `AAPL.US` | `NASDAQ:AAPL` | N/A | `AAPL` | | `BTC-USDT` | `BINANCE:BTCUSDT` | N/A | `BTCUSD` | **Note**: Most indicator code is instrument-agnostic — the user applies it to whatever chart they're viewing. Include a comment noting the original instrument for reference only. ## Limitations & Transparency When a Python strategy uses features that can't be directly translated, clearly note it: | Python Feature | Platform Limitation | |---------------|-------------------| | ML models (sklearn, etc.) | None — flag as "manual implementation required" | | Custom pandas operations | TDX — limited to built-in functions | | Multi-timeframe logic | TDX — no native MTF; Pine/MQL5 — supported | | Dynamic position sizing | TDX — indicator only, no position control | | External data (API calls) | All — indicators run offline on chart data only | Always add a comment block at the top listing any features that could not be translated. ## Quality Checklist Before outputting: - [ ] ALL 3 platform sections are included (Pine Script, TDX, MQL5) - [ ] Each platform section has proper header with usage instructions - [ ] Pine Script: `//@version=6` is first line, no plot() in local scope, ternary on single lines - [ ] TDX: all uppercase functions, `:=` for intermediate, `:` for output, `{comments}` - [ ] MQL5: proper handle-based API, `EMPTY_VALUE` for no-signal - [ ] Entry/exit conditions match the Python signal logic semantically across ALL platforms - [ ] Untranslatable features are clearly documented at the top of each section - [ ] Comment header notes the original Vibe-Trading run_id and instrument