Equal Weight کب Optimization سے بہتر ہوتا ہے؟
مختصر sample میں equal weight، optimized position sizing سے بہتر رہتا ہے۔ Seeded Python simulation میں یہ فرق سامنے آتا اور sample بڑھنے پر ختم ہو جاتا ہے۔
جب sample اتنا مختصر ہو کہ متوقع returns کا قابلِ اعتماد اندازہ لگانا ممکن نہ رہے، تو equal weight عموماً optimized position sizing سے بہتر کارکردگی دکھاتا ہے۔ مختصر samples استثنا نہیں بلکہ معمول ہیں۔ Optimizer ایسی input پر درست arithmetic لاگو کرتا ہے جسے کوئی بھی قابلِ اعتماد طور پر measure نہیں کر پاتا۔ 1/N portfolio، یعنی equal weight، کسی چیز کا تخمینہ نہیں لگاتا۔ یہی وجہ ہے کہ خراب estimates کے باوجود یہ نسبتاً مضبوط رہتا ہے۔
کیا equal weight واقعی optimization سے بہتر کارکردگی دکھاتا ہے؟
ایک مخصوص شرط کے تحت، ہاں۔ اصطلاحات کو ایک ایک کرکے دیکھیں۔ Equal weight، جسے 1/N لکھا جاتا ہے، سرمایہ N positions میں برابر تقسیم کرتا ہے اور کسی بھی قسم کی پیش گوئی درکار نہیں ہوتی۔ Mean variance optimization ایسے weights نکالتا ہے جن سے estimated variance کی فی یونٹ بہترین متوقع return حاصل ہو۔ Kelly criterion ایسے weights نکالتا ہے جو طویل مدت میں compound growth کو زیادہ سے زیادہ بناتے ہیں؛ غیر متعلقہ assets میں اس کا جواب ہر asset کے متوقع excess return کو اس کے variance سے تقسیم کرنے کے تناسب کے برابر ہو جاتا ہے۔ ہماری Kelly criterion کے مطابق position sizing گائیڈ اس formula کی تفصیل بیان کرتی ہے۔
دونوں optimizers کو ایک ہی input درکار ہوتا ہے: ہر asset کے لیے متوقع return۔ یہی وہ مقدار ہے جس کا sample سب سے کم درست اندازہ لگاتا ہے۔ Volatility کا اندازہ مختصر window سے بھی قابلِ عمل precision کے ساتھ لگایا جا سکتا ہے۔ Mean کے معاملے میں ایسا نہیں ہوتا، اور دونوں کے درمیان فرق کسی بھی price history میں واضح نظر آتا ہے۔ ذیل کا panel چھ widely held names لیتا ہے، 2015 سے 2024 تک ہر calendar year کو الگ ناپتا ہے، اور بتاتا ہے کہ سب سے زیادہ اور سب سے کم yearly estimate ایک دوسرے سے کتنے فاصلے پر ہیں۔ یہ ہر name کے لیے دو بار کیا گیا ہے: ایک مرتبہ annualized average daily return کے لیے، اور ایک مرتبہ annualized volatility کے لیے۔
ہر عدد کے پیچھے موجود درست SQL
WITH prices AS
(
SELECT
ticker,
date,
toFloat64(max(close)) AS c
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO', 'JNJ')
AND date >= '2015-01-01'
AND date < '2025-01-01'
GROUP BY ticker, date
),
rets AS
(
SELECT
ticker,
date,
c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
FROM prices
),
yearly AS
(
SELECT
ticker,
toYear(date) AS yr,
avg(ret) * 252 * 100 AS mean_pct,
stddevPop(ret) * sqrt(252) * 100 AS vol_pct
FROM rets
WHERE isFinite(ret)
GROUP BY ticker, yr
HAVING count() >= 200
)
SELECT
ticker,
round(max(mean_pct) - min(mean_pct), 1) AS mean_estimate_range_pct,
round(max(vol_pct) - min(vol_pct), 1) AS vol_estimate_range_pct
FROM yearly
GROUP BY ticker
ORDER BY mean_estimate_range_pct DESCNVDA کے لیے ان دس برسوں میں yearly mean estimate کا پھیلاؤ 184.7 percentage points رہا، جبکہ اسی name کے volatility estimate میں range 28.6 points رہی۔ Panel میں سب سے زیادہ مستحکم name، KO، نے بھی اپنا yearly mean estimate 23.9 points کی حد میں تبدیل کیا۔ جو بھی scheme گزشتہ سال کے average return کو اس سال کے expected return کے طور پر optimizer کو دیتی ہے، وہ اسے اتنے زیادہ اتار چڑھاؤ والی عددی مقدار فراہم کر رہی ہے۔
متوقعہ return کا اندازہ لگانے کے لیے آپ کو کتنا طویل sample درکار ہے؟
Estimated mean return کا standard error، asset کی volatility کو sample length کے سالوں کے square root سے تقسیم کرنے کے برابر ہوتا ہے۔ یہاں پیمانہ سال ہیں، observations نہیں۔ ایک ہی بارہ ماہ کا data روزانہ کے بجائے hourly بنیاد پر لینے سے کوئی اضافی فائدہ نہیں ہوتا۔ اگر 20 فیصد volatility والے asset پر یہ formula لاگو کریں تو ایک سال کی history سے standard error سالانہ 20 percentage points بنتا ہے۔ چار سال میں یہ کم ہو کر 10 points رہ جاتا ہے۔ اسے ایک point تک لانے کے لیے، یعنی اس قدر precision حاصل کرنے کے لیے جو ایسے دو assets کی ranking سے پہلے درکار ہو جن کے حقیقی mean returns میں دو points کا فرق ہو، چار صدیوں کا data چاہیے۔
Volatility کا معاملہ مختلف ہے۔ اس کی precision calendar span کے بجائے observations کی تعداد کے ساتھ بہتر ہوتی ہے، اس لیے چند ماہ کا daily data بھی اسے چند points کے اندر لے آتا ہے۔ ذیل کا panel ایک index fund کے بیس سال کے daily returns کو ایک مقررہ length کے non-overlapping blocks میں تقسیم کرتا ہے، ہر block کے اندر دونوں estimates نکالتا ہے، اور دکھاتا ہے کہ یہ estimates ایک block سے دوسرے block تک کتنے پھیلتے ہیں۔
ہر عدد کے پیچھے موجود درست SQL
WITH prices AS
(
SELECT
date,
toFloat64(max(close)) AS c
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= '2005-01-01'
AND date < '2025-01-01'
GROUP BY date
),
rets AS
(
SELECT
date,
c / lagInFrame(c, 1) OVER (ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
FROM prices
),
numbered AS
(
SELECT
ret,
row_number() OVER (ORDER BY date ASC) AS i
FROM rets
WHERE isFinite(ret)
),
sweep AS
(
SELECT
arrayJoin([21, 63, 126, 252, 504]) AS n,
i,
ret
FROM numbered
),
blocks AS
(
SELECT
n,
intDiv(i - 1, n) AS blk,
avg(ret) * 252 * 100 AS mean_pct,
stddevPop(ret) * sqrt(252) * 100 AS vol_pct
FROM sweep
GROUP BY n, blk
HAVING count() = n
)
SELECT
concat(toString(n), ' sessions') AS sample_length,
round(stddevPop(mean_pct), 1) AS mean_estimate_spread_pct,
round(stddevPop(vol_pct), 1) AS vol_estimate_spread_pct,
count() AS window_count
FROM blocks
GROUP BY n
ORDER BY n ASC21 sessions کے blocks میں mean estimate 53.7 percentage points کے درمیان پھیلتا ہے، جبکہ انہی blocks پر ناپے گئے volatility estimate کے لیے یہ پھیلاؤ 10.9 points ہے۔ block کو 504 sessions تک بڑھانے پر mean کا پھیلاؤ کم ہو کر 10.6 points رہ جاتا ہے۔ یہ کمی square root کے تناسب سے ہوتی ہے: error کو ہر بار نصف کرنے کے لیے data کی مقدار چار گنا درکار ہوتی ہے۔
آپ خود چلانے کے لیے seeded simulation
ان میں سے کوئی بات یہ ثابت نہیں کرتی کہ estimation error اتنی بڑی ہے کہ برتری 1/N کو منتقل ہو جائے۔ یہ simulation ایسا ثابت کرتی ہے۔ اس کے لیے صرف Python install درکار ہے۔ Data files، downloads یا third-party packages کی ضرورت نہیں۔ یہ آپ کے منتخب کردہ parameters سے خود returns پیدا کرتی ہے، اس لیے حقیقی جواب معلوم ہوتا ہے اور دونوں allocations کو اس کے مقابلے میں جانچا جا سکتا ہے۔
- دو modules،
import randomاورimport statistics، کے علاوہfrom math import logimport کریں۔ اگلی سطر میںrandom.seed(20260816)کے ذریعے seed مقرر کریں۔ - پانچ assets متعین کریں جن کے true annual expected returns بالترتیب 5، 6، 7، 8 اور 9 فیصد ہوں۔ ہر asset کی true annual volatility 20 فیصد ہو اور assets باہمی طور پر uncorrelated ہوں۔
mu_d = mu_a / 252اورsd_d = sd_a / (252 ** 0.5)کے ذریعے انہیں daily step میں تبدیل کریں۔ [60, 125, 250, 500, 1000, 2500, 5000]کے sweep میں سے sample length T منتخب کریں۔random.gauss(mu_d, sd_d)کے ذریعے ہر asset کے لیے T daily returns پیدا کریں۔ یہی وہ مکمل history ہے جسے manager دیکھ سکتا ہے۔statistics.meanکے ذریعے ہر asset کا mean اورstatistics.stdevکے ذریعے اس کی volatility estimate کریں۔ Optimizer کے پاس یہی دو estimates ہوں گے۔- Equal-weight portfolio بنائیں اور پانچوں assets کو 0.2 وزن دیں۔ یہ estimates میں سے کسی کو استعمال نہیں کرتا۔
- Optimized portfolio بنائیں۔ ہر raw weight کو
mu_hat / (sd_hat ** 2)کے برابر مقرر کریں، پھر ہر weight کو تمام raw weights کے absolute values کے مجموعے سے تقسیم کریں۔ اس طرح دونوں portfolios کی gross exposure یکساں رہتی ہے۔ - True parameters سے ہر asset کے لیے 2520 daily returns کا ایک نیا out-of-sample path پیدا کریں۔ کسی allocation نے اس path کو پہلے نہیں دیکھا۔
- اس path پر دونوں allocations کو
log(1 + r)کے average کے ذریعے score کریں، جہاں r اس دن پانچوں asset returns کا weighted sum ہے۔ - ہر T پر steps 4 سے 9 کو 2000 independent trials کے لیے دہرائیں، اور یہ ریکارڈ کریں کہ کتنے trials میں equal weight نے optimized weights سے بہتر score حاصل کیا۔
Sweep کو مختصر T سے طویل T تک پڑھیں۔ مختصر T پر equal weight واضح اکثریت trials میں کامیاب رہتا ہے۔ T بڑھنے کے ساتھ یہ share مسلسل کم ہوتا ہے، اور طویل T پر optimized weights زیادہ تر trials میں کامیاب رہتے ہیں۔ درمیان میں کسی مقام پر دونوں کی کارکردگی ایک دوسرے کو cross کرتی ہے۔ Crossover point seed اور true means کے درمیان spread کے ساتھ بدلتا ہے۔ سمت نہیں بدلتی: زیادہ data optimizer کے حق میں جاتا ہے، جبکہ کم data 1/N کے حق میں ہوتا ہے۔ Replicate کرنے کے لیے random.seed(20260816) کے اندر موجود integer تبدیل کریں اور sweep دوبارہ چلائیں۔
خراب mean estimate کو optimizer کیسے بڑھا چڑھا کر پیش کرتا ہے
دیکھیں کہ estimates weight میں کہاں شامل ہوتے ہیں۔ estimated mean numerator میں ہوتا ہے، جبکہ estimated variance denominator میں۔ mean estimate کو دوگنا کریں تو weight بھی دوگنا ہو جاتا ہے۔ variance estimate میں ایک چوتھائی کمی کریں تو weight ایک تہائی بڑھ جاتا ہے۔ خوش قسمت sample میں دونوں غلطیاں ایک ہی سمت میں اثر ڈالتی ہیں: اچھے returns کا مسلسل سلسلہ measured mean کو بڑھاتا ہے اور اکثر اسی مدت کے دوران measured variance کو بھی کم کر دیتا ہے۔ optimizer اس asset کو گروپ کا نمایاں ترین رکن سمجھتا ہے اور اسی حساب سے اس کی position کا حجم مقرر کرتا ہے۔ out-of-sample مدت میں وہ دوبارہ اسی گروپ کا ایک عام رکن بن جاتا ہے۔ Equal weight نے خوش قسمت sample کو کبھی دیکھا ہی نہیں تھا۔
Simulation اس مسئلے کی نسبتاً نرم صورت پیش کرتی ہے۔ پانچ uncorrelated assets ایسی diagonal covariance matrix بناتے ہیں جسے invert کرنے کی ضرورت نہیں پڑتی۔ حقیقی portfolios correlated ہوتے ہیں، اور ایسی sample covariance matrix جو assets کی تعداد سے تھوڑی ہی زیادہ observations پر مبنی ہو، singular ہونے کے قریب رہتی ہے۔ اسے invert کرنے سے input کی معمولی غلطیاں بہت بڑے weights میں بدل جاتی ہیں۔ اسی طرح optimizer ایک نام میں capital سے کئی گنا بڑی position اور اس کے قریبی متبادل میں اس کے مقابل offsetting short position تک پہنچ سکتا ہے۔ portfolio میں concentration risk پر ہمارا note بتاتا ہے کہ اس نوعیت کا weight drawdown پر کیا اثر ڈالتا ہے۔
Input بھی ساکن نہیں رہتا۔ ذیل کا panel ایک broad index fund اور consumer staples کے ایک بڑے نام کے لیے rolling one-year average daily return دکھاتا ہے۔ یہ return annualized ہے اور data ماہانہ بنیاد پر لیا گیا ہے۔
ہر عدد کے پیچھے موجود درست SQL
WITH prices AS
(
SELECT
ticker,
date,
toFloat64(max(close)) AS c
FROM global_markets.stocks_daily_aggs
WHERE ticker IN ('SPY', 'KO')
AND date >= '2015-10-01'
AND date < '2025-01-01'
GROUP BY ticker, date
),
rets AS
(
SELECT
ticker,
date,
c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
FROM prices
),
trailing AS
(
SELECT
ticker,
date,
avg(ret) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) * 252 * 100 AS trailing_mean_pct,
row_number() OVER (PARTITION BY ticker ORDER BY date ASC) AS i
FROM rets
WHERE isFinite(ret)
)
SELECT
toString(toStartOfMonth(date)) AS month,
round(avgIf(trailing_mean_pct, ticker = 'SPY'), 1) AS spy_trailing_mean_pct,
round(avgIf(trailing_mean_pct, ticker = 'KO'), 1) AS ko_trailing_mean_pct
FROM trailing
WHERE i >= 252
AND date >= '2017-01-01'
GROUP BY month
ORDER BY month ASCان دونوں lines کا ہر point ایک ایسا عدد ہے جسے کوئی optimizer اس تاریخ پر expected return کے طور پر قبول کر سکتا تھا۔ SPY کی پہلی monthly reading 17.7% ہے اور آخری 25.8%، جبکہ درمیان میں 96 readings موجود ہیں۔ KO اسی window کا آغاز -0.4% سے کرتا ہے۔ جو weighting scheme اس series کو ماہ بہ ماہ استعمال کرتی ہے، وہ اس میں موجود ہر اتار چڑھاؤ کو بھی اپنے اندر شامل کر لیتی ہے۔
کیا half Kelly اور shrinkage مسئلہ حل کرتے ہیں؟
یہ اسے نرم کرتے ہیں۔ عملی طور پر چار طریقے استعمال ہوتے ہیں، اور ہر طریقہ تخمینی حساسیت کم کرنے کے بدلے نظریاتی optimum کا کچھ حصہ چھوڑ دیتا ہے۔
- Half Kelly ہر weight کو نصف کر دیتا ہے۔ Kelly growth curve اپنی بلند ترین سطح کے قریب ہموار، جبکہ اس سے نیچے تیزی سے گرتی ہے۔ اس لیے half stake نظریاتی growth rate کا نسبتاً معمولی حصہ چھوڑتا ہے، لیکن overstated edge سے ہونے والے نقصان میں کہیں زیادہ کمی لاتا ہے۔ Volatility targeting بھی یہی اصول denominator پر لاگو کرتا ہے اور position sizing کے لیے اس واحد input سے فائدہ اٹھاتا ہے جو ایک مختصر sample فراہم کر سکتا ہے۔
- Shrinkage ہر estimated mean کو estimates کے cross-sectional average کی سمت کھینچتا ہے۔ Sample جتنا چھوٹا ہو، یہ adjustment اتنی ہی بڑھتی ہے۔ اسے آخری حد تک لے جائیں تو ہر asset کا expected return یکساں ہو جاتا ہے؛ اور اگر volatilities بھی یکساں ہوں تو optimizer خود بخود equal weight واپس کرتا ہے۔ Equal weight مکمل طور پر shrunk portfolio ہے۔
- Constraints، یعنی short selling کی اجازت نہ دینا اور ہر position کے لیے maximum cap مقرر کرنا، اس حد کو محدود کرتے ہیں کہ ایک خوش قسمت estimate کسی single weight کو کتنا بڑھا سکتا ہے۔ یہ estimate کو بہتر بنانے کے بجائے نقصان پر قابو پانے کا طریقہ ہیں۔
- Expected returns کو مکمل طور پر خارج کرنے سے minimum variance اور risk parity باقی رہتے ہیں، جو صرف covariance استعمال کرتے ہیں۔ یہی وہ input ہے جو sample حقیقتاً فراہم کر سکتا ہے۔
ان چاروں میں سے کوئی بھی ایسا information پیدا نہیں کرتا جو sample میں موجود نہ ہو۔ فرق صرف یہ ہے کہ portfolio کا کتنا حصہ ایسی information پر منحصر رہتا ہے جو شاید آپ کے پاس موجود ہی نہ ہو۔
جب optimization اپنا جواز ثابت کرتی ہے
یہ crossover دونوں سمتوں میں ہوتا ہے۔ جب T حقیقی means کے درمیان spread کے مقابلے میں کافی بڑا ہو جاتا ہے تو optimized allocation آگے نکل جاتی ہے اور پھر برتری برقرار رکھتی ہے۔ یہ spread جتنا وسیع ہو، یہ مرحلہ اتنا ہی پہلے آتا ہے۔ جب input وہ ہو جو data فراہم کرتا ہے تو optimization ہی درست tool ہے: covariance اور hedge ratios کا اندازہ expected returns کے مقابلے میں کہیں زیادہ بہتر لگایا جا سکتا ہے۔
Equal weight کی بھی اپنی قیمت ہے۔ یہ اس معلومات کو نظرانداز کرتی ہے جو آپ کے پاس حقیقتاً موجود ہوتی ہے، اور چھوٹی universe میں اتنی ہی زیادہ concentration پیدا کر سکتی ہے جتنی کوئی optimizer کرتا۔ اسے baseline سمجھیں، اور ہر candidate weighting کو ایسے data پر اس سے بہتر کارکردگی دکھانی چاہیے جسے weights نے دیکھا ہی نہ ہو۔ ایک ہی sample پر weights fit کرنا اور انہی کو score کرنا backtesting میں look-ahead bias ہی کی ایک مختلف شکل ہے، اور یہ ہر بار optimizer کو غیرضروری فائدہ دیتا ہے۔ کسی ایک point estimate کے بجائے measured edge کے گرد ایک قابلِ اعتماد range کے لیے bootstrapped confidence intervals معیاری tool ہیں۔
اکثر پوچھے جانے والے سوالات
کیا equal weight واقعی mean variance optimization سے بہتر کارکردگی دکھاتا ہے؟
مختصر samples میں اکثر ایسا ہوتا ہے۔ Optimizer کو ہر asset کے expected return کا تخمینہ درکار ہوتا ہے، اور اس تخمینے کی standard error تقریباً asset کی volatility کو sample length کے برسوں کے square root سے تقسیم کرنے کے برابر ہوتی ہے۔ جب تک یہ error assets کے درمیان حقیقی فرق سے بڑی رہتی ہے، optimizer noise کو ترتیب دے رہا ہوتا ہے۔ Equal weight میں ایسا کوئی تخمینہ نہیں ہوتا جس میں غلطی ہو سکے۔
Expected return کا تخمینہ لگانے کے لیے کتنے observations درکار ہوتے ہیں؟
تقریباً ہر شخص کے اندازے سے زیادہ۔ 20 فیصد volatility والے asset کے لیے ایک سال کا daily data سالانہ بنیاد پر تقریباً 20 percentage points کی standard error چھوڑتا ہے۔ اس error کو نصف کرنے کے لیے calendar span کو چار گنا کرنا پڑتا ہے۔ اسی سال کے اندر intraday observations شامل کرنے سے مدد نہیں ملتی۔ اس کے برعکس volatility کا قابلِ استعمال تخمینہ چند ماہ کے data سے بھی لگایا جا سکتا ہے۔
کیا half Kelly صرف ایک چھوٹی bet ہے؟
یہ سازگار شرائط پر ایک چھوٹی bet ہے۔ Kelly growth curve اپنی بلند ترین سطح کے قریب ہموار ہوتی ہے۔ اس لیے stake کو نصف کرنے سے نظریاتی growth rate کا صرف ایک چھوٹا حصہ ضائع ہوتا ہے، جبکہ path کی volatility تقریباً نصف ہو جاتی ہے اور edge کو زیادہ سمجھنے کی لاگت بھی کم ہو جاتی ہے۔
1/N portfolio کیا ہے؟
یہ وہ portfolio ہے جس میں capital کا مساوی حصہ N positions میں لگایا جاتا ہے اور مقررہ schedule کے مطابق rebalancing کی جاتی ہے۔ اسے return forecast یا covariance estimate کی ضرورت نہیں ہوتی۔ اسی لیے یہ ہر ایسے weighting scheme کے لیے standard benchmark ہے جسے ان تخمینوں کی ضرورت ہوتی ہے۔
پینلز کیسے تیار کیے گئے ہیں
تینوں panels daily closes پڑھتے ہیں اور close to close simple returns calculate کرتے ہیں۔ ہر ticker اور date کے لیے duplicate rows کو ایک close تک محدود کر دیا جاتا ہے۔ Means کو average daily return کو 252 sessions سے ضرب دے کر annualize کیا گیا ہے۔ Volatilities کو daily standard deviation کو 252 کے square root سے ضرب دے کر annualize کیا گیا ہے۔ Yearly panel میں calendar year صرف اسی صورت شامل کیا گیا ہے جب اس میں کم از کم 200 sessions موجود ہوں۔ Block panel non-overlapping blocks استعمال کرتا ہے اور ہر length پر آخری نامکمل block کو خارج کر دیتا ہے۔ اس کا window count column دکھاتا ہے کہ ہر length سے کتنے blocks بنے۔ کہیں بھی dividends شامل نہیں کیے گئے، اس لیے یہ price returns ہیں اور dividend-paying assets کے mean کی level کم ظاہر ہوتی ہے۔ Panels کا مقصد estimates کے پھیلاؤ کو دکھانا ہے، ان کی level کو نہیں۔
یہاں ہر panel کے نیچے chart کے لیے مکمل اور عین SQL موجود ہے، جبکہ simulation کے ساتھ اس کا seed بھی دیا گیا ہے۔ اپنی مطلوبہ names کی فہرست پر یہی estimate stability check چلانے کے لیے Strasmore terminal پر plain English میں درخواست کریں۔