{"slug":"open-source-tradingview-optimizer","qid":"walk_forward","label":"walk_forward","post_title":"open-source-tradingview-optimizer","post_url":"/blog/open-source-tradingview-optimizer#q-walk_forward","columns":["in_sample_rank","cell","in_sample_sharpe","out_of_sample_sharpe"],"rows":[{"in_sample_rank":1,"cell":"30 / 50","in_sample_sharpe":1.05,"out_of_sample_sharpe":0.27},{"in_sample_rank":2,"cell":"25 / 50","in_sample_sharpe":1.02,"out_of_sample_sharpe":0.16},{"in_sample_rank":3,"cell":"5 / 200","in_sample_sharpe":1.01,"out_of_sample_sharpe":0.85},{"in_sample_rank":4,"cell":"20 / 50","in_sample_sharpe":0.98,"out_of_sample_sharpe":0.25},{"in_sample_rank":5,"cell":"5 / 150","in_sample_sharpe":0.98,"out_of_sample_sharpe":0.78},{"in_sample_rank":6,"cell":"10 / 100","in_sample_sharpe":0.96,"out_of_sample_sharpe":0.71},{"in_sample_rank":7,"cell":"15 / 50","in_sample_sharpe":0.9,"out_of_sample_sharpe":0.34},{"in_sample_rank":8,"cell":"15 / 100","in_sample_sharpe":0.87,"out_of_sample_sharpe":0.69},{"in_sample_rank":9,"cell":"10 / 200","in_sample_sharpe":0.84,"out_of_sample_sharpe":0.84},{"in_sample_rank":10,"cell":"10 / 150","in_sample_sharpe":0.81,"out_of_sample_sharpe":0.67},{"in_sample_rank":11,"cell":"5 / 50","in_sample_sharpe":0.75,"out_of_sample_sharpe":0.62},{"in_sample_rank":12,"cell":"15 / 150","in_sample_sharpe":0.71,"out_of_sample_sharpe":0.76},{"in_sample_rank":13,"cell":"15 / 200","in_sample_sharpe":0.69,"out_of_sample_sharpe":0.97},{"in_sample_rank":14,"cell":"25 / 200","in_sample_sharpe":0.66,"out_of_sample_sharpe":0.95},{"in_sample_rank":15,"cell":"5 / 100","in_sample_sharpe":0.66,"out_of_sample_sharpe":0.75},{"in_sample_rank":16,"cell":"20 / 100","in_sample_sharpe":0.65,"out_of_sample_sharpe":0.61},{"in_sample_rank":17,"cell":"10 / 50","in_sample_sharpe":0.56,"out_of_sample_sharpe":0.82},{"in_sample_rank":18,"cell":"30 / 150","in_sample_sharpe":0.51,"out_of_sample_sharpe":0.88},{"in_sample_rank":19,"cell":"20 / 150","in_sample_sharpe":0.48,"out_of_sample_sharpe":0.88},{"in_sample_rank":20,"cell":"30 / 200","in_sample_sharpe":0.48,"out_of_sample_sharpe":1.03},{"in_sample_rank":21,"cell":"25 / 150","in_sample_sharpe":0.46,"out_of_sample_sharpe":0.88},{"in_sample_rank":22,"cell":"20 / 200","in_sample_sharpe":0.44,"out_of_sample_sharpe":1.15},{"in_sample_rank":23,"cell":"30 / 100","in_sample_sharpe":0.43,"out_of_sample_sharpe":0.8},{"in_sample_rank":24,"cell":"25 / 100","in_sample_sharpe":0.32,"out_of_sample_sharpe":0.61}],"shape":"ranking","sql":"WITH\n    series AS\n    (\n        SELECT arraySort(r -> r.1, groupArray((date, toFloat64(close)))) AS rows_sorted\n        FROM global_markets.stocks_daily_aggs\n        WHERE ticker = 'SPY'\n          AND date >= '2016-01-04'\n          AND date <= '2025-06-30'\n    ),\n    grid AS\n    (\n        SELECT\n            arrayMap(r -> r.2, rows_sorted)                                         AS px,\n            length(arrayFilter(r -> r.1 < toDate('2021-01-01'), rows_sorted))       AS split_at,\n            g.1                                                                     AS fast,\n            g.2                                                                     AS slow\n        FROM series\n        ARRAY JOIN\n        [\n            (5, 50), (5, 100), (5, 150), (5, 200),\n            (10, 50), (10, 100), (10, 150), (10, 200),\n            (15, 50), (15, 100), (15, 150), (15, 200),\n            (20, 50), (20, 100), (20, 150), (20, 200),\n            (25, 50), (25, 100), (25, 150), (25, 200),\n            (30, 50), (30, 100), (30, 150), (30, 200)\n        ] AS g\n    ),\n    cells AS\n    (\n        SELECT\n            fast,\n            slow,\n            arrayMap(\n                i -> if(arrayAvg(arraySlice(px, i - fast + 1, fast)) > arrayAvg(arraySlice(px, i - slow + 1, slow)),\n                        px[i + 1] / px[i] - 1,\n                        0.0),\n                range(200, split_at)\n            ) AS is_rets,\n            arrayMap(\n                i -> if(arrayAvg(arraySlice(px, i - fast + 1, fast)) > arrayAvg(arraySlice(px, i - slow + 1, slow)),\n                        px[i + 1] / px[i] - 1,\n                        0.0),\n                range(split_at, length(px))\n            ) AS oos_rets\n        FROM grid\n    ),\n    scored AS\n    (\n        SELECT\n            concat(toString(fast), ' / ', toString(slow)) AS cell,\n            round(arrayAvg(is_rets)\n                  / sqrt(arrayAvg(arrayMap(r -> r * r, is_rets)) - pow(arrayAvg(is_rets), 2))\n                  * sqrt(252), 2)                         AS in_sample_sharpe,\n            round(arrayAvg(oos_rets)\n                  / sqrt(arrayAvg(arrayMap(r -> r * r, oos_rets)) - pow(arrayAvg(oos_rets), 2))\n                  * sqrt(252), 2)                         AS out_of_sample_sharpe\n        FROM cells\n    )\nSELECT\n    row_number() OVER (ORDER BY in_sample_sharpe DESC) AS in_sample_rank,\n    cell,\n    in_sample_sharpe,\n    out_of_sample_sharpe\nFROM scored\nORDER BY in_sample_rank","computed_at":"2026-09-22T14:53:22.767080+00:00","elapsed":0.007290534}