| 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
load_skill("pine-script") — read this guide
read_file("config.json") — understand instruments, dates, parameters
read_file("code/signal_engine.py") — understand the Python strategy logic
- Translate the strategy to ALL platforms using the references below
write_file("artifacts/strategy.pine") — save the combined output
- Return the code in a code block with usage instructions per platform
Workflow: Generate from Description
load_skill("pine-script") — read this guide
- Write indicator/strategy code for ALL platforms based on the user's description
write_file("artifacts/strategy.pine") — save the combined output
- 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
// 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)
- Version declaration must be first line:
//@version=6
- Ternary operators MUST stay on one line:
text = condition ? "a" : "b"
- Line continuation: continuation lines must be indented MORE than the starting line
- No plot() in local scope (if/for/function) — use
plot(condition ? value : na)
- var: persistent state across bars; regular assignment recalculates each bar
- Avoid repainting: use
barstate.isconfirmed, lookahead=barmerge.lookahead_off
- 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
- Assignment:
:= for intermediate variables, : for output (plotted) lines
- Comments:
{comment} — curly braces, NOT //
- No semicolons optional: each statement ends with
;
- Colors:
COLORRED, COLORGREEN, COLORYELLOW, COLORWHITE, COLORBLUE, COLORCYAN, COLORMAGENTA
- Line styles:
LINETHICK2, POINTDOT, STICK, VOLSTICK
- Draw text:
DRAWTEXT(COND, PRICE, 'TEXT'), COLOR;
- Draw icon:
DRAWICON(COND, PRICE, ICON_ID);
- All function/variable names UPPERCASE
- No loops / no arrays — everything is vectorized bar-by-bar
- 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)
//+------------------------------------------------------------------+
//| 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
- Indicator handles: call
iMA() etc. in OnInit(), use CopyBuffer() to get values
- Buffer direction: MQL5 buffers are indexed 0=oldest by default; use
ArraySetAsSeries() to reverse
- EMPTY_VALUE: use for "no signal" on arrow plots
- Indicator vs EA: generate indicator (
.mq5), not Expert Advisor, to match "indicator export" purpose
- 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: