مقامی A-share Data Lake اور AI Agents
ashare-lake آپ کی disk پر A-share کے لیے 39 datasets کا مقامی data lake بناتا ہے، delisting records، point-in-time queries اور AI agents کے لیے MCP server فراہم کرتا ہے۔
مقامی A-share data lake سے مراد Chinese mainland equity market کی تاریخ ہے جو آپ کی اپنی disk پر columnar Parquet files کی صورت میں محفوظ ہوتی ہے۔ اسے DuckDB یا Polars کے ذریعے پڑھا جا سکتا ہے۔ یوں ہر بار vendor endpoint سے ایک ایک page طلب کرنے کی ضرورت نہیں رہتی۔ ashare-lake ایک open-source project ہے جو ایسا data lake تیار کرتا ہے، اسے تازہ رکھنے کے لیے روزانہ کا job چلاتا ہے، اور ایک Model Context Protocol server فراہم کرتا ہے جس کے ذریعے AI agent اس سے query کر سکتا ہے۔ اس project کے دو design choices اسے یہاں زیرِ بحث لانے کی بنیادی وجہ ہیں: delisted names محفوظ رکھے جاتے ہیں، اور fundamentals کو کسی سابقہ تاریخ کے مطابق پڑھا جا سکتا ہے۔
AI agent کو مقامی A-share data lake کی ضرورت کیوں ہے
مقامی copy کے بغیر چینی equities پر تحقیق کرنے والے agent کے پاس دو راستے ہوتے ہیں۔ وہ finance pages scrape کرے، اپنے context window کا بڑا حصہ HTML پر خرچ کرے، اور ایسے numbers تیار کرے جنہیں اگلے ماہ کوئی reproduce نہ کر سکے۔ یا وہ registration-gated vendor کو call کرے، جو rows کی تعداد محدود کرتا ہے اور ہر result کو ایک account سے وابستہ کر دیتا ہے۔
Scale وہ پہلو ہے جسے اکثر کم سمجھا جاتا ہے۔ ہمارے اپنے warehouse میں US tape کو minute resolution پر محفوظ کیا جاتا ہے، اور اس کا ایک معمول کا ہفتہ یوں دکھائی دیتا ہے:
ہر عدد کے پیچھے موجود درست SQL
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS session,
formatDateTime(toDate(toTimeZone(window_start, 'America/New_York')), '%b %e') AS session_label,
uniqExact(ticker) AS tickers_count,
round(count() / 1000000, 2) AS minute_bars_millions
FROM global_markets.delayed_stocks_minute_aggs
WHERE toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2026-07-20')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-24')
GROUP BY session, session_label
ORDER BY sessionJul 20 پر tape نے 1.79 million minute bars پیدا کیے، جو 11737 symbols پر مشتمل تھے، اور panel کے دیگر چار sessions میں بھی یہی صورتِ حال دہرائی گئی۔ ایک national market، ایک ہفتہ، ایک resolution۔ کسی دوسرے market کے لیے daily bars، fundamentals، index membership اور money-flow records کا ایک عشرہ بھی اسی نوعیت کا حجم رکھتا ہے، اور اسے HTTP کے ذریعے page by page حاصل کرنا agent کے run کو ضائع کر دیتا ہے۔
مقامی lake بیک وقت دو چیزیں بدل دیتا ہے۔ Reads quota کے بجائے file scan بن جاتے ہیں، اور آج لکھی گئی query چھ ماہ بعد بھی وہی rows واپس کرتی ہے۔ Backtest کے قابلِ جانچ ہونے کے لیے یہی ضروری ہے۔ ہماری تحریریں AI agents کے لیے market data skills اور market data پر SQL API بھی US data کے بارے میں یہی مؤقف پیش کرتی ہیں۔
اسے ایک version پر pin کر کے install کریں
Python 3.10 یا اس کے بعد کا version استعمال کریں۔ version کو pin کریں: 27 جولائی سے 2 اگست 2026 کے درمیان چھ releases جاری ہوئیں، اور agent کے setup script میں unpinned install ایک بدلتا ہوا target بن جاتا ہے۔ code rootSunc/ashare-lake میں Apache 2.0 کے تحت موجود ہے۔
pip install ashare-lake==0.5.0اگست 2026 کے اوائل تک موجودہ release install کرتا ہے۔asl --versioninstalled build دکھاتا ہے۔asl config init --data-root /path/to/ashare-lakepackaged example TOML لکھتا ہے اور اس میں آپ کا data root شامل کرتا ہے؛ repository checkout کی ضرورت نہیں۔--configoutput path مقرر کرتا ہے، جبکہ--forceموجودہ فائل overwrite کرتا ہے۔asl doctorکسی بھی data movement سے پہلے اس کے checks offline چلاتا ہے۔asl servers testupstream quote hosts کو probe کرتا ہے۔asl sourcesہر source کو probe کرتا ہے، جس میں--vantageکی قدرcn،overseasیاlocalہو سکتی ہے۔
یہیں رکیں۔ اگلا command backfill ہے، اور اسے پڑھتے ہوئے فوراً چلانا مناسب نہیں۔
Backfill کا کام
asl init ڈائریکٹری کا ڈھانچہ بناتا ہے اور تاریخی ڈیٹا مکمل کرتا ہے۔ پروجیکٹ کی دستاویزات کے مطابق مکمل run میں کئی گھنٹے کا wall time اور disk پر کئی GB درکار ہوتے ہیں۔ اس کے لیے upstream Tongdaxin quote host سے live connection بھی ضروری ہے، جس کی تصدیق asl servers test کرتا ہے۔ asl init --profile quick اس کے بجائے گزشتہ تین برس کا ڈیٹا چند منٹ میں حاصل کرتا ہے۔ یہ اس مدت کے دوران trade کرنے والے ہر نام کو برقرار رکھتا ہے، ان ناموں کو بھی جو بعد میں market سے نکل چکے ہوں۔ اس کے بعد asl run daily incremental job چلاتا ہے، asl status --datasets ہر dataset کے لیے coverage اور freshness رپورٹ کرتا ہے، جبکہ asl serve 127.0.0.1:8787 پر read-only dashboard دستیاب کراتا ہے۔
Repository میں کوئی data شامل نہیں ہوتا۔ ہر Parquet file آپ کی machine پر تیار ہوتی ہے۔ ہر row میں row-level lineage درج ہوتی ہے، جس سے معلوم ہوتا ہے کہ اسے کس source نے فراہم کیا اور کب fetch کیا گیا۔
39 datasets کیا ہیں؟
یہ datasets تہہ در تہہ منظم ہیں، بنیادی reference data سے شروع ہو کر بیرونی سطحوں تک: 36 curated tables اور 3 derived tables۔
- Reference: instruments، 2016 سے 2027 تک کا trading calendar، trading status۔
- Market data: daily bars، index bars، 1-minute اور 5-minute bars، trade ticks، commodity bars، adjustment factors، delisting events۔
- Corporate events: corporate actions، announcement index، earnings disclosure schedule۔
- Fundamentals and valuation: financial statement items، valuation metrics، analyst consensus۔
- Capital flow: fund flow، margin trading، northbound flows and holdings، بڑے orders کے disclosures پر مشتمل dragon-tiger board، block trades، institutional holdings۔
- Structure and industry: sector members، index constituents، industry members، industry index۔
- Macro: macro indicators، market breadth، economic calendar۔
- Sentiment and rotation: sentiment scores، hot rank، sector bars، sector fund flow، news headlines، flash news wire۔
- Risk and compliance: share unlock schedule، regulatory events۔
کسی dataset کی جگہ یہ بتاتی ہے کہ مصنف کے لیے کیا اہم ہے۔ adjustment factors اور delisting events کو daily bars کے ساتھ Market data layer میں رکھا گیا ہے، کسی appendix میں الگ نہیں کیا گیا۔ تاریخ پر مبنی strategies کو test کرنے والے کے لیے یہی placement پورے project کا سب سے اہم حصہ ہے۔
مقامی lake survivorship bias سے کیسے نمٹتی ہے
Survivorship bias اس وقت پیدا ہوتا ہے جب کسی study کا universe ان names سے بنایا جائے جو آج بھی listed ہیں۔ جو companies merge ہو چکی ہوں، private ہو گئی ہوں یا delist ہو گئی ہوں، وہ خاموشی سے dataset سے غائب رہتی ہیں۔ غائب ہونے والے names عموماً کامیاب ترین نہیں ہوتے۔
ہمارا warehouse US market میں اس کمی کا حجم ناپ سکتا ہے۔ حساب وہی ہے، صرف alphabet مختلف ہے۔ ہر سال کے لیے مارچ کے دوسرے ہفتے میں minute bar print کرنے والے ہر symbol کو لیں، پھر دیکھیں کہ ان میں سے کون سے جولائی 2026 کے آخری دو ہفتوں میں بھی print کر رہے تھے:
ہر عدد کے پیچھے موجود درست SQL
WITH on_tape_now AS (
SELECT ticker
FROM global_markets.delayed_stocks_minute_aggs
WHERE toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2026-07-20')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
GROUP BY ticker
),
cohort AS (
SELECT toYear(toTimeZone(window_start, 'America/New_York')) AS cohort_year,
ticker
FROM global_markets.delayed_stocks_minute_aggs
WHERE toYear(toTimeZone(window_start, 'America/New_York')) BETWEEN 2016 AND 2025
AND toMonth(toTimeZone(window_start, 'America/New_York')) = 3
AND toDayOfMonth(toTimeZone(window_start, 'America/New_York')) BETWEEN 10 AND 14
GROUP BY cohort_year, ticker
)
SELECT c.cohort_year AS year,
count() AS names_on_tape_count,
countIf(n.ticker != '') AS still_trading_count,
count() - countIf(n.ticker != '') AS gone_count,
round(100 * countIf(n.ticker != '') / count(), 1) AS still_trading_pct
FROM cohort AS c
LEFT JOIN on_tape_now AS n ON c.ticker = n.ticker
GROUP BY year
ORDER BY year2016 میں اس ہفتے trading کرنے والے 8101 symbols میں سے 50.1% جولائی 2026 کے آخر میں بھی tape پر موجود تھے، جبکہ 4040 موجود نہیں تھے۔ 2025 cohort کا نتیجہ 86.7% ہے۔ آج کی listings سے تیار کیا گیا screen جب ان 10 برسوں پر ماضی کی طرف چلایا جائے تو مارکیٹ کا بڑھتا ہوا حصہ راستے میں خارج کر دیتا ہے۔
عام مفروضہ یہ ہے کہ غائب ہونے والے names سب penny stocks تھے۔ مارچ 2021 کے cohort کو اس مہینے کے average daily dollar volume کی بنیاد پر tiers میں تقسیم کرنے سے مختلف تصویر سامنے آتی ہے:
ہر عدد کے پیچھے موجود درست SQL
WITH on_tape_now AS (
SELECT ticker
FROM global_markets.delayed_stocks_minute_aggs
WHERE toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2026-07-20')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2026-07-31')
GROUP BY ticker
),
march_2021 AS (
SELECT ticker,
sum(toFloat64(close) * toFloat64(volume))
/ uniqExact(toDate(toTimeZone(window_start, 'America/New_York'))) AS avg_daily_dollar_volume
FROM global_markets.delayed_stocks_minute_aggs
WHERE toDate(toTimeZone(window_start, 'America/New_York')) >= toDate('2021-03-01')
AND toDate(toTimeZone(window_start, 'America/New_York')) <= toDate('2021-03-31')
GROUP BY ticker
)
SELECT multiIf(d.avg_daily_dollar_volume >= 1000000000, '$1B or more',
d.avg_daily_dollar_volume >= 100000000, '$100M to $1B',
d.avg_daily_dollar_volume >= 10000000, '$10M to $100M',
d.avg_daily_dollar_volume >= 1000000, '$1M to $10M',
'under $1M') AS liquidity_bucket,
count() AS names_count,
countIf(n.ticker = '') AS gone_count,
round(100 * countIf(n.ticker = '') / count(), 1) AS gone_pct
FROM march_2021 AS d
LEFT JOIN on_tape_now AS n ON d.ticker = n.ticker
GROUP BY liquidity_bucket
ORDER BY min(d.avg_daily_dollar_volume)under $1M tier نے سب سے بڑا حصہ کھویا: اس کے 3968 names میں سے 57.5%۔ سب سے زیادہ مصروف tier بھی اس سے مستثنیٰ نہیں تھا۔ مارچ 2021 میں روزانہ $1B or more کے حساب سے trading کرنے والے 89 symbols میں سے 3.4% جولائی 2026 کے آخر تک مارکیٹ سے نکل چکے تھے۔ Mergers، take-privates، bankruptcies اور index exits سب price table میں ایک ہی طرح ختم ہوتے ہیں: rows رک جاتی ہیں۔
ashare-lake اسے بنیادی مسئلہ سمجھتا ہے۔ Instruments dataset delisted symbols کو live names تک محدود کرنے کے بجائے برقرار رکھتا ہے۔ delisting_events table ہر departed name کے اختتام کا طریقہ ریکارڈ کرتی ہے، اور Python API میں universe="all_a" ایسا historical snapshot فراہم کرتا ہے جس میں یہ names بھی شامل ہوتے ہیں۔ Project کی اپنی docs کے مطابق 2016 سے 2021 کے دوران survivor-only backtest اور delisting-inclusive backtest کے نتائج میں تقریباً two-fold فرق تھا۔ یہ ہمارے backtesting میں look-ahead bias کے نوٹس میں بیان کیے گئے trap کا عکس ہے: ایسا universe جو خاموشی سے مستقبل سے واقف ہو۔
Point-in-time reads
load("financial_statement_items", as_of="2018-04-30") ہر line item کا وہ تازہ ترین version واپس کرتا ہے جو اس تاریخ تک announce ہو چکا ہو، نہ کہ بعد میں restate کیا گیا number۔ Bars میں adjust argument شامل ہوتا ہے: backward adjustment کے لیے hfq، query window کے اندر normalization کے لیے qfq، یا raw prices۔ ایسے numbers پر تیار کیا گیا factor جنہیں market نے اس وقت تک publish ہی نہیں کیا تھا، کسی چیز کی پیمائش نہیں کرتا۔ کسی بھی LLM سے تیار کردہ alpha factor pipeline میں سب سے پہلے یہی چیز جانچنی چاہیے۔
اسے MCP server کے طور پر رجسٹر کرنا
Model Context Protocol وہ طریقہ ہے جس کے ذریعے agent tools حاصل کرتا ہے۔ asl mcp اسے stdio کے ذریعے چلاتا ہے، جبکہ client process شروع کرتا ہے:
claude mcp add ashare-lake -- asl mcp --config /abs/path/to/ashare-lake.toml- کوئی بھی دوسرا MCP client یہی دو اجزا استعمال کرتا ہے: command کے طور پر
asl، اور arguments کے طور پرmcp --configکے ساتھ absolute path۔ path کا absolute ہونا ضروری ہے، کیونکہ client process کو کسی بھی directory سے شروع کر سکتا ہے۔
چھ tools دستیاب ہوتے ہیں۔ انہیں dataset کے بجائے سوال کی نوعیت کے مطابق منظم کیا گیا ہے: موجودہ ڈیٹا اور اسے پڑھنے کے طریقے کے لیے describe_lake، نام کو code میں تبدیل کرنے کے لیے resolve_symbol، جس میں delisted names بھی شامل ہیں، query_bars، اس کے as_of argument کے ساتھ query_fundamentals، دیگر تمام امور کے لیے query_dataset، اور datasets میں ایک read-only DuckDB SELECT چلانے کے لیے run_sql۔ --live flag server کو اجازت دیتا ہے کہ وہ symbol lookups اور unadjusted daily bars upstream سے حاصل کرے، بغیر lake میں لکھے۔
پہلے جاننے کے قابل حدود
- صرف A-shares شامل ہیں۔ Hong Kong، US listings یا mainland China سے باہر کی کوئی چیز شامل نہیں۔
- یہ ایک ذاتی project ہے۔ Issues اور pull requests پر best-effort بنیاد پر توجہ دی جاتی ہے، اور docs میں واضح طور پر درج ہے کہ availability کی کوئی guarantee نہیں۔ upstream sites تبدیل ہو سکتی ہیں، اور کوئی IP block ہو سکتا ہے، جس کے بعد کوئی شخص patch جاری کرے تب تک data ingest رک جاتا ہے۔
- Apache 2.0 code کا احاطہ کرتا ہے، data کا نہیں۔ ہر upstream source اپنی شرائط برقرار رکھتا ہے، اور maintainer آپ کے تیار کردہ Parquet files کو redistribute یا resell کرنے کا کوئی حق نہیں دیتا۔ کسی بھی commercial use سے پہلے source کی شرائط پڑھیں۔
- جن sources سے یہ project data پڑھتا ہے، ان کے لیے account یا token درکار نہیں۔ یہی اس کی کشش بھی ہے اور کمزوری بھی۔
- Windows support 0.3.0 میں شامل ہوئی، جبکہ 0.3.1 میں Python کی کم از کم version 3.10 کر دی گئی۔
ان project facts کے ذرائع
Version 0.5.0، release کی چھ تاریخیں اور Python کی کم از کم version، project کی PyPI release history اور CHANGELOG سے لیے گئے ہیں، جنہیں 4 اگست 2026 کو پڑھا گیا تھا۔ Dataset catalog، delisting اور point-in-time behaviour، CLI flags، MCP tool list، نیز licensing اور support سے متعلق عبارت repository docs سے لی گئی ہے: docs/datasets/catalog.md، docs/reference/cli.md، docs/reference/mcp.md، اور docs/legal-and-data-sources.md۔ Software posts کے مقابلے میں زیادہ تیزی سے تبدیل ہوتا ہے، اس لیے جو version آپ install کریں اس کی docs ضرور دیکھیں۔ دونوں survivorship panels ہمارے اپنے warehouse میں موجود US symbols کی پیمائش کرتے ہیں، Chinese listings کی نہیں، اور یہ A-share market کی پیمائش کے بجائے اس mechanism کی مثال پیش کرتے ہیں۔
FAQ
کیا مقامی A-share data lake بنانے کے لیے API key درکار ہوتی ہے؟
اس کے لیے نہیں۔ یہ جن upstream sources سے data پڑھتا ہے، وہاں registration یا token درکار نہیں ہوتا، اور data lake خود آپ کی machine پر رہتا ہے۔ ہر source کی اپنی terms of use ہوتی ہیں، جو کسی بھی commercial کام سے پہلے اہم ہیں۔
ashare-lake کا backfill مکمل ہونے میں کتنا وقت لگتا ہے؟
دستاویزات کے مطابق مکمل historical backfill میں wall-clock time کے حساب سے کئی گھنٹے اور disk پر کئی GB درکار ہوتے ہیں۔ اس دوران upstream quote host سے working connection بھی مسلسل ضروری رہتا ہے۔ asl init --profile quick حالیہ تین برس کا data چند منٹ میں cover کرتا ہے اور ان names کو بھی شامل رکھتا ہے جو بعد میں delist ہو چکے ہیں۔
کیا مقامی A-share data lake میں delisted stocks شامل ہوتے ہیں؟
اس میں شامل ہوتے ہیں۔ Delisted symbols instruments dataset میں برقرار رہتے ہیں، ایک delisting_events table ہر name کے اختتام کا ریکارڈ رکھتی ہے، اور universe="all_a" ایک historical snapshot تیار کرتا ہے جس میں یہ stocks بھی شامل ہوتے ہیں۔ اوپر ہماری اپنی US measurement سے ظاہر ہوتا ہے کہ صرف surviving names پر مشتمل universe کتنا data خارج کر دیتا ہے۔
کیا AI agent براہِ راست ashare-lake سے query کر سکتا ہے؟
ہاں۔ asl mcp Model Context Protocol کے ذریعے چھ tools فراہم کرتا ہے۔ ان میں ایک read-only SQL tool بھی شامل ہے، اس لیے agent scraping کے بجائے مقامی Parquet سے query کرتا ہے۔ اسے claude mcp add ashare-lake -- asl mcp --config /abs/path/to/ashare-lake.toml کے ساتھ register کریں۔
کیا ashare-lake، AkShare یا Baostock کا متبادل ہے؟
نہیں۔ یہ ان کے اوپر کام کرتا ہے۔ یہ libraries upstream سے data fetch کرتی ہیں، جبکہ یہ project حاصل کیے گئے data کو curated Parquet میں store، version اور reconcile کرتا ہے۔ اس میں row-level lineage اور ہر dataset کے لیے ایک الگ contract بھی شامل ہے۔
اوپر دی گئی ہر figure حقیقی market data پر مبنی ایک stored، versioned query ہے۔ SQL پڑھنے کے لیے کسی بھی panel کو expand کریں، یا Strasmore terminal پر اپنے universe میں یہی survivorship check چلائیں۔