Strategy · Pine Script v6 · On the chart

SMA cross + TokIO check

by Kuzi-DEV

This strategy plots a fast and a slow simple moving average on the price chart and trades long only.

View on GitHub

GitHub stars4on the repository
Pine versionv6current
Lines of code184
Settings5inputs
LicenceMIT
Last update13 days ago15 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.

Source Code

184 lines of Pine Script v6 from pine/demo_sma_cross.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

demo_sma_cross.pine
//@version=6
// Demo: a long-only SMA crossover with the TokIO check pasted underneath.
// On SPY daily it looks significant alone; set "Variants tried" to the 20
// parameter sets you might have tried and it isn't.
// To use with your own strategy, paste pine/tokio_check.pine below your code.
strategy("SMA cross + TokIO check", overlay = true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.05)
fastLen = input.int(10, "Fast SMA")
slowLen = input.int(30, "Slow SMA")
f = ta.sma(close, fastLen)
s = ta.sma(close, slowLen)
plot(f, color = color.teal)
plot(s, color = color.orange)
if ta.crossover(f, s)
    strategy.entry("Long", strategy.long)
if ta.crossunder(f, s)
    strategy.close("Long")

// ─────────────────────────────────────────────────────────────────────────────
// TokIO backtest check for TradingView — paste below your strategy's code.
// https://github.com/Kuzi-DEV/Tokio-ai   (MIT licence)
//
// Is this strategy's profit distinguishable from luck? Reads the strategy's
// closed trades and draws a table on the chart with:
//   • a one-sided test of the mean trade return that allows for serial
//     dependence (Bartlett HAC, Andrews bandwidth, Kiefer-Vogelsang fixed-b),
//     the same test as TokIO's Python check_backtest on a trade list
//   • Sidak's correction for the number of variants you tried ("Trials")
//   • the Probabilistic / Deflated Sharpe Ratio (Bailey & Lopez de Prado),
//     as published and with the dependence correction
//   • the minimum track record length, and a symmetric-trim check
//
// A trade's return is its P&L as a % of the position's value
// (strategy.closedtrades.profit_percent), so position sizing doesn't move
// the verdict. The Python package does more — several variants corrected
// for each other, probability of backtest overfitting, costs/breakeven, the
// lookahead (one-bar delay) check — on the Strategy Tester's trade export:
//     pip install tokio-ai
//     tokio-ai-backtest "List of trades.csv" --trials 30
//
// Requires: //@version=6 and a strategy() script. Rename nothing below.
// ─────────────────────────────────────────────────────────────────────────────

tokio_trials = input.int(1, "Variants tried (incl. this one)", minval = 1, group = "TokIO check",
     tooltip = "Every parameter set, indicator or rule you tried before keeping this one. Be honest: the correction is only as good as this number.")
tokio_alpha = input.float(0.05, "Significance level", minval = 0.001, maxval = 0.5, group = "TokIO check")
tokio_pos = input.string("bottom_right", "Table position", options = ["top_left", "top_center", "top_right", "middle_left", "middle_center", "middle_right", "bottom_left", "bottom_center", "bottom_right"], group = "TokIO check")

// Standard normal CDF (Abramowitz & Stegun 7.1.26 erf, |error| < 1.5e-7)
tokio_cdf(float tk_z) =>
    tk_x = math.abs(tk_z) / math.sqrt(2.0)
    tk_t = 1.0 / (1.0 + 0.3275911 * tk_x)
    tk_y = 1.0 - (((((1.061405429 * tk_t - 1.453152027) * tk_t) + 1.421413741) * tk_t - 0.284496736) * tk_t + 0.254829592) * tk_t * math.exp(-tk_x * tk_x)
    tk_z >= 0 ? 0.5 * (1.0 + tk_y) : 0.5 * (1.0 - tk_y)

// Inverse standard normal CDF (Acklam, relative error < 1.2e-9)
tokio_inv(float tk_p) =>
    tk_a1 = -3.969683028665376e+01
    tk_a2 = 2.209460984245205e+02
    tk_a3 = -2.759285104469687e+02
    tk_a4 = 1.383577518672690e+02
    tk_a5 = -3.066479806614716e+01
    tk_a6 = 2.506628277459239e+00
    tk_b1 = -5.447609879822406e+01
    tk_b2 = 1.615858368580409e+02
    tk_b3 = -1.556989798598866e+02
    tk_b4 = 6.680131188771972e+01
    tk_b5 = -1.328068155288572e+01
    tk_c1 = -7.784894002430293e-03
    tk_c2 = -3.223964580411365e-01
    tk_c3 = -2.400758277161838e+00
    tk_c4 = -2.549732539343734e+00
    tk_c5 = 4.374664141464968e+00
    tk_c6 = 2.938163982698783e+00
    tk_d1 = 7.784695709041462e-03
    tk_d2 = 3.224671290700398e-01
    tk_d3 = 2.445134137142996e+00
    tk_d4 = 3.754408661907416e+00
    float tk_r = na
    if tk_p < 0.02425
        tk_q = math.sqrt(-2.0 * math.log(tk_p))
        tk_r := (((((tk_c1 * tk_q + tk_c2) * tk_q + tk_c3) * tk_q + tk_c4) * tk_q + tk_c5) * tk_q + tk_c6) / ((((tk_d1 * tk_q + tk_d2) * tk_q + tk_d3) * tk_q + tk_d4) * tk_q + 1.0)
    else if tk_p <= 1.0 - 0.02425
        tk_q = tk_p - 0.5
        tk_s = tk_q * tk_q
        tk_r := (((((tk_a1 * tk_s + tk_a2) * tk_s + tk_a3) * tk_s + tk_a4) * tk_s + tk_a5) * tk_s + tk_a6) * tk_q / (((((tk_b1 * tk_s + tk_b2) * tk_s + tk_b3) * tk_s + tk_b4) * tk_s + tk_b5) * tk_s + 1.0)
    else
        tk_q = math.sqrt(-2.0 * math.log(1.0 - tk_p))
        tk_r := -(((((tk_c1 * tk_q + tk_c2) * tk_q + tk_c3) * tk_q + tk_c4) * tk_q + tk_c5) * tk_q + tk_c6) / ((((tk_d1 * tk_q + tk_d2) * tk_q + tk_d3) * tk_q + tk_d4) * tk_q + 1.0)
    tk_r

tokio_fmt(float tk_v, int dp) =>
    na(tk_v) ? "–" : str.tostring(tk_v, dp == 2 ? "#,##0.00" : dp == 3 ? "0.000" : "0.0000")

if barstate.islastconfirmedhistory or (barstate.islast and barstate.isrealtime)
    int tk_n = strategy.closedtrades
    var table tk_tbl = na
    if not na(tk_tbl)
        table.delete(tk_tbl)
    tk_pos = switch tokio_pos
        "top_left" => position.top_left
        "top_center" => position.top_center
        "top_right" => position.top_right
        "middle_left" => position.middle_left
        "middle_center" => position.middle_center
        "middle_right" => position.middle_right
        "bottom_left" => position.bottom_left
        "bottom_center" => position.bottom_center
        => position.bottom_right
    tk_tbl := table.new(tk_pos, 2, 12, bgcolor = color.new(color.black, 0), border_color = color.gray, border_width = 1, frame_color = color.gray, frame_width = 1)
    tk_txt = color.white
    table.cell(tk_tbl, 0, 0, "TokIO check", text_color = tk_txt, text_size = size.small)
    if tk_n < 60
        table.cell(tk_tbl, 1, 0, "NOT REPORTABLE", text_color = color.orange, text_size = size.small)
        table.cell(tk_tbl, 0, 1, "Closed trades", text_color = tk_txt, text_size = size.small)
        table.cell(tk_tbl, 1, 1, str.tostring(tk_n) + " (need 60+)", text_color = tk_txt, text_size = size.small)
    else
        tk_rets = array.new_float(0)
        for tk_i = 0 to tk_n - 1
            array.push(tk_rets, strategy.closedtrades.profit_percent(tk_i) / 100.0)
        float tk_m = array.avg(tk_rets)
        // central moments (population), Bartlett long-run variance
        float tk_s2 = 0.0
        float tk_s3 = 0.0
        float tk_s4 = 0.0
        float tk_g1 = 0.0
        for tk_i = 0 to tk_n - 1
            tk_d = array.get(tk_rets, tk_i) - tk_m
            tk_s2 += tk_d * tk_d
            tk_s3 += tk_d * tk_d * tk_d
            tk_s4 += tk_d * tk_d * tk_d * tk_d
            if tk_i > 0
                tk_g1 += tk_d * (array.get(tk_rets, tk_i - 1) - tk_m)
        tk_v = tk_s2 / tk_n
        tk_sd = math.sqrt(tk_s2 / (tk_n - 1))
        tk_skew = (tk_s3 / tk_n) / math.pow(tk_v, 1.5)
        tk_kurt = (tk_s4 / tk_n) / (tk_v * tk_v)
        // Andrews (1991) AR(1) plug-in and the Newey-West rule; the larger wins
        tk_rho = math.max(-0.97, math.min(0.97, tk_g1 / tk_s2))
        tk_a1 = 4.0 * tk_rho * tk_rho / (math.pow(1.0 - tk_rho, 2) * math.pow(1.0 + tk_rho, 2))
        int tk_L = math.min(tk_n - 1, math.max(int(math.floor(4.0 * math.pow(tk_n / 100.0, 2.0 / 9.0))), int(1.1447 * math.pow(tk_a1 * tk_n, 1.0 / 3.0))))
        float tk_lrv = tk_s2
        if tk_L > 0
            for tk_l = 1 to tk_L
                float tk_gl = 0.0
                for tk_t = tk_l to tk_n - 1
                    tk_gl += (array.get(tk_rets, tk_t) - tk_m) * (array.get(tk_rets, tk_t - tk_l) - tk_m)
                tk_lrv += 2.0 * (1.0 - tk_l / (tk_L + 1.0)) * tk_gl
        tk_lrv := math.max(tk_lrv / tk_n, 1e-18)
        tk_b = (tk_L + 1.0) / tk_n
        tk_fb = 1.6449 / (1.6449 + 2.1859 * tk_b + 0.3142 * tk_b * tk_b - 0.3427 * tk_b * tk_b * tk_b)
        tk_z = tk_m / math.sqrt(tk_lrv / tk_n) * tk_fb
        tk_p_alone = 1.0 - tokio_cdf(tk_z)
        tk_p_adj = 1.0 - math.pow(1.0 - tk_p_alone, tokio_trials)
        tk_z_naive = tk_m / (tk_sd / math.sqrt(tk_n))
        tk_p_naive = 1.0 - tokio_cdf(tk_z_naive)
        // Sharpe per trade; annualized by trades per year
        tk_sr = tk_m / tk_sd
        tk_span_years = (strategy.closedtrades.exit_time(tk_n - 1) - strategy.closedtrades.entry_time(0)) / (365.25 * 86400000.0)
        tk_tpy = tk_span_years > 0 ? tk_n / tk_span_years : na
        tk_sr_ann = na(tk_tpy) ? na : tk_sr * math.sqrt(tk_tpy)
        // PSR / DSR (Bailey & Lopez de Prado); vr scales Var(SR) for dependence
        tk_vr = (tk_lrv / tk_v) / (tk_fb * tk_fb)
        tk_core = math.max(1.0 - tk_skew * tk_sr + (tk_kurt - 1.0) / 4.0 * tk_sr * tk_sr, 1e-12)
        tk_gam = 0.5772156649015329
        tk_bench = tokio_trials > 1 ? math.sqrt(1.0 / (tk_n - 1)) * ((1.0 - tk_gam) * tokio_inv(1.0 - 1.0 / tokio_trials) + tk_gam * tokio_inv(1.0 - 1.0 / (tokio_trials * math.e))) : 0.0
        tk_psr_pub = tokio_cdf((tk_sr - tk_bench) * math.sqrt(tk_n - 1) / math.sqrt(tk_core))
        tk_psr_dep = tokio_cdf((tk_sr - tk_bench) * math.sqrt(tk_n - 1) / math.sqrt(tk_core * tk_vr))
        tk_mintrl = tk_sr > tk_bench ? 1.0 + tk_core * tk_vr * math.pow(tokio_inv(0.95) / (tk_sr - tk_bench), 2) : na
        // symmetric trim: drop the 5 best and 5 worst trades
        tk_sorted = array.copy(tk_rets)
        array.sort(tk_sorted, order.ascending)
        tk_k = math.min(5, int(tk_n / 20))
        tk_tr = array.slice(tk_sorted, tk_k, tk_n - tk_k)
        tk_sr_trim = array.stdev(tk_tr, false) > 0 ? array.avg(tk_tr) / array.stdev(tk_tr, false) * (na(tk_tpy) ? 1.0 : math.sqrt(tk_tpy)) : na
        tk_sig = tk_p_adj <= tokio_alpha
        tk_verdict = tk_sig ? "SIGNIFICANT" : "NOT SIGNIFICANT"
        table.cell(tk_tbl, 1, 0, tk_verdict + (tokio_trials > 1 ? " (" + str.tostring(tokio_trials) + " trials)" : ""), text_color = tk_sig ? color.lime : color.red, text_size = size.small)
        tk_rows = array.from("p-value, corrected", "p-value, this alone", "p-value, plain t-test", "Sharpe (annualized)", (tokio_trials > 1 ? "Deflated" : "Probabilistic") + " Sharpe Ratio", "  as published (indep. trades)", "Min. track record (trades)", "Sharpe w/o 5 best & 5 worst", "Closed trades", "Trades per year")
        tk_vals = array.from(tokio_fmt(tk_p_adj, 4), tokio_fmt(tk_p_alone, 4), tokio_fmt(tk_p_naive, 4), tokio_fmt(tk_sr_ann, 2), tokio_fmt(tk_psr_dep, 3) + "  (0.95 passes)", tokio_fmt(tk_psr_pub, 3), na(tk_mintrl) ? "never" : str.tostring(math.ceil(tk_mintrl)), tokio_fmt(tk_sr_trim, 2), str.tostring(tk_n), tokio_fmt(tk_tpy, 2))
        for tk_i = 0 to array.size(tk_rows) - 1
            table.cell(tk_tbl, 0, tk_i + 1, array.get(tk_rows, tk_i), text_color = tk_txt, text_size = size.small, text_halign = text.align_left)
            table.cell(tk_tbl, 1, tk_i + 1, array.get(tk_vals, tk_i), text_color = tk_txt, text_size = size.small, text_halign = text.align_right)
        table.cell(tk_tbl, 0, 11, "Mean trade return " + tokio_fmt(tk_m * 100.0, 3) + "%; HAC lag window " + str.tostring(tk_L), text_color = color.gray, text_size = size.tiny, text_halign = text.align_left)
        table.merge_cells(tk_tbl, 0, 11, 1, 11)

Overview

SMA cross + TokIO check enters when the fast average crosses above the slow average and closes the position when the fast average crosses back below. There is no stop loss or take profit. A table in a chosen corner reports a dependence-aware test of mean trade return, a Sidak correction for the number of variants tried, probabilistic and deflated Sharpe ratios, a minimum track record length, and a symmetric-trim check. Fast and slow lengths, significance level, trial count, and table position are inputs.

Details

Published by

Kuzi-DEV on GitHub

Type

Strategy, Pine Script v6

Draws

On the price chart

Category

Trend, Moving averages, Screeners & dashboards

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • The strategy enters trades without a stop loss

Topics

algorithmic-tradingfinancehypothesis-testingllm-agentpythonquantitative-financestatisticspermutation-testreproducible-researchbacktest-overfitting

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Fast SMAint10fastLen
Slow SMAint30slowLen
Variants tried (incl. this one)int1tokio_trials
Significance levelfloat0.05tokio_alpha
Table positionstringbottom_righttokio_pos
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

AC- MY SCRIPT1

by hasnocool
106 stars

This strategy plots an Optimized Trend Tracker and a selectable moving-average support line on the price chart. It builds the average as SMA, EMA, WMA, TMA, VAR, WWMA, ZLEMA, or TSF, then offsets long and short stops by a percent of that average. Optional mark

Strategy v5 TrendMoving averages
Updated 2 years ago · GPL-3.0 GitHub repository of AC- MY SCRIPT1

Calculates a custom moving average (MaMA) by modifying the source price with price momentum, acceleration, and psychological win-rate probability before applying an EMA or SMA. Plots the adjusted moving average directly on the price chart alongside optional re

Strategy v5 Moving averagesTrend
Updated 4 years ago · None stated GitHub repository of Momentum Adjusted Moving Average by DGT

This long-only trend-following strategy combines Ichimoku Kinko Hyo components with higher timeframe moving average filters. It triggers long entries when price trades above a higher timeframe EMA and a bullish Tenkan-Sen cross above Kijun-Sen occurs under fav

Strategy v5 TrendOscillators & momentum
Updated 1 year ago · MPL-2.0 GitHub repository of Ichimoku Kinko Hyo Momentum Strategy

This strategy calculates trend direction across three user-defined higher timeframes using dual Simple Moving Averages, filtered by On-Balance Volume and Commodity Channel Index conditions alongside fractal pivot swings. Entries trigger when multi-timeframe tr

Strategy v5 TrendMoving averages Repaints
Updated 5 months ago · None stated GitHub repository of Fractals with Pivot Trendlines Strategy

CTC Comet Strategy 7.2024.1

by wynnforthework
2 stars

This strategy executes trades based on dual exponential moving average trend alignment, customizable Bollinger Bands, and normalized ATR volatility thresholds. It enters positions in the direction of the moving average trend and manages risk using a dynamic st

Strategy v5 TrendMoving averages
Updated 1 year ago · None stated GitHub repository of CTC Comet Strategy 7.2024.1

EMA Trend Surfer

by nxtaiapp
2 stars

EMA Trend Surfer is a dual-timeframe trend-following strategy designed for index futures such as MES and MNQ. It determines overall trend direction using fast and slow exponential moving averages on a higher timeframe while seeking entry signals on a lower tim

Strategy v5 TrendMoving averages
Updated 11 months ago · MIT GitHub repository of EMA Trend Surfer

More strategys

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers