Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor · · Updated 2026-08-08

Lokalny zbiór danych A-share dla agentów AI

Projekt ashare-lake umożliwia budowę lokalnego zbioru danych A-share. Oferuje trzydzieści dziewięć zestawów danych, obsługę spółek wycofanych oraz serwer MCP dla agentów AI.

Lokalny zbiór danych typu A-share

Lokalny zbiór danych typu A-share to historia chińskiego rynku akcji kontynentalnych zapisana na własnym dysku w formie kolumnowych plików Parquet. Dane te można odczytywać za pomocą DuckDB lub Polars, co eliminuje konieczność korzystania z zewnętrznych punktów końcowych dostawców, które wymagają pobierania danych strona po stronie. ashare-lake to projekt open-source służący do tworzenia takiego zbioru, obejmujący codzienny proces aktualizacji oraz serwer Model Context Protocol, który umożliwia agentom AI wykonywanie zapytań do bazy. Dwa założenia projektowe zasługują na uwagę: zachowywanie nazw spółek wycofanych z obrotu oraz możliwość odczytu danych fundamentalnych według stanu na wybrany dzień w przeszłości.

Dlaczego agent AI potrzebuje lokalnego zbioru danych typu data lake dla akcji typu A-share

Agent badający chińskie akcje bez lokalnej kopii danych ma dwie drogi. Może przeszukiwać strony finansowe, marnując okno kontekstowe na kod HTML i generując liczby, których nikt nie będzie w stanie zweryfikować w przyszłym miesiącu. Może też korzystać z usług dostawcy wymagającego rejestracji, który ogranicza liczbę wierszy i przypisuje każdy wynik do konkretnego konta.

Skala jest czynnikiem, który bywa niedoceniany. Nasze własne repozytorium przechowuje dane z rynku amerykańskiego z rozdzielczością minutową, a typowy tydzień wygląda następująco:

ZapytanieTydzień notowań minutowych w USA: symbole i słupki na sesję, 20–24 lipca 2026 r.
Dokładny kod SQL dla każdej liczby
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
Run this yourself

W dniu Jul 20 taśma wygenerowała 1.79 milionów słupków minutowych dla 11737 symboli, a cztery pozostałe sesje w panelu powtarzają ten schemat. Jeden rynek krajowy, jeden tydzień, jedna rozdzielczość. Dekada słupków dziennych, danych fundamentalnych, składów indeksów oraz rejestrów przepływów pieniężnych dla innego rynku ma taką samą strukturę, a pobieranie ich przez HTTP wyczerpuje zasoby agenta.

Lokalny zbiór danych typu data lake zmienia dwie rzeczy jednocześnie. Odczyty stają się skanowaniem plików, a nie limitem kwotowym, a zapytanie napisane dzisiaj zwraca te same wiersze za sześć miesięcy, co jest niezbędne, aby backtest był weryfikowalny. Nasze notatki na temat umiejętności pracy z danymi rynkowymi dla agentów AI oraz interfejsu SQL API dla danych rynkowych przedstawiają ten sam argument w odniesieniu do danych z rynku amerykańskiego.

Instalacja i przypięcie wersji

Wymagany Python w wersji 3.10 lub nowszej. Należy przypiąć wersję: między 27 lipca a 2 sierpnia 2026 roku ukazało się sześć wydań, a nieprzypięta instalacja w skrypcie konfiguracyjnym agenta jest zmiennym celem. Kod znajduje się w rootSunc/ashare-lake na licencji Apache 2.0.

  • pip install ashare-lake==0.5.0 instaluje bieżące wydanie z początku sierpnia 2026 roku.
  • asl --version wyświetla zainstalowaną kompilację.
  • asl config init --data-root /path/to/ashare-lake zapisuje spakowany plik TOML z uzupełnionym katalogiem głównym danych; pobieranie repozytorium nie jest wymagane. --config ustawia ścieżkę wyjściową, --force nadpisuje plik.
  • asl doctor uruchamia testy w trybie offline, przed rozpoczęciem transferu danych.
  • asl servers test sonduje zewnętrzne serwery notowań. asl sources sonduje każde źródło z parametrem --vantage równym cn, overseas lub local.

W tym miejscu należy przerwać. Kolejnym poleceniem jest uzupełnienie danych historycznych (backfill), którego nie należy uruchamiać w trakcie czytania dokumentacji.

Funkcja uzupełniania danych

asl init tworzy strukturę katalogów i uzupełnia historię. Dokumentacja projektu wskazuje, że pełny przebieg procesu zajmuje wiele godzin czasu rzeczywistego i wymaga kilku GB miejsca na dysku, a ponadto wymaga aktywnego połączenia z nadrzędnym serwerem notowań Tongdaxin, co weryfikuje asl servers test. asl init --profile quick obejmuje natomiast ostatnie trzy lata, wykonuje się w kilka minut i zachowuje wszystkie nazwy, które były przedmiotem obrotu w tym okresie, w tym spółki, które wycofały się już z rynku. asl run daily to zadanie przyrostowe wykonywane w kolejnym kroku, asl status --datasets raportuje zakres i aktualność danych dla poszczególnych zbiorów, a asl serve uruchamia pulpit nawigacyjny w trybie tylko do odczytu pod adresem 127.0.0.1:8787.

Repozytorium nie zawiera żadnych danych. Każdy plik w formacie Parquet jest tworzony na komputerze użytkownika, przy czym każdy wiersz posiada metadane dotyczące pochodzenia, wskazujące źródło oraz czas pobrania informacji.

Czym jest trzydzieści dziewięć zbiorów danych?

Są one ułożone warstwowo, poczynając od danych referencyjnych: trzydzieści sześć tabel przygotowanych przez ekspertów oraz trzy tabele pochodne.

  • Dane referencyjne: instrumenty, kalendarz sesji obejmujący lata od 2016 do 2027, status notowań.
  • Dane rynkowe: notowania dzienne, notowania indeksów, notowania minutowe i pięciominutowe, transakcje jednostkowe (ticks), notowania towarów, współczynniki korekcyjne, zdarzenia związane z wycofaniem z obrotu.
  • Zdarzenia korporacyjne: działania korporacyjne, indeks komunikatów, harmonogram publikacji wyników finansowych.
  • Fundamenty i wycena: pozycje sprawozdań finansowych, wskaźniki wyceny, konsensus analityków.
  • Przepływy kapitałowe: przepływy funduszy, handel z wykorzystaniem depozytu zabezpieczającego (margin trading), przepływy i stany posiadania typu northbound, zestawienia dużych zleceń (dragon-tiger board), transakcje pakietowe, udziały instytucjonalne.
  • Struktura i branża: członkowie sektorów, składniki indeksów, członkowie branż, indeksy branżowe.
  • Makroekonomia: wskaźniki makroekonomiczne, szerokość rynku, kalendarz ekonomiczny.
  • Sentyment i rotacja: wyniki sentymentu, ranking popularności, notowania sektorowe, przepływy kapitałowe w sektorach, nagłówki wiadomości, serwis informacyjny typu flash.
  • Ryzyko i zgodność: harmonogram odblokowania akcji, zdarzenia regulacyjne.

Miejsce danego zbioru w strukturze wskazuje na priorytety autora. Współczynniki korekcyjne oraz zdarzenia związane z wycofaniem z obrotu znajdują się w warstwie danych rynkowych obok notowań dziennych, a nie w załączniku; to właśnie to rozmieszczenie stanowi połowę wartości projektu dla każdego, kto testuje strategie w oparciu o dane historyczne.

W jaki sposób lokalny zbiór danych radzi sobie z błędem przeżywalności

Błąd przeżywalności występuje, gdy zakres badania ograniczony jest wyłącznie do podmiotów notowanych w dniu dzisiejszym. Każda spółka, która została przejęta, wycofana z obrotu lub sprywatyzowana, jest pomijana, a podmioty, które znikają z rynku, rzadko należą do grona zwycięzców.

Nasz magazyn danych pozwala oszacować skalę tego zjawiska dla rynku amerykańskiego, stosując tę samą arytmetykę w innym ujęciu. Dla każdego roku należy wyodrębnić wszystkie symbole, dla których odnotowano transakcje w drugim tygodniu marca, a następnie sprawdzić, które z nich były nadal notowane w ostatnich dwóch tygodniach lipca 2026 roku:

ZapytanieWskaźnik przetrwania: marcowe kohorty symboli w USA notowane pod koniec lipca 2026 r.
Dokładny kod SQL dla każdej liczby
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
Run this yourself

Spośród 8101 symboli notowanych w tamtym tygodniu w 2016, 50.1% nadal znajdowało się w obrocie pod koniec lipca 2026 roku, a 4040 zostało wycofanych. Kohorta 2025 prezentuje się następująco: 86.7%. Przeprowadzenie analizy wstecznej w oparciu o dzisiejszą listę notowań dla tych 10 lat powoduje, że wraz z upływem czasu pomijana jest coraz większa część rynku.

Powszechnie przyjmuje się, że znikające podmioty to wyłącznie spółki typu penny stocks. Podział kohorty z marca 2021 roku na grupy według średniego dziennego wolumenu obrotu w ujęciu dolarowym wskazuje na coś innego:

ZapytanieSymbole wycofane z obrotu: zestawienie marcowych symboli z 2021 r. według dziennego wolumenu w USD ze stanem na koniec lipca 2026 r.
Dokładny kod SQL dla każdej liczby
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)
Run this yourself

Grupa under $1M odnotowała największy spadek, tracąc 57.5% z 3968 nazw. Najbardziej aktywne podmioty również nie były zwolnione z tego procesu: 3.4% z 89 symboli, dla których średni dzienny obrót w marcu 2021 roku wynosił $1B or more, zniknęło z rynku do końca lipca 2026 roku. Fuzje, prywatyzacje, upadłości oraz wykluczenia z indeksów kończą się w tabelach cenowych w ten sam sposób: zaprzestaniem publikacji notowań.

ashare-lake traktuje to jako kluczowy problem. Zbiór danych o instrumentach zachowuje symbole wycofane z obrotu, zamiast ograniczać się do aktywnych, tabela delisting_events rejestruje sposób zakończenia notowań każdego z nich, a universe="all_a" w interfejsie API języka Python pozwala na uzyskanie historycznego obrazu rynku uwzględniającego te podmioty. Dokumentacja projektu wskazuje na dwukrotną różnicę w wynikach między backtestem uwzględniającym tylko spółki „przeżywające” a takim, który uwzględnia wycofane podmioty w okresie od 2016 do 2021 roku. Jest to lustrzane odbicie pułapki opisanej w naszych notatkach na temat błędu wyprzedzenia w backtestingu: uniwersum, które dysponuje wiedzą o przyszłości.

Odczyty typu point-in-time

load("financial_statement_items", as_of="2018-04-30") zwraca najnowszą wersję każdej pozycji raportowanej w dniu lub przed wskazaną datą, a nie wartości skorygowane w późniejszym czasie. Notowania posiadają argument adjust: hfq dla korekty wstecznej, qfq dla wartości znormalizowanych wewnątrz okna zapytania lub ceny surowe. Czynnik dopasowany do danych, których rynek jeszcze nie opublikował, nie mierzy niczego, co jest pierwszą rzeczą do sprawdzenia w każdym potoku czynników alfa generowanych przez LLM.

Rejestracja jako serwer MCP

Model Context Protocol stanowi sposób, w jaki agent uzyskuje dostęp do narzędzi. asl mcp obsługuje ten protokół za pośrednictwem stdio, a klient uruchamia proces:

  • claude mcp add ashare-lake -- asl mcp --config /abs/path/to/ashare-lake.toml
  • Każdy inny klient MCP wymaga tych samych dwóch elementów: asl jako komendy oraz mcp --config wraz ze ścieżką bezwzględną jako argumentów. Ścieżka musi być bezwzględna, ponieważ klient może uruchomić proces z dowolnego katalogu.

Dostępnych jest sześć narzędzi, zorganizowanych według pytań, a nie zbiorów danych: describe_lake służy do sprawdzania zasobów i sposobu ich odczytu, resolve_symbol mapuje nazwę na kod (w tym nazwy wycofane z obrotu), query_bars, query_fundamentals z argumentem as_of, query_dataset dla pozostałych danych oraz run_sql do pojedynczych zapytań SELECT typu read-only w DuckDB dla różnych zbiorów danych. Flaga --live umożliwia serwerowi odpowiadanie na wyszukiwania symboli oraz pobieranie nieskorygowanych notowań dziennych ze źródła nadrzędnego bez zapisu w jeziorze danych (lake).

Ograniczenia, o których warto wiedzieć

  • Wyłącznie akcje typu A. Brak notowań z Hongkongu, USA oraz jakichkolwiek rynków poza Chinami kontynentalnymi.
  • Projekt osobisty. Zgłoszenia problemów (issues) oraz propozycje zmian (pull requests) są obsługiwane w miarę możliwości, a dokumentacja wyraźnie wskazuje na brak gwarancji dostępności: źródła zewnętrzne ulegają zmianom, a adres IP może zostać zablokowany, co wstrzymuje pobieranie danych do czasu wprowadzenia poprawki.
  • Licencja Apache 2.0 obejmuje kod, a nie dane. Każde źródło zewnętrzne posiada własne warunki użytkowania, a autor projektu nie udziela prawa do redystrybucji ani odsprzedaży wygenerowanych plików w formacie Parquet. Przed jakimkolwiek wykorzystaniem komercyjnym należy zapoznać się z regulaminami źródeł.
  • Do obsługi źródeł nie jest wymagane konto ani token, co stanowi zarówno o atrakcyjności, jak i o kruchości rozwiązania.
  • Obsługa systemu Windows została wprowadzona w wersji 0.3.0, a minimalna wymagana wersja języka Python została podniesiona do 3.10 w wersji 0.3.1.
Źródła informacji o projekcie

Wersja 0.5.0, sześć dat wydań oraz minimalna wersja języka Python pochodzą z historii wydań PyPI oraz pliku CHANGELOG projektu, odczytanych 4 sierpnia 2026 roku. Katalog zbiorów danych, zachowanie w przypadku wycofania z obrotu (delisting) oraz dane historyczne (point-in-time), flagi CLI, lista narzędzi MCP, a także zapisy dotyczące licencji i wsparcia pochodzą z dokumentacji repozytorium: docs/datasets/catalog.md, docs/reference/cli.md, docs/reference/mcp.md oraz docs/legal-and-data-sources.md. Oprogramowanie rozwija się szybciej niż publikacje, dlatego należy sprawdzać dokumentację dla instalowanej wersji. Dwa panele dotyczące przeżywalności (survivorship) mierzą symbole z rynku USA w naszym własnym magazynie danych, a nie notowania chińskie, i stanowią ilustrację mechanizmu, a nie pomiar rynku akcji typu A.

FAQ

Czy do budowy lokalnego jeziora danych (data lake) dla akcji typu A wymagany jest klucz API?

W tym przypadku nie. Źródła danych, z których korzysta rozwiązanie, nie wymagają rejestracji ani tokenów, a samo jezioro danych znajduje się na lokalnej maszynie. Każde źródło posiada własne warunki użytkowania, które należy zweryfikować przed rozpoczęciem jakichkolwiek prac komercyjnych.

Ile czasu zajmuje uzupełnienie danych historycznych w ashare-lake?

Zgodnie z dokumentacją, pełne uzupełnienie historii zajmuje kilka godzin czasu rzeczywistego i wymaga kilku GB miejsca na dysku, przy założeniu stałego połączenia z hostem dostarczającym notowania. asl init --profile quick pozwala na pobranie danych z ostatnich trzech lat w ciągu kilku minut i uwzględnia również spółki, które zostały wycofane z obrotu.

Czy lokalne jezioro danych dla akcji typu A zawiera spółki wycofane z obrotu?

Tak. Symbole spółek wycofanych pozostają w zbiorze instrumentów, tabela delisting_events rejestruje sposób zakończenia notowań każdej spółki, a universe="all_a" tworzy historyczny obraz danych uwzględniający te podmioty. Nasze powyższe pomiary dla rynku amerykańskiego pokazują skalę danych, które są pomijane w zbiorach ograniczonych wyłącznie do spółek notowanych.

Czy agent AI może bezpośrednio odpytywać ashare-lake?

Tak. asl mcp udostępnia sześć narzędzi w ramach protokołu Model Context Protocol, w tym narzędzie SQL typu read-only, dzięki czemu agent odpytuje lokalne pliki Parquet zamiast przeprowadzać scraping. Narzędzie należy zarejestrować za pomocą claude mcp add ashare-lake -- asl mcp --config /abs/path/to/ashare-lake.toml.

Czy ashare-lake zastępuje biblioteki AkShare lub Baostock?

Nie. Rozwiązanie to stanowi warstwę nadrzędną. Wspomniane biblioteki pobierają dane ze źródeł zewnętrznych, natomiast ten projekt przechowuje, wersjonuje i uzgadnia pobrane dane w ustrukturyzowane pliki Parquet z zachowaniem pochodzenia danych na poziomie wiersza oraz ujednoliconym kontraktem dla każdego zbioru.


Każda z powyższych liczb pochodzi z zapisanego, wersjonowanego zapytania opartego na rzeczywistych danych rynkowych. Rozwiń dowolny panel, aby wyświetlić kod SQL lub przeprowadź własną weryfikację przeżywalności spółek w swoim uniwersum na terminalu Strasmore.

#market-data#mcp#a-shares#open-source#ai-agents