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(fill_method=None) |
(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(fill_method=None) |
(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:
1---2name: pine-script3description: Export backtest strategies to indicator/strategy code for major trading platforms — TradingView, 通达信, 同花顺, 东方财富, MT5.4---5
6## Overview
7
8This skill exports a Vibe-Trading strategy to **all major trading platforms** in one go.
9Output file: `artifacts/strategy.pine` (inside the run directory).
10
11Supported platforms (always generate ALL):
12
13| Group | Platforms | Language |
14|-------|-----------|----------|
15| International Charts | TradingView | Pine Script v6 |
16| China Equities | 通达信 / 同花顺 / 东方财富 | TDX Formula |
17| Forex / CFD | MetaTrader 5 | MQL5 |
18
19## Workflow: Export from Backtest
20
211. `load_skill("pine-script")` — read this guide
222. `read_file("config.json")` — understand instruments, dates, parameters
233. `read_file("code/signal_engine.py")` — understand the Python strategy logic
244. **Translate** the strategy to ALL platforms using the references below
255. `write_file("artifacts/strategy.pine")` — save the combined output
266. Return the code in a code block with usage instructions per platform
27
28## Workflow: Generate from Description
29
301. `load_skill("pine-script")` — read this guide
312. Write indicator/strategy code for ALL platforms based on the user's description
323. `write_file("artifacts/strategy.pine")` — save the combined output
334. Return the code with usage instructions
34
35## Output Format
36
37The output file uses this structure (all platforms in one file):
38
39```
40================================================================================
41 TRADINGVIEW — Pine Script v6
42 Paste into: Pine Editor → New blank indicator → Add to Chart
43================================================================================
44
45[Pine Script code here]
46
47================================================================================
48 通达信 / 同花顺 / 东方财富 (TDX Formula)
49 Paste into: 功能 → 公式管理器 → 新建指标公式
50================================================================================
51
52[TDX formula code here]
53
54================================================================================
55 MT5 — MQL5
56 Save as: .mq5 file → MetaEditor → Compile → Navigator → Attach to Chart
57================================================================================
58
59[MQL5 code here]
60
61```
62
63---
64
65# Platform Reference
66
67## 1. TradingView — Pine Script v6
68
69### Template
70
71```pinescript
72// This strategy was generated by Vibe-Trading
73// Paste into TradingView Pine Editor → Add to Chart
74//@version=6
75strategy("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)
76
77// ============================================================================
78// INPUTS
79// ============================================================================
80// [Group inputs logically with input.int(), input.float(), input.string()]
81
82// ============================================================================
83// CALCULATIONS
84// ============================================================================
85// [Core indicator calculations]
86
87// ============================================================================
88// CONDITIONS
89// ============================================================================
90longCondition = false
91shortCondition = false
92exitLongCondition = false
93exitShortCondition = false
94
95// ============================================================================
96// STRATEGY EXECUTION
97// ============================================================================
98if longCondition
99 strategy.entry("Long", strategy.long)
100if shortCondition
101 strategy.entry("Short", strategy.short)
102if exitLongCondition
103 strategy.close("Long")
104if exitShortCondition
105 strategy.close("Short")
106
107// ============================================================================
108// PLOTS
109// ============================================================================
110// [Visual overlays: moving averages, bands, signals]
111
112// ============================================================================
113// ALERTS
114// ============================================================================
115alertcondition(longCondition, title="Long Signal", message="Long entry signal triggered")
116alertcondition(shortCondition, title="Short Signal", message="Short entry signal triggered")
117```
118
119### Python → Pine Script Mapping
120
121| Python (pandas/numpy) | Pine Script v6 |
122|------------------------|----------------|
123| `df['close'].rolling(n).mean()` | `ta.sma(close, n)` |
124| `df['close'].ewm(span=n).mean()` | `ta.ema(close, n)` |
125| `ta.RSI(df['close'], n)` or manual RSI | `ta.rsi(close, n)` |
126| `ta.MACD(df['close'])` | `[macdLine, signalLine, hist] = ta.macd(close, 12, 26, 9)` |
127| `df['close'].rolling(n).std()` | `ta.stdev(close, n)` |
128| `df['high'].rolling(n).max()` | `ta.highest(high, n)` |
129| `df['low'].rolling(n).min()` | `ta.lowest(low, n)` |
130| `df['close'].pct_change(fill_method=None)` | `(close - close[1]) / close[1]` |
131| `df['volume'].rolling(n).mean()` | `ta.sma(volume, n)` |
132| `df['close'] > df['close'].shift(1)` | `close > close[1]` |
133| Bollinger Bands | `[mid, upper, lower] = ta.bb(close, length, mult)` |
134| ATR | `ta.atr(length)` |
135| ADX | `ta.adx(high, low, close, length)` |
136| Stochastic | `ta.stoch(close, high, low, length, smoothK, smoothD)` |
137| CCI | `ta.cci(close, length)` |
138| Williams %R | `ta.wpr(length)` |
139| MFI | `ta.mfi(close, length)` |
140| OBV | `ta.obv` |
141| VWAP | `ta.vwap` |
142
143### Data References
144
145| Python | Pine Script v6 |
146|--------|----------------|
147| `df['open']` | `open` |
148| `df['high']` | `high` |
149| `df['low']` | `low` |
150| `df['close']` | `close` |
151| `df['volume']` | `volume` |
152| `df.index` (datetime) | `time` |
153| `df['close'].shift(n)` | `close[n]` |
154
155### Signal Logic
156
157| Python Pattern | Pine Script v6 |
158|---------------|----------------|
159| `(fast > slow) & (fast.shift(1) <= slow.shift(1))` | `ta.crossover(fast, slow)` |
160| `(fast < slow) & (fast.shift(1) >= slow.shift(1))` | `ta.crossunder(fast, slow)` |
161| `signal.where(condition, 0)` | `condition ? value : 0` |
162| `np.where(cond, val_true, val_false)` | `cond ? val_true : val_false` |
163| `signal.clip(-1, 1)` | `math.max(-1, math.min(1, signal))` |
164| `signal.fillna(0)` | `nz(signal, 0)` |
165| `pd.isna(value)` | `na(value)` |
166
167### Position Sizing
168
169| Python Pattern | Pine Script v6 |
170|---------------|----------------|
171| Equal weight 1/N | `strategy.percent_of_equity` with `default_qty_value = 100/N` |
172| Full position on signal=1.0 | `default_qty_type=strategy.percent_of_equity, default_qty_value=100` |
173| Half position on signal=0.5 | Use `strategy.entry(..., qty=strategy.equity * 0.5 / close)` |
174| Stop-loss | `strategy.exit("Exit", stop=entryPrice * (1 - stopPct))` |
175| Take-profit | `strategy.exit("Exit", limit=entryPrice * (1 + tpPct))` |
176
177### Syntax Rules (Critical)
178
1791. **Version declaration must be first line**: `//@version=6`
1802. **Ternary operators MUST stay on one line**: `text = condition ? "a" : "b"`
1813. **Line continuation**: continuation lines must be indented MORE than the starting line
1824. **No plot() in local scope** (if/for/function) — use `plot(condition ? value : na)`
1835. **var**: persistent state across bars; regular assignment recalculates each bar
1846. **Avoid repainting**: use `barstate.isconfirmed`, `lookahead=barmerge.lookahead_off`
1857. **Limits**: max 500 bars lookback, 500 plot calls, 64 entry/exit per bar, 40 request.security()
186
187---
188
189## 2. 通达信 / 同花顺 / 东方财富 — TDX Formula
190
191These platforms share 95%+ identical formula syntax. Write ONE version that works on all three.
192
193### Template
194
195```
196{Vibe-Trading 策略导出}
197{策略名称: XXX}
198
199{——————— 参数 ———————}
200N:=14;
201M:=6;
202
203{——————— 指标计算 ———————}
204RSI_VAL:=RSI(CLOSE,N);
205MA_FAST:=MA(CLOSE,5);
206MA_SLOW:=MA(CLOSE,20);
207
208{——————— 买卖信号 ———————}
209BUY:CROSS(MA_FAST,MA_SLOW) AND RSI_VAL<40,COLORRED;
210SELL:CROSS(MA_SLOW,MA_FAST) AND RSI_VAL>60,COLORGREEN;
211
212DRAWTEXT(BUY,LOW,'B'),COLORYELLOW;
213DRAWTEXT(SELL,HIGH,'S'),COLORWHITE;
214```
215
216### Python → TDX Mapping
217
218| Python | TDX Formula |
219|--------|-------------|
220| `df['close'].rolling(n).mean()` | `MA(CLOSE,N)` |
221| `df['close'].ewm(span=n).mean()` | `EMA(CLOSE,N)` |
222| RSI | `RSI(CLOSE,N)` (returns 0-100) |
223| MACD | `MACD.DIF`, `MACD.DEA`, `MACD.MACD` or manual: `DIF:=EMA(CLOSE,12)-EMA(CLOSE,26); DEA:=EMA(DIF,9); MACD:=(DIF-DEA)*2;` |
224| Bollinger Bands | `BOLL(N,M)` → `BOLL.UPPER`, `BOLL.MID`, `BOLL.LOWER` or manual |
225| ATR | `ATR:=MA(MAX(MAX(HIGH-LOW,ABS(HIGH-REF(CLOSE,1))),ABS(LOW-REF(CLOSE,1))),N);` |
226| `df['close'].shift(n)` | `REF(CLOSE,N)` |
227| `df['high'].rolling(n).max()` | `HHV(HIGH,N)` |
228| `df['low'].rolling(n).min()` | `LLV(LOW,N)` |
229| crossover(fast, slow) | `CROSS(FAST,SLOW)` |
230| crossunder(fast, slow) | `CROSS(SLOW,FAST)` |
231| `df['volume']` | `VOL` |
232| `abs(x)` | `ABS(X)` |
233| `max(a,b)` | `MAX(A,B)` |
234| `min(a,b)` | `MIN(A,B)` |
235| conditional | `IF(COND,A,B)` |
236| `df['close'].pct_change(fill_method=None)` | `(CLOSE-REF(CLOSE,1))/REF(CLOSE,1)` |
237| count true in N bars | `COUNT(COND,N)` |
238| sum over N bars | `SUM(X,N)` |
239| std over N bars | `STD(CLOSE,N)` |
240| slope / linear regression | `SLOPE(CLOSE,N)` |
241
242### Syntax Rules
243
2441. **Assignment**: `:=` for intermediate variables, `:` for output (plotted) lines
2452. **Comments**: `{comment}` — curly braces, NOT `//`
2463. **No semicolons optional**: each statement ends with `;`
2474. **Colors**: `COLORRED`, `COLORGREEN`, `COLORYELLOW`, `COLORWHITE`, `COLORBLUE`, `COLORCYAN`, `COLORMAGENTA`
2485. **Line styles**: `LINETHICK2`, `POINTDOT`, `STICK`, `VOLSTICK`
2496. **Draw text**: `DRAWTEXT(COND, PRICE, 'TEXT'), COLOR;`
2507. **Draw icon**: `DRAWICON(COND, PRICE, ICON_ID);`
2518. **All function/variable names UPPERCASE**
2529. **No loops / no arrays** — everything is vectorized bar-by-bar
25310. **Max formula length**: ~10,000 characters per formula
254
255### Platform Differences
256
257| Feature | 通达信 | 同花顺 | 东方财富 |
258|---------|--------|--------|----------|
259| MACD built-in | `MACD(12,26,9)` | `MACD(12,26,9)` | same |
260| Stochastic | `KDJ(N,M1,M2)` | same | same |
261| Custom color | `COLOR+RRGGBB` | `COLOR+RRGGBB` | limited |
262| Strategy backtest | 条件选股 only | 条件选股 only | 条件选股 only |
263
264For maximum compatibility, avoid platform-specific extensions. Stick to core functions.
265
266---
267
268## 3. MetaTrader 5 — MQL5
269
270### Template (Custom Indicator)
271
272```mql5
273//+------------------------------------------------------------------+
274//| Generated by Vibe-Trading |
275//+------------------------------------------------------------------+
276#property copyright "Vibe-Trading"
277#property indicator_chart_window // or indicator_separate_window
278#property indicator_buffers 2
279#property indicator_plots 2
280#property indicator_color1 clrDodgerBlue
281#property indicator_color2 clrRed
282
283input int InpPeriod = 14; // Period
284
285double BuyBuffer[];
286double SellBuffer[];
287
288int OnInit()
289{
290 SetIndexBuffer(0, BuyBuffer, INDICATOR_DATA);
291 SetIndexBuffer(1, SellBuffer, INDICATOR_DATA);
292 PlotIndexSetInteger(0, PLOT_ARROW, 233); // up arrow
293 PlotIndexSetInteger(1, PLOT_ARROW, 234); // down arrow
294 PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ARROW);
295 PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_ARROW);
296 return(INIT_SUCCEEDED);
297}
298
299int OnCalculate(const int rates_total,
300 const int prev_calculated,
301 const datetime &time[],
302 const double &open[],
303 const double &high[],
304 const double &low[],
305 const double &close[],
306 const long &tick_volume[],
307 const long &volume[],
308 const int &spread[])
309{
310 int start = MathMax(prev_calculated - 1, InpPeriod);
311 for(int i = start; i < rates_total; i++)
312 {
313 BuyBuffer[i] = EMPTY_VALUE;
314 SellBuffer[i] = EMPTY_VALUE;
315
316 // === YOUR LOGIC HERE ===
317 // Example: if(buyCondition) BuyBuffer[i] = low[i];
318 // if(sellCondition) SellBuffer[i] = high[i];
319 }
320 return(rates_total);
321}
322```
323
324### Python → MQL5 Mapping
325
326| Python | MQL5 |
327|--------|------|
328| `df['close'].rolling(n).mean()` | `iMA(_Symbol, PERIOD_CURRENT, n, 0, MODE_SMA, PRICE_CLOSE)` or manual loop |
329| EMA | `iMA(..., MODE_EMA, ...)` |
330| RSI | `iRSI(_Symbol, PERIOD_CURRENT, n, PRICE_CLOSE)` |
331| MACD | `iMACD(_Symbol, PERIOD_CURRENT, 12, 26, 9, PRICE_CLOSE)` |
332| Bollinger | `iBands(_Symbol, PERIOD_CURRENT, n, 0, mult, PRICE_CLOSE)` |
333| ATR | `iATR(_Symbol, PERIOD_CURRENT, n)` |
334| Stochastic | `iStochastic(_Symbol, PERIOD_CURRENT, K, D, slowing, MODE_SMA, STO_LOWHIGH)` |
335| `df['close'].shift(n)` | `close[i-n]` (in OnCalculate loop) |
336| crossover | `buf[i] > ref[i] && buf[i-1] <= ref[i-1]` |
337
338### Syntax Rules
339
3401. **Indicator handles**: call `iMA()` etc. in `OnInit()`, use `CopyBuffer()` to get values
3412. **Buffer direction**: MQL5 buffers are indexed 0=oldest by default; use `ArraySetAsSeries()` to reverse
3423. **EMPTY_VALUE**: use for "no signal" on arrow plots
3434. **Indicator vs EA**: generate indicator (`.mq5`), not Expert Advisor, to match "indicator export" purpose
3445. **Handle-based API**: MQL5 uses handles — create in `OnInit`, read in `OnCalculate`
345
346---
347
348## Symbol Format Mapping
349
350When generating code, map Vibe-Trading instrument codes appropriately:
351
352| Vibe-Trading | TradingView | 通达信/同花顺 | MT5 |
353|-------------|-------------|---------------|-----|
354| `000001.SZ` | `SZSE:000001` | `000001` | N/A |
355| `600519.SH` | `SSE:600519` | `600519` | N/A |
356| `AAPL.US` | `NASDAQ:AAPL` | N/A | `AAPL` |
357| `BTC-USDT` | `BINANCE:BTCUSDT` | N/A | `BTCUSD` |
358
359**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.
360
361## Limitations & Transparency
362
363When a Python strategy uses features that can't be directly translated, clearly note it:
364
365| Python Feature | Platform Limitation |
366|---------------|-------------------|
367| ML models (sklearn, etc.) | None — flag as "manual implementation required" |
368| Custom pandas operations | TDX — limited to built-in functions |
369| Multi-timeframe logic | TDX — no native MTF; Pine/MQL5 — supported |
370| Dynamic position sizing | TDX — indicator only, no position control |
371| External data (API calls) | All — indicators run offline on chart data only |
372
373Always add a comment block at the top listing any features that could not be translated.
374
375## Quality Checklist
376
377Before outputting:
378- [ ] ALL 3 platform sections are included (Pine Script, TDX, MQL5)
379- [ ] Each platform section has proper header with usage instructions
380- [ ] Pine Script: `//@version=6` is first line, no plot() in local scope, ternary on single lines
381- [ ] TDX: all uppercase functions, `:=` for intermediate, `:` for output, `{comments}`
382- [ ] MQL5: proper handle-based API, `EMPTY_VALUE` for no-signal
383- [ ] Entry/exit conditions match the Python signal logic semantically across ALL platforms
384- [ ] Untranslatable features are clearly documented at the top of each section
385- [ ] Comment header notes the original Vibe-Trading run_id and instrument