Backtest Confidence Bands உருவாக்குவது எப்படி?
ஒரு equity curve என்பது ஒரு மாதிரி மட்டுமே. Backtest Sharpe விகிதத்தில் பூஜ்ஜியத்தை உள்ளடக்கும் confidence interval-ஐ எவ்வாறு உருவாக்குவது மற்றும் வாசிப்பது என்பதை இங்கு காண்போம்.
0.88
ஒரு backtest confidence interval ஒரு கேள்வியை மட்டுமே எதிர்கொள்கிறது: ஒரு equity curve-ல் எவ்வளவு பங்கு அந்த உத்தியைச் சார்ந்தது, எவ்வளவு பங்கு அது இயங்கிய வரலாற்றுத் தரவைச் சார்ந்தது? ஒரு backtest-க்கு Bootstrapping செய்வதன் மூலம், வருவாய் வரிசையை (return series) பலமுறை மறுமாதிரி (resample) செய்து, ஒவ்வொரு முறையும் புள்ளிவிவரத்தைக் கணக்கிட்டு, அதன் percentiles-ஐப் பார்ப்பதன் மூலம் அந்த இடைவெளி (interval) உருவாக்கப்படுகிறது. ஒரு வருட கால தினசரி தரவுகளில் கணக்கிடப்பட்ட 1.4 Sharpe விகிதமானது, பூஜ்ஜியத்தை உள்ளடக்கும் அளவுக்கு அகலமான தொண்ணூற்று ஐந்து சதவீத இடைவெளியைக் கொண்டுள்ளது; இதற்கான காரணங்களை கீழே உள்ள panels விளக்குகின்றன.
ஏன் ஒரு ஈக்விட்டி கர்வ் என்பது ஒரு மாதிரி மட்டுமே
ஒரு பேக்டெஸ்ட் (backtest) ஒவ்வொரு புள்ளிவிவரத்திற்கும் ஒரு எண்ணை மட்டுமே வழங்குகிறது: ஒரு Sharpe ratio, ஒரு வருடாந்திர வருவாய், ஒரு மோசமான drawdown, ஒரு வெற்றி விகிதம். இவை எதுவும் அந்த உத்தியின் உண்மையான மதிப்பு அல்ல. ஒவ்வொன்றும் வர்த்தக நாட்களின் வரையறுக்கப்பட்ட கால அளவிலிருந்து கணக்கிடப்பட்ட மதிப்பீடு மட்டுமே. அதே கால அளவு கொண்ட வேறொரு காலகட்டத்தை எடுத்துக்கொண்டால், முடிவுகள் வேறாக இருந்திருக்கும்.
கீழே உள்ள அட்டவணை, உத்தியைப் பற்றிய கேள்வியை முழுமையாக நீக்கிவிட்டு, மிக எளிமையான நிலையை அளவிடுகிறது. இது SPY-ஐ ஒரு காலண்டர் ஆண்டுக்கு ஒருமுறை, close-to-close விலை வருவாயின் அடிப்படையில் வைத்திருப்பதை அளவிடுகிறது.
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
SELECT
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2011-12-01'
AND date < '2026-01-01'
)
SELECT
toString(toYear(date)) AS year,
count() AS obs_count,
round(avg(ret) * 252 * 100, 2) AS ann_return_pct,
round(stddevSamp(ret) * sqrt(252) * 100, 2) AS ann_vol_pct,
round(avg(ret) / stddevSamp(ret) * sqrt(252), 2) AS sharpe_ratio
FROM daily
WHERE date >= '2012-01-01'
AND ret IS NOT NULL
GROUP BY year
ORDER BY yearஒவ்வொரு வரிசையும் சுமார் 250 வர்த்தக அமர்வுகளை உள்ளடக்கியது, இது ஒரு நிலையான வர்த்தக ஆண்டிற்கு நெருக்கமானது. இந்த நிலையைப் பொறுத்தவரை, எந்த மாற்றமும் செய்யப்படவில்லை. 2012-இல் வருடாந்திர Sharpe ratio 1.06 ஆக இருந்தது; 2025-இல் அது 0.88 ஆக இருந்தது, வரைபடத்தில் 14 ஆண்டுகள் காட்டப்பட்டுள்ளன. ஒரு பரந்த குறியீட்டை (broad index) ஓராண்டு வைத்திருப்பது, பெரும்பாலான வாசகர்கள் இரைச்சல் (noise) என்று கருதுவதை விட அதிகமான மாற்றத்தை அந்த முக்கிய எண்ணில் ஏற்படுத்துகிறது. அதே கால அளவு கொண்ட ஒரு உத்தியின் பேக்டெஸ்ட், குறைந்தபட்சம் அந்த அளவிற்காவது மாற்றத்தைப் பெறும். இந்த நெடுவரிசைக்கு பின்னால் உள்ள வருடாந்திர முறை (annualization convention) நமது Sharpe ratio வழிகாட்டி-யிலும், கால வருவாய் இயக்கவியல் (period-return mechanics) மாதாந்திர வருவாய் எவ்வாறு அளவிடப்படுகிறது என்பதிலும் உள்ளது.
Backtest Sharpe-ஐச் சுற்றியுள்ள வரம்பு எவ்வளவு அகலமானது?
Sharpe மதிப்பீட்டின் standard error, தரவுப் புள்ளிகளின் எண்ணிக்கையின் வர்க்க மூலத்திற்கு (square root) ஏற்ப குறைகிறது. அந்தச் சூத்திரத்தைச் சார்ந்திருப்பதற்குப் பதிலாக, spread-ஐ நேரடியாக அளவிடுங்கள். இருபது ஆண்டுகால வர்த்தக அமர்வுகளை ஒரே மாதிரியான நீளம் கொண்ட, ஒன்றின் மேல் ஒன்று மேற்படியாத (non-overlapping) கால இடைவெளிகளாகப் பிரித்து, ஒவ்வொரு இடைவெளியிலும் annualized Sharpe-ஐக் கணக்கிடுங்கள். அந்த எண்கள் எவ்வளவு தூரம் விலகி இருக்கின்றன என்பதைப் பாருங்கள்.
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
SELECT
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2005-12-01'
AND date < '2026-01-01'
),
indexed AS
(
SELECT
ret,
row_number() OVER (ORDER BY date) AS i
FROM daily
WHERE date >= '2006-01-01'
AND ret IS NOT NULL
),
blocks AS
(
SELECT
w,
intDiv(i, w) AS blk,
count() AS n,
avg(ret) / nullIf(stddevSamp(ret), 0) * sqrt(252) AS sharpe
FROM indexed
CROSS JOIN (SELECT arrayJoin([21, 63, 126, 252, 504]) AS w) AS ws
GROUP BY w, blk
HAVING n = w
)
SELECT
concat(toString(w), ' sessions') AS horizon,
count() AS block_count,
round(quantileDeterministic(0.05)(sharpe, blk), 2) AS sharpe_p05,
round(quantileDeterministic(0.50)(sharpe, blk), 2) AS sharpe_p50,
round(quantileDeterministic(0.95)(sharpe, blk), 2) AS sharpe_p95,
round(quantileDeterministic(0.95)(sharpe, blk)
- quantileDeterministic(0.05)(sharpe, blk), 2) AS sharpe_band_width
FROM blocks
WHERE sharpe IS NOT NULL
GROUP BY w
ORDER BY wஒவ்வொரு கால இடைவெளிக்கும் 21 sessions என்ற அளவில், அளவிடப்பட்ட Sharpe-ன் ஐந்தாவது முதல் தொண்ணூற்றைந்தாவது percentile வரை -3.37 முதல் 6.97 வரை அமைகிறது; இது 238 கால இடைவெளிகளில் 10.34 Sharpe புள்ளிகள் கொண்ட spread ஆகும். ஒவ்வொரு கால இடைவெளியையும் 504 sessions என நீட்டித்தால், spread 1.67 புள்ளிகளாகக் குறைகிறது; இது இப்போது வெறும் 8 கால இடைவெளிகளில் மட்டுமே அளவிடப்படுகிறது. ஒரே நேரத்தில் இரண்டு விஷயங்கள் நடக்கின்றன. மாதிரி அளவு (sample size) அதிகரிக்கும்போது மதிப்பீடு துல்லியமாகிறது, அதே சமயம் வரலாறு வழங்கக்கூடிய சுதந்திரமான மாதிரிகளின் எண்ணிக்கை குறைகிறது. இந்த முரண்பாடே முழுப் பொருளும் ஆகும்.
Backtest confidence interval-ஐ எவ்வாறு உருவாக்குவது (Bootstrap)
இதற்கான வழிமுறை முழுமையாக எழுதுவதற்கு எளிமையானது.
- உத்தியின் (strategy) நடைமுறைப்படுத்தப்பட்ட வருவாய் வரிசையிலிருந்து தொடங்கவும்; ஒவ்வொரு காலத்திற்கும் ஒரு மதிப்பு வீதம், மொத்தம் N மதிப்புகள் இருக்க வேண்டும்.
- அந்தப் பட்டியலிலிருந்து N வருவாய்களைத் தற்செயலாகத் தேர்ந்தெடுக்கவும் (with replacement). இதில் சில மதிப்புகள் இருமுறை வரலாம், சில வராமலும் போகலாம்.
- மறுமாதிரி (resample) செய்யப்பட்ட தரவுகளுக்குப் புள்ளிவிவரத்தைக் கணக்கிடவும்.
- இதைச் சில ஆயிரம் முறை மீண்டும் செய்து, ஒவ்வொரு மதிப்பையும் சேமிக்கவும்.
- சேமிக்கப்பட்ட மதிப்புகளை வரிசைப்படுத்தி, தொண்ணூற்று ஐந்து சதவீத இடைவெளிக்கு (95 percent interval), இரண்டரை (2.5) மற்றும் தொண்ணூற்று ஏழரை (97.5) சதவீத புள்ளிகளை (percentiles) எடுக்கவும்.
இரண்டாவது படிக்கு முன்பாக தற்செயல் எண் உருவாக்கும் கருவிக்கு (random number generator) ஒரு தொடக்க எண்ணை (seed) வழங்கவும்; வெளியிடப்பட்ட இடைவெளியுடன் அந்தத் தொடக்க எண்ணையும் குறிப்பிடவும். ஒரு bootstrap என்பது Monte Carlo மதிப்பீடு ஆகும்: தொடக்க எண் வழங்கப்படாத இரண்டு சோதனைகள் கடைசி இலக்கங்களில் மாறுபடும். உங்கள் இடைவெளியை மீண்டும் சரிபார்க்க முடியாத ஒரு ஆய்வாளரால் அதை உறுதிப்படுத்த முடியாது. மீண்டும் உருவாக்கக்கூடிய backtest அமைப்பு என்பதில் விவரிக்கப்பட்டுள்ள அதே ஒழுக்கம் இதற்கும் பொருந்தும்.
சராசரி வருவாய் (mean return) மற்றும் Sharpe விகிதம் ஆகியவை இரண்டாவது படியில் சரியாகச் செயல்படும், ஏனெனில் இவை வருவாய் பட்டியலை ஒரு தொகுப்பாகவே கருதுகின்றன. ஆனால் அதிகபட்ச சரிவு (maximum drawdown) அவ்வாறு செயல்படாது. சரிவு என்பது வரிசைப்படுத்தப்பட்ட பாதையை அடிப்படையாகக் கொண்டது. வருவாய்களை மறுவரிசைப்படுத்தும் ஒரு மறுமாதிரி, உண்மையான வர்த்தக வரிசையில் இல்லாத ஒரு மோசமான சரிவை உருவாக்கலாம். இருப்பினும், இதைச் செய்வது பயனுள்ளது; ஆனால் அதன் வெளியீட்டைச் சரியாகக் குறிப்பிட வேண்டும்: இது அடுத்த காலத்திற்கான கணிப்பு அல்ல, மாறாக மாற்றியமைக்கப்பட்ட வரலாறுகளின் அடிப்படையில் சரிவு எவ்வாறு அமையும் என்பதற்கான பரவல் (distribution) ஆகும். இதற்கான வரையறை maximum drawdown என்பதில் உள்ளது.
சந்தை வருவாய்களுக்கு IID பூட்ஸ்ட்ராப் (bootstrap) ஏன் தவறானது
படி இரண்டு, ஒவ்வொரு வருவாயும் தனித்தன்மை வாய்ந்தது மற்றும் ஒரே மாதிரியாக விநியோகிக்கப்பட்டது (IID assumption) என்று கருதுகிறது. தினசரி வருவாய்கள் இந்த அனுமானத்தை உடைக்கின்றன, இது இடைவெளி அகலத்தை (interval width) மாற்றுகிறது. குறியீடு செய்யப்பட்ட வருவாய்கள் (signed returns) ஒரு நாள் மட்டுமே நீடிக்கும் மிகக் குறைந்த நினைவகத்தையே கொண்டுள்ளன. ஆனால் அவற்றின் அளவுகள் தொகுப்புகளாக அமைகின்றன: பெரிய நகர்வுகள் பெரிய நகர்வுகளுக்கு அருகிலும், அமைதியான நாட்கள் தொடர்ச்சியாகவும் வருகின்றன.
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
SELECT
ticker,
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('SPY', 'MSFT', 'KO', 'XOM', 'JNJ', 'PG')
AND date >= '2015-11-01'
AND date < '2026-01-01'
),
lagged AS
(
SELECT
ticker,
date,
ret,
lagInFrame(ret, 1) OVER (PARTITION BY ticker ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS ret_prev
FROM daily
WHERE ret IS NOT NULL
AND abs(ret) < 0.35
)
SELECT
ticker,
count() AS obs_count,
round(corr(ret, ret_prev), 3) AS return_autocorr,
round(corr(abs(ret), abs(ret_prev)), 3) AS abs_return_autocorr
FROM lagged
WHERE date >= '2016-01-01'
AND ret_prev IS NOT NULL
GROUP BY ticker
ORDER BY abs_return_autocorr DESCSPY-க்கு, 2514 அமர்வுகளில் அளவிடப்பட்ட தினசரி முழுமையான வருவாய்களின் (absolute daily returns) லேக்-ஒன் ஆட்டோகோரிலேஷன் (lag-one autocorrelation) 0.366 ஆக உள்ளது, அதே நாட்களில் குறியீடு செய்யப்பட்ட வருவாய்களுக்கு இது -0.133 ஆக உள்ளது. வரைபடத்தில் உள்ள எந்தவொரு பங்கின் இரண்டு பட்டைகளையும் ஒப்பிட்டுப் பாருங்கள். வருவாய் வரிசையை மாற்றி அமைப்பது (shuffling) அந்தத் தொகுப்புத்தன்மையை அழித்துவிடுகிறது. இந்தத் தரவுகளில் இயக்கப்படும் ஒரு IID பூட்ஸ்ட்ராப், மாதிரி ஆதரிக்கும் இடைவெளியை விட குறுகிய இடைவெளியையே காட்டுகிறது. இந்தத் தவறு முதலீட்டாளருக்கு மிகவும் பாதகமான திசையில் நிகழ்கிறது: இது அந்த உத்தியின் செயல்திறனை மிகைப்படுத்திக் காட்டுகிறது.
நகரும் தொகுதி பூட்ஸ்ட்ராப் (moving block bootstrap) மற்றும் தொகுதி நீளத்தைத் தேர்ந்தெடுத்தல்
ஒற்றை வருவாய்களுக்குப் பதிலாக, தொடர்ச்சியான தொகுதிகளை (contiguous blocks) மறுமாதிரி (resample) செய்வதே இதற்கான தீர்வாகும். ஒரு தொகுதி நீளம் L-ஐத் தேர்ந்தெடுத்து, L தொடர்ச்சியான வருவாய்களைக் கொண்ட தொகுதிகளைத் தற்செயலாகவும், மீண்டும் பயன்படுத்தக்கூடிய வகையிலும் (with replacement) எடுத்து, அவற்றை ஒன்றன் பின் ஒன்றாக இணைத்து N நீளம் கொண்ட செயற்கைத் தொடரை உருவாக்க வேண்டும். ஒரு தொகுதிக்குள் இருக்கும் சார்புத்தன்மை (dependence) அப்படியே இருக்கும்: அந்த வருவாய்கள் அவற்றின் அசல் வரிசையிலேயே இருக்கும். தொகுதிகளுக்கு இடையிலான இணைப்புகள் மட்டுமே செயற்கையானவை.
தொகுதி நீளம் இரண்டு பிழைகளுக்கு இடையே சமநிலையை ஏற்படுத்துகிறது; எந்த அமைப்பும் இரண்டிலிருந்தும் தப்ப முடியாது. குறுகிய தொகுதிகள் IID பூட்ஸ்ட்ராப் போலச் செயல்பட்டு, இடைவெளியைக் குறைவாகக் காட்டுகின்றன; இது ஒரு சார்பு (bias) ஆகும். நீண்ட தொகுதிகள் அதிக சார்புத்தன்மையை நிலைநிறுத்துகின்றன, ஆனால் எடுப்பதற்குத் தனித்துவமான தொகுதிகள் குறைவாகவே இருக்கும். இதனால் ஒவ்வொரு மறுமாதிரியும் ஒரே வரலாற்றின் பெரிய பகுதிகளை மீண்டும் மீண்டும் பயன்படுத்துகிறது, மேலும் இடைவெளியே இரைச்சலாக (noisy) மாறுகிறது; இது மாறுபாடு (variance) ஆகும். வெளியிடப்பட்ட பொதுவான விதிகள், நீளத்தை N-ன் மூன்றில் ஒரு பங்கு அடுக்குக்கு (one-third power) ஏற்ப மாற்றுகின்றன. இவற்றைத் தொடக்கப் புள்ளிகளாகக் கருதுங்கள்.
மாறுபாடு கால எல்லைக்கு ஏற்ப எவ்வாறு மாறுகிறது என்பதைச் சரிபார்ப்பது ஒரு எளிமையான கண்டறியும் முறையாகும். சார்பின்மை நிலையில், k-நாள் வருவாய் கூட்டுத்தொகையின் மாறுபாடு, ஒரு நாள் மாறுபாட்டைப் போல k மடங்கு இருக்கும், மேலும் இரண்டிற்கும் இடையிலான விகிதம் 1 ஆக இருக்கும்.
ஒவ்வொரு எண்ணின் பின்னணியில் உள்ள துல்லியமான SQL
WITH daily AS
(
SELECT
date,
toFloat64(close) / nullIf(lagInFrame(toFloat64(close), 1)
OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW), 0) - 1 AS ret
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2005-12-01'
AND date < '2026-01-01'
),
indexed AS
(
SELECT
ret,
row_number() OVER (ORDER BY date) AS i
FROM daily
WHERE date >= '2006-01-01'
AND ret IS NOT NULL
),
base AS
(
SELECT varSamp(ret) AS var_1d FROM indexed
),
blocks AS
(
SELECT
k,
intDiv(i, k) AS blk,
count() AS n,
sum(ret) AS block_ret
FROM indexed
CROSS JOIN (SELECT arrayJoin([2, 3, 5, 10, 21, 42, 63]) AS k) AS ks
GROUP BY k, blk
HAVING n = k
)
SELECT
concat(toString(k), ' sessions') AS block_length,
count() AS block_count,
round(varSamp(block_ret) / (k * any(var_1d)), 3) AS variance_ratio
FROM blocks
CROSS JOIN base
GROUP BY k
ORDER BY k2 sessions-இல் இந்த விகிதம் 0.844 ஆக அளவிடப்பட்டது; 63 sessions-இல் இது 0.584 ஆக இருந்தது, இது 78 ஒன்றுடன் ஒன்று சேராத தொகுதிகளில் கணக்கிடப்பட்டது. 1-க்கு அருகில் உள்ள மதிப்புகள், அந்த கால எல்லையில் சார்பற்ற தரவுகளைப் போலவே கூட்டுத்தொகை அளவிடப்படுவதைக் குறிக்கின்றன. 1-லிருந்து விலகி இருக்கும் மதிப்புகள், சார்புத்தன்மை இன்னும் செயல்படும் கால எல்லைகளைக் குறிக்கின்றன; அந்த வரம்பைத்தான் ஒரு தொகுதி நீளம் ஈடுசெய்ய வேண்டும். அதைச் சரிசெய்யும் மிகக் குறுகிய தொகுதியைத் தேர்ந்தெடுத்து, அதன் பிறகு தொகுதி எண்ணிக்கை எவ்வளவு குறைந்துள்ளது என்பதைக் கவனியுங்கள்.
Bucketed resampling மற்றும் ஒவ்வொரு இடைவெளிக்கும் அருகிலுள்ள எண்ணிக்கை
Volatility regime அல்லது காலண்டர் மாதத்தின் அடிப்படையில் buckets-க்குள் resampling செய்வது, அந்த கேள்வியை சுவாரஸ்யமாக்கிய நிபந்தனைகளை அப்படியே தக்கவைக்கிறது. ஒரு உத்தி (strategy) அதிக volatility உள்ள காலங்களில் அதன் Sharpe விகிதத்தைப் பெறுகிறது என்று கூறப்பட்டால், அதிக volatility உள்ள நாட்களை மட்டும் கொண்டு உருவாக்கப்பட்ட ஒரு இடைவெளிதான் அந்த கூற்றைச் சோதிக்கும். இதற்கான விலை கணித ரீதியானது. இருநூற்று ஐம்பது அவதானிப்புகளை (observations) நான்கு buckets-ஆகப் பிரிக்கும்போது, ஒவ்வொரு bucket-லும் சுமார் அறுபது அவதானிப்புகள் மட்டுமே இருக்கும். அறுபது அவதானிப்புகளைக் கொண்ட ஒரு bootstrap, முழு மாதிரியைக் கொண்ட பதிப்பை விட இரண்டு மடங்கு அகலமான இடைவெளியையே தரும்.
எனவே, ஒவ்வொரு முறையும் ஒவ்வொரு இடைவெளிக்கும் அருகில் bucket எண்ணிக்கையைக் குறிப்பிடுங்கள். மேலே உள்ள பேனல்களில் உள்ள block_count நெடுவரிசை அந்தப் பழக்கத்தை வெளிப்படுத்துகிறது: ஒன்பது விண்டோக்களிலிருந்து பெறப்பட்ட ஐந்தாவது percentile மதிப்பும், இருநூறு விண்டோக்களிலிருந்து பெறப்பட்ட மதிப்பும் வெவ்வேறானவை; அவை இரண்டுமே இரண்டு தசம இடங்களுக்கு அச்சிடப்பட்டாலும், அவற்றின் நம்பகத்தன்மை மாறுபடும்.
பூட்ஸ்ட்ராப் (bootstrap) சரிசெய்ய முடியாதவை
ஒரு பூட்ஸ்ட்ராப் என்பது உங்களிடம் உள்ள தரவுகளிலிருந்து கணக்கிடப்பட்ட புள்ளிவிவரத்தில் உள்ள மாதிரி இரைச்சலை (sampling noise) மட்டுமே அளவிடுகிறது. அந்தத் தரவுகள் உண்மையில் வர்த்தகம் செய்யக்கூடியவைதானா என்பது குறித்து அது எந்தத் தகவலையும் தருவதில்லை.
look-ahead bias பாதிப்புள்ள ஒரு பேக்டெஸ்ட் (backtest), வர்த்தகம் செய்ய முடியாத வருவாய் வரிசையை உருவாக்குகிறது. அதன் பூட்ஸ்ட்ராப், ஒரு கற்பனையான விஷயத்தைச் சுற்றி இறுக்கமான, நம்பிக்கையான வரம்புகளை மட்டுமே வழங்குகிறது. இன்றைய குறியீட்டு உறுப்பினர்களைக் கொண்டு உருவாக்கப்பட்ட ஒரு பிரபஞ்சம் (universe), survivorship bias-ஐக் கொண்டுள்ளது; அந்தப் பிரபஞ்சத்தின் ஒவ்வொரு மறுமாதிரியும் (resample) இதையே பெறுகிறது. மூன்றாவது குறைபாடு தேர்வு விளைவு (selection effect) ஆகும்: இருநூறு வகைகளை இயக்கி, அதில் சிறந்ததைத் தேர்ந்தெடுத்தால், அதன் பூட்ஸ்ட்ராப் இடைவெளி அந்த ஒரு வகையின் மாதிரி இரைச்சலை மட்டுமே விவரிக்கிறது; அதைத் தேர்ந்தெடுக்கப் பயன்படுத்தப்பட்ட மற்ற நூற்று தொண்ணூற்று ஒன்பது முயற்சிகளை அது புறக்கணிக்கிறது. நேர்மையான வரம்புகள் பயனுள்ளவை. ஆனால், அவை out-of-sample தரவுகளுக்கு மாற்றாகாது.
தரவு குறிப்புகள் மற்றும் முறை
- வருவாய்கள் தினசரி பார்களில் உள்ள close-to-close விலை வருவாய்கள் ஆகும். ஈவுத்தொகைகள் (dividends) இதில் சேர்க்கப்படவில்லை, இது ஒவ்வொரு வருவாய் மற்றும் Sharpe மதிப்பையும் ஈவுத்தொகை விளைச்சலுக்கு (dividend yield) ஏற்ப குறைத்துக் காட்டுகிறது. இந்த இடுகையில் விவாதிக்கப்படும் பரவல் (dispersion) இதைப் பாதிக்காது.
- விண்டோக்கள் மற்றும் பிளாக்குகள் ஒன்றுடன் ஒன்று சேராதவை (non-overlapping), எனவே ஒவ்வொரு அளவிடப்பட்ட புள்ளிவிவரமும் வரலாற்றின் தனித்தனி பகுதியைப் பயன்படுத்துகிறது. ஒன்றுடன் ஒன்று சேரும் விண்டோக்கள், மாதிரிகளின் எண்ணிக்கையைத் தவறாக உயர்த்திக் காட்டும்.
- குவாண்டைல்கள் (quantiles) ஒரு தீர்மானிக்கப்பட்ட மதிப்பீட்டாளரைப் பயன்படுத்துகின்றன, எனவே ஒரு பேனலை மீண்டும் இயக்கும்போது புதிய தோராயத்திற்குப் பதிலாக அதே சதவீதமே கிடைக்கும்.
- ஆட்டோகோரிலேஷன் (autocorrelation) பேனல், விண்டோவிற்குள் பங்குப் பிரிப்பு இல்லாத ஆறு பெரிய நிறுவனங்களைப் பயன்படுத்துகிறது. முப்பத்தைந்து சதவீதத்திற்கு மேல் நகர்வுள்ள எந்த நாளையும் இது நீக்குகிறது, இது விலை சரிசெய்தல் தொடர்பான சிக்கல்களைத் தவிர்க்கிறது.
அடிக்கடி கேட்கப்படும் கேள்விகள் (FAQ)
Backtest ஒன்றைப் பற்றி bootstrap confidence interval என்ன கூறுகிறது?
ஒரே செயல்முறை அதே கால அளவுகளில் மீண்டும் மாதிரி எடுக்கப்பட்டால், அந்த புள்ளிவிவரம் (statistic) எந்த வரம்பிற்குள் இருக்க வாய்ப்புள்ளது என்பதை இது காட்டுகிறது. 95 சதவீத இடைவெளியில் பூஜ்ஜியம் (zero) இருந்தால், அந்த உத்தியின் (strategy) செயல்திறனை, எந்தவிதமான கூடுதல் பலனும் இல்லாத நிலையிலிருந்து பிரித்தறிய அந்த மாதிரி அளவு போதாது என்று பொருள்.
எத்தனை bootstrap resamples போதுமானவை?
95 சதவீத இடைவெளிக்கு, சில ஆயிரம் resamples பொதுவாக நிலையான முடிவுகளைத் தரும். 10,000 என்பது பொதுவான இயல்புநிலை (default) மற்றும் இதற்கு அதிக செலவும் இல்லை. மிகக் குறைந்த அல்லது அதிகப்படியான tail quantiles-க்கு கூடுதல் தேவைப்படும்: 1,000 மாதிரிகளில் முதல் percentile-ஐக் கணக்கிட சுமார் பத்து மதிப்புகளே கிடைக்கும்.
Moving block bootstrap-க்கு என்ன block length பயன்படுத்த வேண்டும்?
இதற்கு உலகளவில் ஏற்றுக்கொள்ளப்பட்ட சரியான நீளம் என்று எதுவும் இல்லை. மாதிரி அளவின் (sample size) மூன்றில் ஒரு பங்கு (one-third power) என்ற அளவில் இதைக் கணக்கிடுவது ஒரு பொதுவான விதி. மாறுபாடு (variance) நேரியல் முறையில் (linearly) அதிகரிப்பது எங்கு நிற்கிறது என்பதைக் கண்டறிவது ஒரு நடைமுறைச் சரிபார்ப்பு; மேலே உள்ள variance ratio பேனல் இதை அளவிடுகிறது. நீங்கள் பயன்படுத்திய நீளத்தை இடைவெளியுடன் சேர்த்து வெளியிடுங்கள்.
Maximum drawdown-க்கு bootstrap பயன்படுத்த முடியுமா?
ஆம், ஆனால் வரிசைப்படுத்துவதில் ஒரு நிபந்தனை உள்ளது. Drawdown என்பது வருவாயின் வரிசையைச் (sequence of returns) சார்ந்தது. எனவே, தரவுகளைக் கலைத்து (shuffling) உருவாக்கப்படும் ஒரு resample, மறுவரிசைப்படுத்தப்பட்ட வரலாற்றின் drawdown-ஐயே காட்டும். Block bootstrap குறுகிய கால வரிசைகளை அப்படியே வைத்திருப்பதால், path statistics-க்கு இதுவே சிறந்த கருவியாகும்.
Overfitting-ஐ bootstrap சரிசெய்கிறதா?
இல்லை. இது ஒரு வருவாய் தொடருக்குள் (return series) உள்ள மாதிரி இரைச்சலை (sampling noise) மட்டுமே அளவிடுகிறது. Look-ahead bias மற்றும் பல மாறுபாடுகளைச் சோதிப்பதன் மூலம் ஏற்படும் selection effect ஆகியவற்றை இதால் கண்டறிய முடியாது.
இங்குள்ள ஒவ்வொரு பேனலும் அதை உருவாக்கிய SQL-ஐக் கொண்டுள்ளது. Ticker அல்லது window நீளத்தை மாற்றி, Strasmore terminal-ல் நீங்களே இயக்கிப் பாருங்கள்.