ساخت دریاچه داده محلی سهام A برای ایجنتهای هوش مصنوعی
پروژه ashare-lake با ذخیره 39 مجموعه داده در قالب فایلهای Parquet روی دیسک، امکان پرسوجوهای دقیق تاریخی و دسترسی به سوابق حذفشده را برای ایجنتهای هوش مصنوعی فراهم میکند.
ashare-lake
یک «دریاچه داده» (data lake) محلی برای سهام A، در واقع تاریخچه بازار سهام سرزمین اصلی چین است که بهجای استفاده از نقاط پایانی (endpoint) فروشندگان که دادهها را صفحه به صفحه ارائه میدهند، بهصورت فایلهای ستونی Parquet روی دیسک شخصی شما ذخیره شده و توسط DuckDB یا Polars قابل خواندن است. ashare-lake یک پروژه متنباز است که چنین ساختاری را ایجاد میکند؛ این پروژه شامل یک فرآیند روزانه برای بهروزرسانی دادهها و یک سرور پروتکل زمینه مدل (Model Context Protocol) است که به یک عامل هوش مصنوعی اجازه میدهد در آن جستوجو کند. دو انتخاب در طراحی، این پروژه را شایسته معرفی در اینجا کرده است: نمادهای حذفشده از فهرست (delisted) حفظ میشوند و دادههای بنیادی (fundamentals) را میتوان بر اساس تاریخهای گذشته بازخوانی کرد.
چرا یک ایجنت هوش مصنوعی به دریاچه داده محلی برای سهام A نیاز دارد
ایجنت هوش مصنوعی که بدون داشتن یک کپی محلی به تحقیق درباره سهام چین میپردازد، دو مسیر پیش رو دارد. یا صفحات مالی را اسکرپ میکند که باعث هدر رفتن پنجره کانتکست (context window) روی کدهای HTML میشود و اعدادی تولید میکند که ماه آینده هیچکس قادر به بازتولید آنها نیست؛ یا از فروشندهای با دسترسی محدود و نیازمند ثبتنام استفاده میکند که تعداد ردیفهای خروجی را محدود کرده و هر نتیجه را به یک حساب کاربری خاص گره میزند.
مقیاس، بخشی است که اغلب دستکم گرفته میشود. انبار داده اختصاصی ما، دادههای بازار ایالات متحده را با رزولوشن دقیقهای نگهداری میکند و یک هفته معمولی در آن به این شکل است:
کد دقیق 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 sessionدر Jul 20، این بازار 1.79 میلیون نوار دقیقهای برای 11737 نماد تولید کرد و چهار جلسه معاملاتی دیگر در این پنل نیز همین الگو را تکرار میکنند. یک بازار ملی، یک هفته، یک رزولوشن. یک دهه دادههای روزانه، صورتهای مالی، عضویت در شاخصها و سوابق جریان پول برای بازاری دیگر نیز همین ساختار را دارد و فراخوانی آن از طریق HTTP، منابع پردازشی ایجنت را به سرعت تخلیه میکند.
داشتن یک دریاچه داده محلی، دو تغییر همزمان ایجاد میکند. خواندن دادهها به جای محدودیت سهمیه، به یک اسکن فایل تبدیل میشود و کوئری نوشتهشده در امروز، شش ماه دیگر همان ردیفها را بازمیگرداند؛ این همان چیزی است که برای قابلبررسی بودن یک بکتست (backtest) ضروری است. یادداشتهای ما درباره مهارتهای داده بازار برای ایجنتهای هوش مصنوعی و یک رابط SQL برای دادههای بازار، همین استدلال را برای دادههای ایالات متحده مطرح میکنند.
نصب و تثبیت نسخه
پایتون 3.10 یا جدیدتر. نسخه را تثبیت کنید: بین 27 ژوئیه تا 2 اوت 2026، شش نسخه منتشر شده است و نصب بدون تثبیت نسخه در اسکریپت راهاندازی یک ایجنت، هدفی متغیر محسوب میشود. کد در rootSunc/ashare-lake تحت مجوز Apache 2.0 قرار دارد.
pip install ashare-lake==0.5.0نسخه جاری تا اوایل اوت 2026 را نصب میکند.asl --versionبیلد نصبشده را چاپ میکند.asl config init --data-root /path/to/ashare-lakeفایل نمونه TOML بستهبندیشده را با درج مسیر ریشه دادههای شما مینویسد؛ نیازی به دریافت مخزن (checkout) نیست.--configمسیر خروجی را تعیین میکند و--forceفایل موجود را بازنویسی میکند.asl doctorبررسیهای خود را پیش از هرگونه جابهجایی داده، بهصورت آفلاین انجام میدهد.asl servers testمیزبانهای بالادستی قیمتها را بررسی میکند.asl sourcesهر منبع را با یک--vantageاز نوعcn،overseasیاlocalارزیابی میکند.
در اینجا متوقف شوید. دستور بعدی، عملیات backfill است و نباید همزمان با مطالعه اجرا شود.
عملکرد فرایند تکمیل دادهها (Backfill)
asl init ساختار دایرکتوری را ایجاد کرده و تاریخچه را تکمیل میکند. طبق مستندات پروژه، اجرای کامل این فرایند چندین ساعت زمان برده و چندین گیگابایت فضا روی دیسک اشغال میکند؛ همچنین این فرایند نیازمند اتصال زنده به یک میزبان قیمتگذاری Tongdaxin بالادستی است که asl servers test صحت آن را تأیید میکند. در مقابل، asl init --profile quick بازه زمانی سه سال اخیر را در عرض چند دقیقه پوشش میدهد و تمامی نمادهایی را که در این بازه معامله شدهاند، از جمله مواردی که از بازار خارج شدهاند، حفظ میکند. asl run daily وظیفه بهروزرسانیهای افزایشی پس از آن را بر عهده دارد، asl status --datasets گزارش پوشش و تازگی دادهها را به تفکیک هر مجموعه داده ارائه میدهد و asl serve یک داشبورد فقطخواندنی را روی نشانی 127.0.0.1:8787 در دسترس قرار میدهد.
این مخزن هیچگونه دادهای را به همراه ندارد. تمامی فایلهای Parquet روی دستگاه شما ساخته میشوند و هر ردیف دارای یک تبارنامه (lineage) در سطح ردیف است که ثبت میکند کدام منبع آن را تولید کرده و چه زمانی دریافت شده است.
این 39 مجموعه داده شامل چه مواردی هستند؟
این دادهها بهصورت لایهبندیشده و از دادههای مرجع به سمت بیرون سازماندهی شدهاند: 36 جدولِ پردازششده و 3 جدولِ مشتقشده.
- مرجع: ابزارهای مالی، تقویم معاملاتی پوششدهنده سالهای 2016 تا 2027، وضعیت معاملاتی.
- دادههای بازار: نمودارهای روزانه، نمودارهای شاخص، نمودارهای 1 و 5 دقیقهای، تیکهای معاملاتی (trade ticks)، نمودارهای کالا، ضرایب تعدیل، رویدادهای حذف از فهرست (delisting).
- رویدادهای شرکتی: اقدامات شرکتی، شاخص اطلاعیهها، برنامه زمانی افشای سود.
- بنیادین و ارزشگذاری: اقلام صورتهای مالی، معیارهای ارزشگذاری، اجماع تحلیلگران.
- جریان سرمایه: جریان صندوقها، معاملات اعتباری (margin trading)، جریانها و داراییهای شمالی (northbound)، افشای سفارشهای بزرگ در تابلوی دراگون-تایگر، معاملات بلوکی، داراییهای نهادی.
- ساختار و صنعت: اعضای بخشها، اجزای شاخص، اعضای صنعت، شاخص صنعت.
- کلان: شاخصهای کلان، پهنای بازار (market breadth)، تقویم اقتصادی.
- احساسات و چرخش: امتیازات احساسات، رتبه داغ (hot rank)، نمودارهای بخش، جریان سرمایه بخش، عناوین خبری، جریان اخبار فوری.
- ریسک و انطباق: برنامه زمانی آزادسازی سهام (share unlock)، رویدادهای نظارتی.
جایگاه هر مجموعه داده نشاندهنده اولویتهای نویسنده است. ضرایب تعدیل و رویدادهای حذف از فهرست در لایه دادههای بازار و در کنار نمودارهای روزانه قرار گرفتهاند، نه در پیوست؛ این نوع چیدمان، نیمی از ارزش این پروژه برای هر کسی است که ایدههای خود را بر اساس دادههای تاریخی آزمون میکند.
چگونه یک دریاچه داده محلی با سوگیری بقا برخورد میکند
سوگیری بقا زمانی رخ میدهد که جامعه آماری یک مطالعه تنها از نامهایی تشکیل شده باشد که امروزه همچنان در فهرستها حضور دارند. هر شرکتی که ادغام شده، خصوصی شده یا از فهرست حذف شده باشد، بیسروصدا غایب است و نامهایی که ناپدید میشوند بهندرت از برندگان هستند.
انبار داده ما میتواند این خلأ را برای بازار ایالات متحده اندازهگیری کند؛ همان محاسبات با الفبایی متفاوت. برای هر سال، تمام نمادهایی را که در هفته دوم مارس یک «بار» دقیقهای ثبت کردهاند در نظر بگیرید، سپس بررسی کنید کدامیک از آنها در دو هفته پایانی ژوئیه 2026 همچنان در حال ثبت قیمت بودهاند:
کد دقیق 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 yearاز میان 8101 نماد در حال معامله در آن هفته در 2016، تعداد 50.1% نماد در اواخر ژوئیه 2026 همچنان روی نوار قیمت حضور داشتند و 4040 نماد دیگر حذف شده بودند. گروه 2025 به صورت 86.7% خوانده میشود. اگر یک غربالگری مبتنی بر فهرستهای امروز را در طول آن 10 سال به عقب اجرا کنید، با گذشت زمان سهم بزرگتری از بازار را از دست میدهد.
فرض رایج این است که نامهای مفقودشده همگی سهام پنی (ارزانقیمت) بودهاند. دستهبندی گروه مارس 2021 بر اساس میانگین حجم دلاری روزانه در آن ماه، خلاف این را نشان میدهد:
کد دقیق 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 بیشترین سهم را از دست داد، یعنی 57.5% از 3968 نماد. فعالترین گروه نیز مصون نبود: 3.4% از 89 نمادی که در مارس 2021 روزانه $1B or more معامله میشدند، تا اواخر ژوئیه 2026 از بازار خارج شده بودند. ادغامها، خصوصیسازیها، ورشکستگیها و خروج از شاخصها همگی در جدول قیمت به یک شکل پایان مییابند: ردیفها متوقف میشوند.
پروژه ashare-lake با این موضوع بهعنوان یک مسئله درجهیک برخورد میکند. مجموعه داده ابزارها، نمادهای حذفشده را بهجای فیلتر کردن و محدود شدن به نمادهای فعال، حفظ میکند؛ یک جدول delisting_events نحوه پایان کار هر نام حذفشده را ثبت میکند و universe="all_a" در API پایتون، یک تصویر لحظهای تاریخی را بازیابی میکند که شامل آنها نیز میشود. مستندات خودِ پروژه گزارش میدهد که بین یک بکتستِ مبتنی بر «فقط بازماندگان» و یک بکتستِ شامل «حذفشدهها» در بازه 2016 تا 2021، تقریباً شکافی دوبرابری وجود دارد. این تصویر آینهایِ همان دامی است که در یادداشتهای ما درباره سوگیری نگاه به آینده در بکتست آمده است: جهانی که بیسروصدا از آینده خبر دارد.
خوانشهای مقطعی (Point-in-time)
load("financial_statement_items", as_of="2018-04-30") آخرین نسخه از هر قلم اطلاعاتی اعلامشده در آن تاریخ یا پیش از آن را بازمیگرداند، نه عددی که بعداً اصلاح شده است. «بارها» دارای یک آرگومان adjust هستند: hfq برای تعدیل معکوس، qfq برای نرمالسازی در داخل پنجره پرسوجو، یا قیمتهای خام. عاملی که بر اساس اعدادی برازش شود که بازار هنوز منتشر نکرده است، هیچچیز را اندازهگیری نمیکند؛ این اولین نکتهای است که باید در هر خط لوله عامل آلفای تولیدشده توسط LLM بررسی شود.
ثبت بهعنوان یک سرور MCP
پروتکل زمینه مدل (Model Context Protocol) روشی است که یک عامل (Agent) از طریق آن ابزارها را فراخوانی میکند. asl mcp از طریق stdio با این پروتکل ارتباط برقرار میکند و کلاینت، فرآیند مربوطه را اجرا مینماید:
claude mcp add ashare-lake -- asl mcp --config /abs/path/to/ashare-lake.toml- هر کلاینت MCP دیگر نیز از همین دو مؤلفه استفاده میکند:
aslبهعنوان دستور (command) وmcp --configبههمراه یک مسیر مطلق (absolute path) بهعنوان آرگومانها. مسیر باید مطلق باشد، زیرا کلاینت ممکن است فرآیند را از هر پوشهای آغاز کند.
شش ابزار در دسترس قرار میگیرند که بهجای دستهبندی بر اساس مجموعه داده، بر اساس پرسش سازماندهی شدهاند: describe_lake برای آگاهی از موجودیها و نحوه خواندن آنها، resolve_symbol برای تبدیل نام به کد (شامل نامهای حذفشده از فهرست)، query_bars، query_fundamentals با آرگومان as_of، query_dataset برای سایر موارد، و run_sql برای اجرای یک دستور SELECT تکخطی و فقطخواندنی در DuckDB روی مجموعهدادهها. یک پرچم --live به سرور اجازه میدهد تا بدون نوشتن در دریاچه داده (lake)، به جستجوی نمادها و دادههای روزانه تعدیلنشده از منبع بالادستی پاسخ دهد.
محدودیتهایی که باید پیش از هر چیز بدانید
- فقط سهام A (A-shares). شامل هنگکنگ، فهرستهای ایالات متحده یا هیچ دارایی خارج از سرزمین اصلی چین نمیشود.
- یک پروژه شخصی. به «ایشو»ها و «پولریکوئست»ها بر اساس بهترین تلاش رسیدگی میشود و مستندات بهصراحت بیان میکنند که هیچ تضمینی برای در دسترس بودن وجود ندارد: سایتهای بالادستی تغییر میکنند و ممکن است یک IP مسدود شود که این امر تا زمانی که شخصی آن را اصلاح نکند، فرایند دریافت داده را متوقف میکند.
- مجوز Apache 2.0 کد را پوشش میدهد، نه دادهها را. هر منبع بالادستی شرایط خاص خود را حفظ میکند و نگهداریکننده پروژه هیچ حقی برای بازنشر یا فروش مجدد فایلهای Parquet که میسازید، اعطا نمیکند. پیش از هرگونه استفاده تجاری، شرایط منبع را مطالعه کنید.
- برای منابعی که این ابزار میخواند، نیازی به حساب کاربری یا توکن نیست؛ این همان ویژگی جذاب و در عین حال شکننده پروژه است.
- پشتیبانی از ویندوز در نسخه 0.3.0 اضافه شد و حداقل نسخه پایتون در نسخه 0.3.1 به 3.10 ارتقا یافت.
منبع این حقایق پروژه
نسخه 0.5.0، شش تاریخ انتشار و حداقل نسخه پایتون از تاریخچه انتشار PyPI پروژه و CHANGELOG در تاریخ 4 اوت 2026 استخراج شدهاند. کاتالوگ مجموعه دادهها، رفتار حذف از فهرست (delisting) و مقطع زمانی (point-in-time)، پرچمهای CLI، فهرست ابزارهای MCP، و متن مربوط به مجوزها و پشتیبانی از مستندات مخزن استخراج شدهاند: docs/datasets/catalog.md، docs/reference/cli.md، docs/reference/mcp.md و docs/legal-and-data-sources.md. نرمافزار سریعتر از مطالب وبلاگ تغییر میکند، بنابراین برای نسخهای که نصب میکنید، مستندات را بررسی کنید. دو پنل بقا (survivorship panels) نمادهای ایالات متحده را در انبار دادههای خودمان اندازهگیری میکنند، نه فهرستهای چینی، و بهعنوان نمونهای از این مکانیسم عمل میکنند، نه بهعنوان معیاری برای بازار سهام A.
پرسشهای متداول
آیا برای ساخت یک دریاچه داده (Data Lake) محلی از سهام A-share به کلید API نیاز دارم؟
خیر. منابع بالادستی که این ابزار از آنها استفاده میکند نیازی به ثبتنام یا توکن ندارند و دریاچه داده نیز روی دستگاه خودتان مستقر میشود. هر منبع شرایط استفاده خاص خود را دارد که پیش از هرگونه فعالیت تجاری باید مدنظر قرار گیرد.
فرآیند تکمیل دادههای گذشته (Backfill) در ashare-lake چقدر زمان میبرد؟
مستندات نشان میدهد که تکمیل تاریخچه کامل، چندین ساعت زمان برده و چندین گیگابایت فضا روی دیسک اشغال میکند؛ ضمن اینکه در تمام این مدت به یک اتصال فعال به میزبان دادههای بالادستی نیاز است. asl init --profile quick دادههای سه سال اخیر را در عرض چند دقیقه بازیابی میکند و همچنان شامل نمادهایی است که از آن زمان تاکنون از فهرست بورس حذف (Delist) شدهاند.
آیا دریاچه داده محلی A-share شامل سهام حذفشده از فهرست بورس میشود؟
بله. نمادهای حذفشده در مجموعه داده ابزارها باقی میمانند، جدول delisting_events نحوه خروج هر نماد را ثبت میکند و universe="all_a" یک تصویر لحظهای (Snapshot) تاریخی ایجاد میکند که شامل این نمادها نیز هست. بررسی ما روی بازار ایالات متحده در بالا نشان میدهد که نادیده گرفتن این نمادها و تمرکز صرف بر شرکتهای فعال، چه حجمی از دادهها را از دست میدهد.
آیا یک عامل هوش مصنوعی (AI Agent) میتواند مستقیماً از ashare-lake پرسوجو کند؟
بله. asl mcp شش ابزار را از طریق پروتکل زمینه مدل (Model Context Protocol) ارائه میدهد که یکی از آنها ابزار SQL فقطخواندنی است؛ بنابراین عامل هوش مصنوعی بهجای اسکرپ کردن، مستقیماً از فایلهای Parquet محلی پرسوجو میکند. آن را با claude mcp add ashare-lake -- asl mcp --config /abs/path/to/ashare-lake.toml ثبت کنید.
آیا ashare-lake جایگزینی برای AkShare یا Baostock است؟
خیر. این پروژه در سطحی بالاتر از آنها قرار میگیرد. آن کتابخانهها دادهها را از منابع بالادستی دریافت میکنند، اما این پروژه دادههای دریافتی را ذخیره، نسخهبندی و با هم تطبیق میدهد تا به فایلهای Parquet سازمانیافته با تبارنامه (Lineage) در سطح ردیف و یک قرارداد مشخص برای هر مجموعه داده تبدیل شوند.
تمامی ارقام فوق حاصل پرسوجوهای ذخیرهشده و نسخهبندیشده روی دادههای واقعی بازار هستند. برای مشاهده کد SQL هر پنل، آن را باز کنید یا همین بررسی بقای نمادها (Survivorship check) را برای مجموعه دادههای خود در ترمینال Strasmore اجرا کنید.