Strasmore Research
ஆழ்ந்த ஆய்வு Matt Connorஆசிரியர் Matt Connor · புதுப்பிக்கப்பட்டது 2026-08-08

Python-ல் API Key இன்றி மீண்டும் உருவாக்கக்கூடிய Backtest

API Key இன்றி Python மூலம் மீண்டும் உருவாக்கக்கூடிய Backtest முறையை அறியுங்கள். Pinned install மற்றும் தரவுத் தொகுப்புகளைப் பயன்படுத்தி சந்தை தரவுகளின் உண்மைத்தன்மையை ஆராயுங்கள்.

பைதான் (Python) மூலம் மீண்டும் உருவாக்கக்கூடிய பேக்டெஸ்ட் (Backtest)

ஒரு அந்நிய நபர், புதிய கணினியில் உங்கள் குறியீட்டை இயக்கும்போது, எந்தவிதமான கணக்கு விவரங்களோ அல்லது API key-களோ இன்றி, நீங்கள் பெற்ற அதே முடிவுகளைப் பெறுவதே மீண்டும் உருவாக்கக்கூடிய (reproducible) பேக்டெஸ்ட் ஆகும். பெரும்பாலான பயிற்சிகள் முதல் வரியிலேயே இந்தத் தேர்வில் தோல்வியடைகின்றன; ஏனெனில், நேரடி தரவிறக்கம் (live download) செய்யும்போது, ஆசிரியருக்குக் கிடைத்த அதே விலை வரலாற்றை அடுத்த வாசகருக்குத் தருவதில்லை. இந்த வழிகாட்டி quantjourney-bt-ன் 0.12.4 பதிப்பை ஒரு திறந்தநிலை இயந்திரமாகப் பயன்படுத்துகிறது. இது எந்தவிதமான நற்சான்றிதழ்களும் (credentials) இன்றி அதன் உதாரணங்களை இயக்குகிறது. பின்னர், உண்மையான சந்தை தரவுகளைப் பயன்படுத்தி, ஒருமுறை மட்டும் சுத்தமாக இயக்கும் சோதனையில் கூட எவற்றை அறிய முடியாது என்பதை விளக்குகிறது.

ஒரு backtest-ஐ மீண்டும் அதே முடிவுகளைத் தரும் வகையில் (reproducible) உருவாக்குவது எப்படி?

இங்கு 'reproducibility' என்பதற்கு ஒரு குறுகிய, சோதிக்கக்கூடிய அர்த்தம் உள்ளது: வேறொரு நபர் ஒரு புதிய கணினியில் ஒரே ஒரு கட்டளையை (command) இயக்கும்போது, உங்கள் முடிவுகள் தசம புள்ளி வரை அப்படியே கிடைக்க வேண்டும். இரண்டு சாதாரண விஷயங்கள் இதைத் தடுக்கின்றன.

முதலாவது, நிரல் (code). 0.x பதிப்பில் உள்ள ஒரு library, அதன் அடுத்தடுத்த சிறிய பதிப்புகளுக்கு இடையே இணக்கத்தன்மையை (compatibility) உறுதி செய்வதில்லை. ஒரு பெயர் மாற்றம், இயல்புநிலை அமைப்பில் மாற்றம், அல்லது நிரல் வரிசையில் மாற்றம் ஏற்பட்டால், உங்கள் script தொடர்ந்து இயங்கும், ஆனால் தவறான முடிவுகளைத் தரும்.

இரண்டாவது, தரவு (data). ஒரு tutorial-ன் முதல் வரியிலேயே நேரடி பதிவிறக்கம் (live download) இருந்தால், அது மீண்டும் அதே முடிவுகளைத் தரும் வகையில் இருக்காது. தரவு வழங்குநர்கள் வரலாற்றுத் தரவுகளைத் திருத்துவார்கள், பங்குப் பிரிப்புக்கு (splits) ஏற்ப மாற்றங்களைச் செய்வார்கள், மற்றும் விடுபட்ட தரவுகளை நிரப்புவார்கள். இதனால், ஒரு மாதம் கழித்து அதே script-ஐ இயக்கினால் வெவ்வேறு முடிவுகள் கிடைக்கும். ஒருமுறை முடிவுகள் வந்த பிறகு, நிரலில் மாற்றம் நடந்ததா அல்லது தரவில் மாற்றம் நடந்ததா என்பதை உங்களால் கண்டறிய முடியாது.

இந்தத் திட்டத்திலிருந்து நாம் பின்பற்ற வேண்டிய முறை என்னவென்றால், ஒரு நிலையான engine பதிப்பையும், அந்த package-க்குள்ளேயே சிறிய தொகுப்பாக இணைக்கப்பட்ட தரவையும் (bundled dataset) ஒன்றாகப் பயன்படுத்துவதாகும்.

நிறுவுவதற்கான கட்டளை: pip install quantjourney-bt==0.12.4

quantjourney-bt என்பது QuantJourney backtester ஆகும். இது Apache License 2.0-ன் கீழ் வெளியிடப்பட்டுள்ளது மற்றும் இதற்கு Python 3.11 அல்லது அதற்குப் பிந்தைய பதிப்பு தேவைப்படுகிறது. பதிப்பு 0.12.4, 21 ஜூலை 2026 அன்று வெளியிடப்பட்டது. ஆகஸ்ட் 2026-ல் ஆவணப்படுத்தப்பட்டபடி, கீழே உள்ள ஒவ்வொரு கட்டளையும் இந்தப் பதிப்பையே குறிக்கின்றன.

தனிமைப்படுத்தப்பட்ட சூழலில் (isolated environment) வேலை செய்யுங்கள். python3 -m venv .venv ஒரு சூழலை உருவாக்குகிறது, source .venv/bin/activate அதற்குள் நுழைகிறது, மற்றும் python -m pip install -U pip அதற்குள் உள்ள நிறுவியை (installer) புதுப்பிக்கிறது. பின்னர், சரியான பதிப்பை இவ்வாறு எடுத்துக் கொள்ளுங்கள்: pip install quantjourney-bt==0.12.4.

இந்தத் திட்டம், பின் செய்யப்படாத (unpinned) வடிவமான pip install quantjourney-bt-ஐ ஆவணப்படுத்துகிறது. ==0.12.4 பகுதி உங்கள் பொறுப்பாகும், மேலும் 0.x நிலையில் இது பயனுள்ளதாக இருக்கும். அடுத்த நபர் கண்டறியும் வகையில் பின் செய்த விவரத்தை எழுதி வையுங்கள்: pip freeze > requirements.txt, நீங்கள் குறிப்பிடாதவை உட்பட அனைத்து தீர்க்கப்பட்ட சார்புகளையும் (resolved dependencies) பதிவு செய்கிறது.

இரண்டு விருப்பத்தேர்வு கூடுதல் வசதிகள் உள்ளன. pip install "quantjourney-bt[wf]", walk-forward மற்றும் optimization உதாரணங்களுக்காக Optuna-வைச் சேர்க்கிறது. pip install "quantjourney-bt[data]", ஒப்பீட்டு அளவீடுகளுக்கு (benchmarks) பயன்படுத்தப்படும் yfinance fallback-ஐச் சேர்க்கிறது.

Apache-2.0 என்பது தாராளமான உரிமமாகும். நீங்கள் குறியீட்டை வணிக ரீதியாகப் பயன்படுத்தலாம் மற்றும் மாற்றியமைக்கலாம். மறுவிநியோகம் செய்யும் போது உரிமம் மற்றும் அறிவிப்பு கோப்புகளை நீங்கள் வைத்திருக்க வேண்டும், மேலும் பங்களிப்பாளர்கள் காப்புரிமை உரிமைகளை வெளிப்படையாக வழங்குகிறார்கள்.

API விசை (API key) இன்றி தொகுக்கப்பட்ட SMA உதாரணத்தை இயக்குவது எப்படி

இந்த களஞ்சியத்தில் (repository) ஐம்பது இயங்கக்கூடிய உத்தி உதாரணங்கள் (example strategies) ஒரு தொடக்க ஸ்கிரிப்ட்டுடன் வழங்கப்பட்டுள்ளன. இவை எடை அடிப்படையிலான பாதை மற்றும் ஆணை அடிப்படையிலான பாதை என பிரிக்கப்பட்டுள்ளன; அவற்றுள் ஐந்து walk-forward பணிப்பாய்வுகளும் அடங்கும். ./strategy.sh --list பட்டியலை அச்சிடுகிறது. ./strategy.sh example_weights_01_sma_daily --check ஒரு குறிப்பிட்ட உத்தியை மட்டும் இறக்குமதி செய்கிறது, இது எந்த தரவையும் அணுகாது. நிறுவல் சரியாக உள்ளதா என்பதை உறுதிப்படுத்த இதுவே மிக விரைவான வழியாகும்.

டெமோ இயக்கமானது ஒரே வரியில் அமையும்: ./strategy.sh example_weights_01_sma_daily --sample-data --output /tmp/qj-sample

--sample-data கொடிதான் (flag) இதன் முக்கிய நோக்கமாகும். இந்தத் திட்டம் அதன் பின்னணியில் உள்ள தரவுத்தொகுப்பை இவ்வாறு விவரிக்கிறது:

மாதிரி தரவுத்தொகுப்பு வேண்டுமென்றே சிறியதாகவும், மீண்டும் உருவாக்கக்கூடியதாகவும் வைக்கப்பட்டுள்ளது. கணக்கு எதையும் உருவாக்காமல், நிறுவல் சரிபார்ப்பு, அறிக்கை உருவாக்கம் மற்றும் என்ஜின் செயல்பாட்டைப் புரிந்துகொள்ள இது பயனுள்ளதாக இருக்கும்.
ஆதாரம்: quantjourney-bt README, பதிப்பு 0.12.4, வாசிக்கப்பட்டது 6 ஆகஸ்ட் 2026.

இந்த இயக்கம் கன்சோலில் முடிவுகளைக் காட்டுவதற்குப் பதிலாக ஒரு கோப்பகத்தை (directory) உருவாக்குகிறது: summary.txt மற்றும் summary.json, ஒரு metrics.csv, அதன் equity_curve.png அருகில் ஒரு equity_curve.csv, ஒரு dashboard.html, ஒரு plots/ கோப்புறை, மற்றும் இயக்கம் எவ்வாறு கட்டமைக்கப்பட்டது என்பதைப் பதிவு செய்யும் ஒரு run_metadata.json. அந்த கடைசி கோப்பைத்தான் பெரும்பாலானோர் கவனிக்கத் தவறுவார்கள், ஆனால் ஓராண்டு கழித்து முடிவுகளைத் தணிக்கை செய்ய அதுவே மிக முக்கியமானது.

கிடைக்கும் அளவீடுகளை (metrics) நேர்மையாக அணுகவும். தொகுக்கப்பட்ட தரவுத்தொகுப்பு சிறியது மற்றும் விளக்க நோக்கத்திற்கானது மட்டுமே. எனவே, summary.txt-இல் அச்சிடப்பட்டுள்ள Sharpe ratio மற்றும் maximum drawdown ஆகியவை ஒரு மாதிரி கோப்பை மட்டுமே விவரிக்கின்றன. அவை ஒரு உத்திக்கான ஆதாரங்கள் அல்ல; அவற்றை முடிவுகளாகக் கருதுவது நீங்கள் செய்யும் முதல் தவறாகும்.

இந்த இயக்கம் எதை உறுதிப்படுத்துகிறது என்பது முக்கியமானது: நிறுவல் சரியாக வேலை செய்கிறது, மேலும் சிக்னல் முதல் இலக்கு எடைகள் (target weights) மற்றும் மறுசீரமைக்கப்பட்ட போர்ட்ஃபோலியோ மதிப்பு வரை முழு என்ஜின் செயல்பாடும், எந்தவொரு நற்சான்றிதழும் (credential) இன்றி உங்கள் கணினியில் அதன் கலைப்பொருட்களை (artifacts) உருவாக்குகிறது. உண்மையான வரலாற்றுத் தரவுகளில் backtest செய்ய, திட்டத்தின் சொந்த தரவுச் சேவைக்கான நற்சான்றிதழ் பாதை உள்ளது. அந்தப் பாதை ஆவணப்படுத்தப்பட்டுள்ளது, மேலும் இந்த விளக்கவுரை இத்துடன் முடிகிறது; யாருடைய உதவியும் தேவையில்லாத பகுதி வரை மட்டுமே இது விவரிக்கப்பட்டுள்ளது.

ஒரு in-sample equity curve எதைச் சொல்லாது

இந்த மாதிரி ஓட்டம் ஒரு equity curve-ஐ மட்டுமே காட்டுகிறது. ஒரு டெமோ கோப்பிற்குப் பதிலாக உண்மையான சந்தை தரவுகளில் அளவிடப்பட்டபோது, அந்த curve-ஆல் எதைச் செய்ய முடியாது என்பதை இங்கே காணலாம்.

கீழே உள்ள பேனல், உதாரண உத்தியில் பயன்படுத்தப்பட்ட அதே கருத்தை (20-session moving average, 50-session moving average-ஐக் கடப்பது) SPY-க்குச் செயல்படுத்தி, 2017 முதல் 2025 வரையிலான ஒவ்வொரு காலண்டர் ஆண்டையும் தனித்தனியாகப் பட்டியலிடுகிறது. ஒவ்வொரு session-லும் நிலை (position), முந்தைய session-ன் முடிவிலேயே தீர்மானிக்கப்படுகிறது; எனவே, இந்த விதி இன்னும் கிடைக்காத ஒரு எண்ணை வைத்து ஒருபோதும் வர்த்தகம் செய்வதில்லை.

வினவவும்SPY-இன் 20/50 நகரும் சராசரி குறுக்குவெட்டு (Moving-average crossover), ஆண்டு வாரியாக, முதலீட்டுடன் ஒப்பீடு
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
    SELECT
        toDate(toTimeZone(window_start, 'America/New_York')) AS d,
        toFloat64(argMax(close, window_start))               AS px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= '2016-01-01 00:00:00'
      AND window_start <  '2026-01-01 05:00:00'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
    GROUP BY d
),
averaged AS
(
    SELECT
        d,
        px,
        avg(px) OVER (ORDER BY d ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS fast_ma,
        avg(px) OVER (ORDER BY d ROWS BETWEEN 49 PRECEDING AND CURRENT ROW) AS slow_ma,
        row_number() OVER (ORDER BY d)                                      AS session_no
    FROM daily
),
positioned AS
(
    SELECT
        d,
        px,
        if(session_no >= 50 AND fast_ma > slow_ma, 1, 0) AS long_today,
        lagInFrame(if(session_no >= 50 AND fast_ma > slow_ma, 1, 0), 1)
            OVER (ORDER BY d ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS long_prior,
        lagInFrame(px, 1)
            OVER (ORDER BY d ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS px_prior
    FROM averaged
)
SELECT
    toYear(d)                                                                   AS year,
    round((exp(sum(log(if(long_prior = 1, px / px_prior, 1.0)))) - 1) * 100, 1) AS rule_pct,
    round((exp(sum(log(px / px_prior))) - 1) * 100, 1)                          AS hold_pct,
    countIf(long_today != long_prior)                                           AS crossover_count
FROM positioned
WHERE px_prior > 0
  AND toYear(d) >= 2017
GROUP BY year
ORDER BY year
Run this yourself

மாற்றமில்லாத ஒரு விதி, 9 தனித்தனி முறைகள் அளவிடப்படுகிறது. மற்ற எதையும் படிப்பதற்கு முன், இரண்டு சதவீத நெடுவரிசைகளை (percent columns) கீழே வாசிக்கவும். 2017-ல், அந்த விதி ஆண்டை 16% என்ற அளவில் முடித்தது, அதே காலகட்டத்தில் SPY-ஐ வைத்திருந்ததற்கான அளவு 19.4% ஆகும். 2025-ல், அதே இரண்டு நெடுவரிசைகளும் 10.4% மற்றும் 16.4% என்று காட்டுகின்றன. இரண்டு வரிசைகளிலும் குறியீடு (code) ஒரே மாதிரியானது. கால இடைவெளி (window) மட்டுமே மாறியுள்ளது.

Crossover நெடுவரிசை, அடிப்படை ஆதாரங்கள் எவ்வளவு குறைவாக உள்ளன என்பதைக் காட்டுகிறது. 2025-ல் 4 நிலை மாற்றங்கள் என்பது, ஒரு முழு ஆண்டு equity curve-ம் ஒரு சில முடிவுகளின் மீது மட்டுமே தங்கியுள்ளது என்பதைக் குறிக்கிறது. ஒரு முடிவை உறுதிப்படுத்த இது மிகச்சிறிய மாதிரியாகும்.

மற்ற பங்குகளில் இதே விதி ஒரே மாதிரியாகச் செயல்படுகிறதா?

கால அளவை மாற்றுவது ஒரு குறிப்பிட்ட வளைவை (curve) ஆய்வு செய்வதற்கான ஒரு வழியாகும். முதலீட்டுத் தொகுப்பை (universe) மாற்றுவது மற்றொரு வழியாகும். கீழே உள்ள அட்டவணை, அளவுருக்களை (parameters) மாற்றாமல், 2021 முதல் 2025 வரையிலான ஐந்து காலண்டர் ஆண்டுகளில், அதிக வர்த்தக அளவு கொண்ட ஐந்து பங்குகளில் இதே விதியைப் பயன்படுத்துகிறது.

வினவவும்ஐந்து முக்கிய பங்குகளில் 2021 முதல் 2025 வரை அதே 20/50 விதி
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
    SELECT
        ticker,
        toDate(toTimeZone(window_start, 'America/New_York')) AS d,
        toFloat64(argMax(close, window_start))               AS px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker IN ('SPY', 'QQQ', 'AAPL', 'MSFT', 'KO')
      AND window_start >= '2020-07-01 00:00:00'
      AND window_start <  '2026-01-01 05:00:00'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
    GROUP BY ticker, d
),
averaged AS
(
    SELECT
        ticker,
        d,
        px,
        avg(px) OVER (PARTITION BY ticker ORDER BY d ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS fast_ma,
        avg(px) OVER (PARTITION BY ticker ORDER BY d ROWS BETWEEN 49 PRECEDING AND CURRENT ROW) AS slow_ma,
        row_number() OVER (PARTITION BY ticker ORDER BY d)                                      AS session_no
    FROM daily
),
positioned AS
(
    SELECT
        ticker,
        d,
        px,
        lagInFrame(if(session_no >= 50 AND fast_ma > slow_ma, 1, 0), 1)
            OVER (PARTITION BY ticker ORDER BY d ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS long_prior,
        lagInFrame(px, 1)
            OVER (PARTITION BY ticker ORDER BY d ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS px_prior
    FROM averaged
)
SELECT
    ticker                                                                      AS symbol,
    round((exp(sum(log(if(long_prior = 1, px / px_prior, 1.0)))) - 1) * 100, 1) AS rule_pct,
    round((exp(sum(log(px / px_prior))) - 1) * 100, 1)                          AS hold_pct,
    round(avg(long_prior) * 100, 0)                                             AS days_long_pct
FROM positioned
WHERE px_prior > 0
  AND d >= toDate('2021-01-01')
GROUP BY symbol
ORDER BY rule_pct DESC
Run this yourself

QQQ அட்டவணையின் மேல்பகுதியில் 40.2% என்ற இடத்தில் உள்ளது, மற்றும் கீழ் வரிசையான KO, 3.8% என்ற இடத்தில் உள்ளது. days_long_pct நெடுவரிசை, ஒவ்வொரு பதிப்பும் அந்த காலக்கட்டத்தில் எவ்வளவு நேரம் பங்குகளைத் தன்வசம் வைத்திருந்தது என்பதைக் காட்டுகிறது; மேல் வரிசைக்கு இது 67% ஆகும். ஒரே அளவுரு தொகுப்பு, ஐந்து வெவ்வேறு முதலீட்டுத் தொகுப்புகள், மற்றும் முடிவுகளைப் பார்த்த பிறகு வெற்றியாளரைத் தேர்ந்தெடுப்பது, நீங்கள் இன்னும் செய்யாத வர்த்தகத்தைப் பற்றி எதையும் கூறாது என்ற அளவுக்கு இதில் பரந்த இடைவெளி உள்ளது.

இவை எதுவும் crossover வர்த்தகம் செய்வதற்கான பரிந்துரை அல்ல. Crossover என்பது backtest-ஐ அளவிடுவதற்கான ஒரு கருவி மட்டுமே, மேலும் நாம் அளவிடுவது அந்த backtest-ஐத்தான்.

எடைகள் சார்ந்த பின்னோக்கிய சோதனையில் (backtest) 'look-ahead bias' எவ்வாறு நுழைகிறது

எடைகளை அடிப்படையாகக் கொண்ட ஒரு இயந்திரம், ஒரு சிக்னலை இலக்கு எடைகளாக (target weights) மாற்றுகிறது, அந்த எடைகளின் அடிப்படையில் வர்த்தகங்களைச் (fills) உருவகப்படுத்துகிறது, பின்னர் விளைந்த நிலைகளிலிருந்து போர்ட்ஃபோலியோ மதிப்பை மீண்டும் கட்டமைக்கிறது. சிக்னலுக்கும் எடைக்கும் இடையிலான இணைப்பில் தான் பிழை மறைந்திருக்கிறது. இன்றைய எடை இன்றைய closing விலையிலிருந்து பெறப்பட்டு, அதே நாளில் வருமானத்தை ஈட்டினால், அந்தப் பின்னோக்கிய சோதனை, ஆர்டர் இடப்பட்டபோது இல்லாத தகவலைப் பயன்படுத்தி வர்த்தகம் செய்ததாகிறது. இதுவே look-ahead bias ஆகும், இது எந்தப் பிழையையும் காட்டாது. இது எல்லாவற்றையும் மிகச் சிறப்பாக இருப்பது போலக் காட்டும்.

கீழே உள்ள பேனல், ஒரே SPY வரலாற்றின் மீது ஒரு விதியின் இரண்டு பதிப்புகளையும் இயக்குகிறது.

வினவவும்அதே விதி, முந்தைய அமர்வு சிக்னல் மற்றும் தற்போதைய அமர்வு சிக்னல் ஒப்பீடு, SPY ஆண்டு வாரியாக
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
    SELECT
        toDate(toTimeZone(window_start, 'America/New_York')) AS d,
        toFloat64(argMax(close, window_start))               AS px
    FROM global_markets.delayed_stocks_minute_aggs
    WHERE ticker = 'SPY'
      AND window_start >= '2016-01-01 00:00:00'
      AND window_start <  '2026-01-01 05:00:00'
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570
      AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
           + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960
    GROUP BY d
),
averaged AS
(
    SELECT
        d,
        px,
        avg(px) OVER (ORDER BY d ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS fast_ma,
        avg(px) OVER (ORDER BY d ROWS BETWEEN 49 PRECEDING AND CURRENT ROW) AS slow_ma,
        row_number() OVER (ORDER BY d)                                      AS session_no
    FROM daily
),
positioned AS
(
    SELECT
        d,
        px,
        if(session_no >= 50 AND fast_ma > slow_ma, 1, 0) AS long_today,
        lagInFrame(if(session_no >= 50 AND fast_ma > slow_ma, 1, 0), 1)
            OVER (ORDER BY d ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS long_prior,
        lagInFrame(px, 1)
            OVER (ORDER BY d ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS px_prior
    FROM averaged
)
SELECT
    toYear(d)                                                                   AS year,
    round((exp(sum(log(if(long_prior = 1, px / px_prior, 1.0)))) - 1) * 100, 1) AS next_bar_pct,
    round((exp(sum(log(if(long_today = 1, px / px_prior, 1.0)))) - 1) * 100, 1) AS same_bar_pct,
    round(abs(exp(sum(log(if(long_today = 1, px / px_prior, 1.0))))
              - exp(sum(log(if(long_prior = 1, px / px_prior, 1.0))))) * 100, 1) AS gap_pp
FROM positioned
WHERE px_prior > 0
  AND toYear(d) >= 2017
GROUP BY year
ORDER BY year
Run this yourself

2017-இல், முந்தைய அமர்வு பதிப்பு 16%-ஐப் பதிவு செய்தது, அதேசமயம் அதே அமர்வு பதிப்பு 17.1%-ஐப் பதிவு செய்தது; இவை 1.1 சதவீதப் புள்ளிகள் வேறுபடுகின்றன. 2025-இல், இரண்டிற்கும் இடையிலான இடைவெளி 1.6 சதவீதப் புள்ளிகளாக இருந்தது. அமர்வு எங்கே முடிந்தது என்று முன்பே தெரியாத ஒரு இயந்திரத்தால் இந்த நெடுவரிசைகளில் ஒன்றை மட்டுமே உருவாக்க முடியும், அவற்றுக்கிடையேயான வேறுபாடு வெறும் கணக்கியல் மட்டுமே; இதற்குப் பின்னால் எந்த யோசனையோ, திறமையோ அல்லது வர்த்தகமோ இல்லை.

இந்த இயந்திரம் காலக்கெடு குறித்த கேள்வியில் தனது சொந்த நிலைப்பாட்டைத் தெரிவிக்கிறது, இது ஒரு வாக்குறுதியை விட அதிக மதிப்புடையது:

சந்தை தொடக்கத்தில் (open) வர்த்தகங்களைச் செய்யும்போது, வரம்பு-உணர்திறன் கொண்ட slippage முந்தைய முழுமையான பார் (bar) மற்றும் வால்யூம் திறனை மட்டுமே கவனிக்கிறது; இந்த இயந்திரம் அந்த நாளின் பிந்தைய high, low, close அல்லது முழு நாள் வால்யூமைப் பயன்படுத்துவதில்லை.
ஆதாரம்: quantjourney-bt README, பதிப்பு 0.12.4, வாசிக்கப்பட்டது 6 ஆகஸ்ட் 2026.

ஆவணப்படுத்தப்பட்ட ஒரு அனுமானத்தை நீங்கள் ஏற்கனவே நிறுவியுள்ள மூலத்துடன் சரிபார்க்க முடியும். ஆவணப்படுத்தப்படாத ஒன்று வெறும் ஊகம் மட்டுமே.

Walk-forward கூடுதல் ஏன் தேவைப்படுகிறது

WF01 முதல் WF05 வரையிலான walk-forward உதாரணங்கள், [wf] கூடுதல் அம்சம் மற்றும் அதன் Optuna சார்ந்த செயல்பாடுகளுடன் வருகின்றன. Walk-forward முறையில், வரலாற்றுத் தரவுகளின் ஒரு பகுதியில் அளவுருக்கள் (parameters) பொருத்தப்படுகின்றன, அதன் அடுத்த பகுதியில் அவை அளவிடப்படுகின்றன. பின்னர், இந்த ஜோடி முன்னோக்கி நகர்த்தப்பட்டு மீண்டும் அதே செயல்முறை செய்யப்படுகிறது. Rolling மற்றும் expanding வகைகளில், தரவு நகரும்போது பழைய தரவுகள் நீக்கப்படுகிறதா என்பதில் மட்டுமே வேறுபாடு உள்ளது. மற்றொரு உதாரணத்தில், ஒவ்வொரு எல்லையிலும் purge மற்றும் embargo சேர்க்கப்படுகிறது. இது தரவுத் தொகுப்பின் விளிம்பில் உள்ள அவதானிப்புகளை நீக்குகிறது; இதனால், ஒரு பகுதியில் பொருத்தப்பட்ட அளவுருக்கள், அது அளவிடப்படும் அடுத்த பகுதிக்குள் கசியாது.

இவை எதுவும் ஒரு பலவீனமான முதலீட்டு யோசனையைச் சிறந்ததாக மாற்றிவிடாது. இது ஒரு ஒற்றை எண்ணிற்குப் பதிலாக, நீங்கள் விவாதிக்கக்கூடிய ஒரு தரவுப் பரவலை (distribution) வழங்குகிறது; இதுவே இந்த மேம்பாட்டின் முக்கிய நோக்கமாகும். இதற்கு அடுத்த கட்டம் இன்னும் நேரடி முதலீடு அல்ல: உண்மையான பணத்திற்கு முன் பேப்பர் டிரேடிங் என்பது, ஒரு backtest-ஆல் கண்டறிய முடியாத அம்சங்களை அளவிடுகிறது. இதில், சிமுலேட்டர் கருதிய விலையில் உங்கள் ஆர்டர் நிறைவேற்றப்படுகிறதா என்பது முதல் விஷயமாகும். மேலும், டிரேடிங் பாட்களுக்கான சர்க்யூட் பிரேக்கர்கள் உங்கள் குறியீடு (code) செயல்படாத நாட்களில் என்ன செய்ய வேண்டும் என்பதை வரையறுக்கின்றன. இவற்றின் அடிப்படையிலான புள்ளிவிவரங்களுக்கு, எங்களது திறந்தநிலை குவாண்ட் டிரேடிங் புத்தகம் குறித்த குறிப்புகள் இன்னும் ஆழமான புரிதலை வழங்கும்.

அடிக்கடி கேட்கப்படும் கேள்விகள் (FAQ)

API key இல்லாமலேயே ஒரு உத்தியை (strategy) backtest செய்ய முடியுமா?

ஆம். quantjourney-bt, --sample-data flag-ன் கீழ் ஒரு மாதிரி தரவுத்தொகுப்பை (sample dataset) உள்ளடக்கியுள்ளது. அதன் உதாரண உத்திகள் எந்தவொரு கணக்கு அல்லது நற்சான்றிதழ்களும் (credentials) இன்றி அந்தத் தரவுத்தொகுப்பில் இயங்குகின்றன. இது ஒரு சிறிய மற்றும் விளக்க நோக்கிலான தரவுத்தொகுப்பு என்பதால், இதை ஒரு உத்தியின் செயல்திறனுக்கான ஆதாரமாகப் பார்க்காமல், நிறுவல் மற்றும் pipeline சரியாகச் செயல்படுகிறதா என்பதைச் சரிபார்க்கும் சோதனையாகக் கருதவும்.

Python backtesting தொகுப்பின் பதிப்பை (version) ஏன் நிலைநிறுத்த (pin) வேண்டும்?

0.x நிலையில் உள்ள ஒரு தொகுப்பு, அதன் சிறிய பதிப்புகளுக்கு (minor releases) இடையே எந்தவொரு இணக்கத்தன்மை உத்தரவாதத்தையும் (compatibility guarantee) வழங்குவதில்லை. இயல்புநிலை மாற்றங்கள் அல்லது பெயர் மாற்றப்பட்ட அளவீடுகள் (metrics) குறித்து எந்த முன்னறிவிப்பும் இருக்காது. pip install quantjourney-bt==0.12.4 மூலம் பதிப்பை நிலைநிறுத்தி, அந்தச் சூழலை (environment) ஒரு requirements கோப்பில் பதிவு செய்வதன் மூலம், இன்று நீங்கள் பெறும் முடிவை அடுத்த ஆண்டு அதே engine-ஐக் கொண்டு மீண்டும் உருவாக்க முடியும்.

quantjourney-bt எந்த உரிமத்தின் (licence) கீழ் வெளியிடப்பட்டுள்ளது?

Apache License 2.0. இது வணிக ரீதியான பயன்பாட்டிற்கும் மாற்றங்களுக்கும் அனுமதி அளிக்கிறது. மறுவிநியோகம் செய்யும் போது உரிமம் மற்றும் அறிவிப்பு கோப்புகளை வைத்திருக்க வேண்டும் என்று கோருகிறது, மேலும் பங்களிப்பாளர்களிடமிருந்து வெளிப்படையான காப்புரிமை மானியத்தையும் (patent grant) உள்ளடக்கியுள்ளது. பதிப்பு 0.12.4, ஜூலை 21, 2026 அன்று வெளியிடப்பட்டது மற்றும் இதற்கு Python 3.11 அல்லது அதற்குப் பிந்தைய பதிப்பு தேவை.

வலுவான backtest முடிவு என்பது அந்த உத்தி சிறப்பாகச் செயல்படும் என்று அர்த்தமா?

இல்லை. ஒரு backtest என்பது ஒரு குறிப்பிட்ட கால இடைவெளியில், ஒரு குறிப்பிட்ட தரவுத் தொகுப்பில் செய்யப்படும் ஒரே ஒரு அளவீடு மட்டுமே. மேலே உள்ள panels, ஒரே மாறாத விதி ஒரு ticker-ல் வெவ்வேறு வருடாந்திர புள்ளிவிவரங்களையும், ஐந்து வெவ்வேறு பங்குகளில் முற்றிலும் மாறுபட்ட முடிவுகளையும் தருவதைக் காட்டுகின்றன. இந்த இடைவெளியை வெளிப்படுத்தவே walk-forward validation மற்றும் out-of-sample testing போன்றவை உருவாக்கப்பட்டுள்ளன.

மேலே உள்ள panels எவ்வாறு கணக்கிடப்பட்டன

தினசரி முடிவுகள் (daily closes), ஒவ்வொரு தேதியிலும் நியூயார்க் நேரப்படி காலை 9:30 மணி முதல் மாலை 4:00 மணி வரை வழக்கமான வர்த்தக அமர்வின் கடைசி நிமிடத்தில் பதிவான விலையாகும். இது சந்தை பாதியிலேயே முடிவடையும் நாட்களை, அமர்வின் கால அளவை hardcode செய்யாமலேயே சரியாகக் கையாள உதவுகிறது. வேகமான சராசரி (fast average) 20 அமர்வுகளையும், மெதுவான சராசரி (slow average) 50 அமர்வுகளையும் உள்ளடக்கியது; இவை இரண்டும் simple moving averages ஆகும். ஒவ்வொரு தொடரின் முதல் 49 அமர்வுகள் warm-up காலமாகும், இதில் எந்த நிலையும் (position) எடுக்கப்படாது. வருடாந்திர புள்ளிவிவரங்கள், அந்த விதி long நிலையில் இருந்த அமர்வுகளின் close-to-close நகர்வுகளைக் கூட்டுத்தொகையாக்குகின்றன; ஒப்பீட்டிற்காக 'hold' நெடுவரிசை அதே ஆண்டில் உள்ள அனைத்து அமர்வுகளையும் கூட்டுத்தொகையாக்குகிறது. குறுக்குவெட்டு ஆய்வில் (cross-section) உள்ள ஐந்து பெயர்களும், அந்த கால இடைவெளிக்குள் எந்தப் பங்குப் பிரிப்பும் (split) இல்லாத தொடர்ச்சியான வரலாற்றைக் கொண்டவை என்பதால், இந்த விலை வரிசைக்கு எந்த மாற்றமும் (adjustment) தேவையில்லை. கால இடைவெளிகள் கடந்த காலத்தில் நிலையானவை என்பதால், இந்த panels ஒவ்வொரு முறை உருவாக்கும்போதும் ஒரே எண்களையே தருகின்றன.


இங்குள்ள ஒவ்வொரு panel-ம் அதன் அடியில் உள்ள துல்லியமான SQL-ஐக் கொண்டுள்ளது. இது இந்தப் பக்கத்தில் உள்ள எண்களை, நிலைநிறுத்தப்பட்ட (pinned) நிறுவல் போலவே மீண்டும் இயக்கக்கூடியதாக மாற்றுகிறது. நீங்கள் எந்தவொரு backtest குறியீட்டையும் எழுதும் முன்பே, உங்கள் சொந்த கால இடைவெளியில் ஒரு விதியை அளவிட விரும்பினால், Strasmore terminal-ல் அந்த வினாவை எளிய ஆங்கிலத்தில் கேட்கவும்.

#backtesting#python#open source#reproducibility#quantjourney