指定
Refactor my current NIKA_FTS.mq5 into a minimal, fast, backtest-deterministic indicator that keeps:
-
Tilson T3 pair (fast/slow) with separate alphas → drives REV state
-
PSAR (plot + up/down cross signals)
-
Heikin-Ashi overlay (candles/bars/hollow), colored by REV state
Remove everything else (RSI, TSI, TRM, MA1/2/3, MA crosses, Curl, bar-color logic from RSI/TRM, etc.).
All logic must be closed-candle only (no live/intrabar behavior).
Scope of Work
KEEP & Implement
-
Tilson T3 (double-alpha)
-
Inputs:
input int aLength = 5; // fast T3 length input int Length = 8; // slow T3 length input double alphaFast = 0.70; // fast T3 alpha input double alphaSlow = 0.70; // slow T3 alpha
-
Buffers: anT3Average[] (fast), nT3Average[] (slow)
-
Plots: T3 Fast color line, T3 Slow color line, T3 Fill between them
-
Calls:
calc_t3_series(src_arr, total, aLength, alphaFast, anT3Average); calc_t3_series(src_arr, total, Length , alphaSlow, nT3Average);
-
-
REV state (Tilson-based)
-
For bar i (closed bars only):
-
uc : anT3Average[i] >= nT3Average[i] && Close[i] > nT3Average[i]
-
dc : anT3Average[i] <= nT3Average[i] && Close[i] < nT3Average[i]
-
ur : anT3Average[i] <= nT3Average[i] && Close[i] > nT3Average[i] (cross up)
-
dr : anT3Average[i] >= nT3Average[i] && Close[i] < nT3Average[i] (cross down)
-
-
Output buffer: Rev[] = +1 (bull: uc/ur), -1 (bear: dc/dr), 0 otherwise.
-
-
PSAR
-
Inputs: start , inc_v , max_v
-
Use iSAR() handle; copy to sar[]
-
Signal buffer: SARsig[] = +1 if Close[i] >= sar[i] , else -1
-
Plot: dots/arrows (bull/bear color by state)
-
-
Heikin-Ashi overlay (KEEP)
-
Inputs:
enum CandleType {CT_Candles }; input CandleType type =
CT_Candles
input bool haover = true; input bool rPrice = false; // optional real-close line -
Buffers: hac_* and/or hab_* + color index buffer
-
Color rule: map REV → HA color
-
Rev>0 → bull; Rev<0 → bear; Rev==0 → neutral
-
-
-
Alerts (closed-bar only)
-
Mode input:
enum AlertMode { AM_PER_BAR=0, AM_PER_BAR_CLOSE }; input AlertMode i_alert_mode = AM_PER_BAR_CLOSE; input bool REVUP=false, REVDWN=false, SARUP=false, SARDWN=false;
-
Trigger only on last fully closed bar:
-
REVUP : Close[i-1] <= nT3[i-1] && Close[i] > nT3[i]
-
REVDWN : Close[i-1] >= nT3[i-1] && Close[i] < nT3[i]
-
SARUP : cross above PSAR
-
SARDWN : cross below PSAR
-
-
-
2-row table (Rev, SAR)
-
Inputs:
input bool showTable=false; input int textSize=12, textWidth=100, textHeight=25, tableYpos=10, tableXpos=10;
-
Rows: “Rev”, “SAR”; icons ✅ / ❌ / 🔸 .
-
Update only when a new bar closes (no per-tick redraw).
-
REMOVE / PRUNE
-
All RSI/TSI/TRM/MA/Curl code: enums, inputs, buffers, plots, alerts, palette colors, paint logic, table cells.
-
Any leftover live/intrabar logic (e.g., using TimeCurrent , per-tick alerts, on-the-fly objects).
-
Any plotting/objects unrelated to T3/PSAR/HA/table.
Closed-Candle-Only Rules (hard requirement)
-
In OnCalculate , set:
const int last_closed = rates_total - 2; int start = (prev_calculated>0 ? prev_calculated-1 : warmup); for(int i=start; i<=last_closed; ++i) { ... } // NEVER use rates_total-1 in logic
-
Use data from arrays time[]/open[]/high[]/low[]/close[] only.
-
No SymbolInfoDouble(BID/ASK) or TimeCurrent() in logic/alerts.
-
Alerts and table update only when time[last_closed] changes (track static datetime last_bar_time ).
Performance & Code Quality (hard requirement)
-
Max speed / zero “dirty” code:
-
Single pass loop, no nested loops per bar.
-
Respect prev_calculated . Start at max(prev_calculated-1, warmup) .
-
Pre-allocate & reuse buffers; ArraySetAsSeries(..., true) once.
-
No dynamic ObjectCreate/Delete inside the bar loop. Table draw only once per closed bar; otherwise disabled.
-
Move branches out of hot loops; precompute booleans reused multiple times.
-
Keep #property indicator_plots and indicator_buffers to exact counts used.
-
Avoid repeated switch / Math* in hot path when possible; cache inputs.
-
Use built-in iSAR handle; a single CopyBuffer per call; fill EMPTY_VALUE for overflow.
-
No sleeps, prints, file I/O, or terminal calls in calc loop.
-
-
Backtest determinism:
-
No tick-dependent state. Results must be identical in visual/non-visual and multi-core tester.
-
No dependence on chart scaling/zoom or user objects.
-
-
Deinit hygiene: ObjectsDeleteByPrefix(0,"NIKA-") ; do not nuke user objects.
Final Inputs (only)
// T3 input int aLength = 5; input int Length = 8; input double alphaFast = 0.70; input double alphaSlow = 0.70; // PSAR input double start = 0.043; input double inc_v = 0.043; input double max_v = 0.34; // Visuals enum CandleType { CT_Hollow=0, CT_Bars, CT_Candles }; input CandleType type = CT_Hollow; input bool t3vis = true; input bool psarvis = true; input bool haover = true; input bool rPrice = false; // Alerts (closed-bar only) enum AlertMode { AM_PER_BAR=0, AM_PER_BAR_CLOSE }; input AlertMode i_alert_mode = AM_PER_BAR_CLOSE; input bool REVUP=false, REVDWN=false, SARUP=false, SARDWN=false; // Optional table input bool showTable=false; input int textSize=12, textWidth=100, textHeight=25, tableYpos=10, tableXpos=10;
Required Buffers/Plots
-
Calc: anT3Average[] , nT3Average[] , sar[] , src_arr[] , HA arrays ( hac_* / hab_* )
-
Signals: Rev[] , SARsig[]
-
Plots:
-
Color-line T3 Fast , color-line T3 Slow , T3 Fill (2 buffers)
-
PSAR dots
-
HA candles/bars/hollow (color index)
-
Real Close line (optional)
-
-
Palette: only colors used by T3/PSAR/HA.
Acceptance Tests
-
Compilation: MT5 current build, 0 errors / 0 warnings.
-
Search-clean: No occurrences of RSI , TSI , TRM , MA1 , MA2 , MA3 , HCROSS , Curl .
-
Closed-bar only: Changing tester from “Every tick” → “1 minute OHLC” yields identical buffers.
-
Performance: On M1 with 50k bars, first load < 50ms and incremental updates scale O(1) per bar (no visible lag).
-
Alerts: Fire once per qualifying closed bar (when AM_PER_BAR_CLOSE ), never on forming bar.
-
HA coloring: Follows Rev state correctly; table (if enabled) shows only “Rev”, “SAR”.
-
Determinism: Visual vs non-visual backtests produce the same Rev[]/SARsig[]/sar[]/T3 values.
Deliverables
-
Refactored NIKA_FTS.mq5 .
-
Short changelog of removed modules + final public API (inputs/plots/buffers).
-
QA note with 3 screenshots:
-
Bull REV + SARUP
-
Bear REV + SARDWN
-
Neutral REV
-
-
Export a consolidated Signal[] buffer: +1 bull / 0 neutral / −1 bear (mirrors Rev ).
-
Inputs for line widths and PSAR dot size.
input int WarmupBars = 500; // bars to prefill T3 before signaling
input int MaxHistory = 10000; // cap processing for speed; 0 = unlimited
input bool UseSeries = true; // ArraySetAsSeries on calc buffers