5. ローカル データ ソース — DataSource オブジェクト

ローカル データ ソースは、qteasy のデータ管理機能の中核です。 qteasy で使用するには、まずすべてのデータをダウンロードしてローカル データ ソースに保存する必要があります。 qteasy は、DataSource オブジェクトを使用してローカル データ ソースを管理します。ローカル データ ソースはデータベースに似ており、一連の事前定義されたデータ テーブルが含まれています。 DataSource クラスは、データの読み取り、更新、削除、クエリなど、データ テーブル内のデータを管理するための一連の API を提供します。

新しい DataSource オブジェクトを作成するには、次のコマンドを使用できます。

>>> import qteasy as qt
>>> ds = qt.DataSource()

DataSource オブジェクトを印刷すると、その最も基本的なプロパティを表示できます。

>>> print(ds)
file://csv@qt_root/data/

DataSource の出力された文字列 file://csv@qt_root/data/ から、その基本的なプロパティがわかります。

印刷結果には、データ ソース オブジェクトに関する基本情報が含まれています。

  • file: – データ ソースのタイプ。 qteasy は、ファイルベースとデータベースベースの 2 種類のデータ ソースをサポートします。 file は、データ ソース内のすべてのデータ テーブルがファイルとしてディスクに保存されていることを意味します。同様に、データを mysql データベースに保存することもできます。この場合、データ ソース タイプ コードは db です。

  • csv: – データファイルの保存形式。 qteasy は、データ ファイルをさまざまな形式でディスクに保存できます。最も基本的な形式は csv ですが、ユーザーはさまざまなパフォーマンスの好みに合わせてデータを hdf および fth (feather) ファイルとして保存することもできます。

  • qt_root/data/: – データファイルを保存するパス。 qt_root は、qteasy のインストール ルート パスを表します。デフォルトでは、すべてのデータ ファイルはルート ディレクトリの下の /data/ サブディレクトリに保存されます。

同様に、データ ストレージ タイプ「データベース」でデータ ソース オブジェクトを作成し、その基本プロパティを表示できます。ただし、「データベース」タイプのデータ ソースを作成する場合は、接続先の MySQL データベースのホスト名、ユーザー名、パスワード、データベース名を指定する必要があります。

>>> ds_db = qt.DataSource(source_type='database', host='localhost', user='您的用户名', password='您的密码', db_name='test_db')
>>> print(ds_db)
db:mysql://localhost@3306/test_db

同様に、印刷結果にはデータ ソースに関する基本情報が含まれます。

  • db:mysql – データ ソース タイプは MySQL データベースです。すべてのデータ テーブルはこのデータベースに保存されます。

  • localhost – データベースのホスト名

  • 3306 – データベース接続ポート

  • test_db – データベース名。名前を指定しない場合、デフォルトのデータベースは qt_db ですが、このデータベースは事前に作成する必要があります。

異なるデータ ソース オブジェクトは、異なるストレージ メソッドとストレージ パスを持っていても、相互に関係がなく、相互のデータに干渉しません。ただし、2 つのデータ ソースが同じパスを指し、同じファイル タイプを持つ場合、重複したデータが保存されます。

データ ソースのさらに基本的なプロパティを表示するには、データ ソース オブジェクトのいくつかのプロパティにアクセスします。

>>> print(ds.source_type)  # 数据源的类型
file
>>> print(ds_db.source_type)
db
>>> print(ds.file_type, ds.file_path)  # 数据源的文件类型和存储路径
csv /Users/jackie/Projects/qteasy/qteasy/data/
>>> print(ds.connection_type, ds_db.connection_type)  # 数据源的连接类型
file://csv@qt_root/data/ db:mysql://localhost@3306/test_db

5.1. デフォルトのデータソース

qteasy には、ユーザーが手動で作成する必要のないデフォルトのデータ ソースが組み込まれています。デフォルトでは、すべてのデータはこのデフォルトのデータ ソースに保存され、そこから読み取られます。ユーザーは、qteasy の構成ファイルを通じてこのデータ ソースのパラメーターを構成でき、データ ソースが正しいパスを指していること、または正しいデータベースへのログインに正しいユーザー名が使用されていることを確認できます。組み込みのデフォルト データ ソースのプロパティは、次の方法を使用して表示できます。

>>> print(qt.QT_DATA_SOURCE)
db:mysql://www.qteasy.online@3306/ts_db

5.2. データテーブルを表示する

データ ソース オブジェクトの基本プロパティを理解したら、次のステップは、データ ソースに格納されているデータをさらに理解することです。

データ ソース内のデータ テーブルはすべて事前定義されています。各データ テーブルには、異なる種類のデータが格納されます。このデータは、上海および深センの株式市場および先物市場の株式、指数、ファンド、先物、オプションなどのさまざまな投資商品の基本情報、Kラインデータ、上場企業業績レポート、マクロ経済データなどの膨大なデータを網羅しています。データテーブルの完全なリストについては、次の章を参照してください。ここでは主に各種データテーブルの基本情報やデータの見方を紹介します。

データ ソース内のテーブルのリストは、データ ソースの all_tables プロパティを通じて取得できます。このプロパティは、データ ソース内のすべての定義済みテーブルを含むリスト オブジェクトを返します。ただし、多くのテーブルはデータ ソースで定義されていますが、それらには基本的な定義しかなく、ヘッダー情報、フィールド名、フィールドの意味、およびデータ型がすべて定義されていることを明確にすることが重要です。新しく作成されたデータ ソースには通常、データが含まれていない空のテーブルがあります。データ ソース内のどのテーブルに既にデータが含まれているかを確認するには、get_table_info() 関数を使用する必要があります。

>>> print('All tables in datasource:', len(ds.all_tables))
All tables in datasource: 108
>>> print('Some tables:', ds.all_tables[5:15])
Some tables: ['hk_trade_calendar', 'us_trade_calendar', 'stock_basic', 'hk_stock_basic', 'us_stock_basic', 'stock_names', 'stock_company', 'stk_managers', 'new_share', 'money_flow']

ご覧のとおり、qteasy の現在のバージョンでは 108 個のデータ テーブルが事前定義されており、その一部には stock_basic などの名前が付いています。

現在のデータ ソース内の特定のテーブルの詳細 (その定義やテーブルにデータが含まれているかどうかなど) を表示するには、get_table_info() メソッドを使用します。

>>> info = ds.get_table_info('stock_basic')
<stock_basic>--<股票基本信息>
852KB/5K records on disc
primary keys: 
----------------------------------------
1:   ts_code:  <5396> entries
     starts: 000001.SZ, end: 920128.BJ

columns of table:
------------------------------------
        columns        dtypes remarks
0       ts_code    varchar(9)    证券代码
1        symbol    varchar(6)    股票代码
2          name   varchar(20)    股票名称
3          area   varchar(10)      地域
4      industry   varchar(10)    所属行业
5      fullname   varchar(50)    股票全称
6        enname  varchar(120)    英文全称
7       cnspell   varchar(40)    拼音缩写
8        market    varchar(6)    市场类型
9      exchange    varchar(6)   交易所代码
10    curr_type    varchar(6)    交易货币
11  list_status    varchar(4)    上市状态
12    list_date          date    上市日期
13  delist_date          date    退市日期
14        is_hs    varchar(2)  是否沪深港通

印刷される情報には、テーブル名、説明、フィールド定義、データ型が含まれます。

データ テーブルに既にデータが入力されている場合は、テーブルの現在のサイズが表示されることに注意してください。上の例では、いくつかの重要な情報を以下に説明します。

  • 852KB/5K records on disc – これは、テーブルが約 852KB のディスク領域を占有し、約 5000 行のデータが含まれていることを示します。

  • primary keys – データの主キー列を表示します。ここでは、ts_code 列がテーブルの主キーであり、この列には約 5396 個の個別のレコードがあることを示しています。テーブルに複数の主キーがある場合、各主キー列がそのフィールドのデータ範囲とともに個別にリストされます。たとえば、上記の例では、ts_code 列のデータ範囲は 000001.SZ から 920128.BJ までとなっており、基本株式情報テーブルにはコード 000001 から 920128 までの 5,000 銘柄以上の情報が含まれていることがわかります。

  • columns of table – データ テーブルのフィールド定義 (テーブルの schema) が表示されます。各列の名前 columns、データ型 dtypes、および説明情報 remarks がリストされます。

さらに、get_table_info() メソッドは、テーブルに関する情報も含まれる dict を返します。この情報は印刷して、上記で説明したフォーマット済みの情報と比較することで、理解を深めることができます。

>>> print(info)
{'table': 'stock_basic', 'table_exists': True, 'table_size': '852KB', 'table_rows': '5K', 'primary_key1': 'ts_code', 'pk_records1': 5396, 'pk_min1': '000001.SZ', 'pk_max1': '920128.BJ', 'primary_key2': None, 'pk_records2': None, 'pk_min2': None, 'pk_max2': None}

5.3. データソースに関する全体的な情報を表示する

上記のメソッドを使用して各テーブルを検査します。 overview() は、DataSource 全体を要約します。

>>> overview = ds.overview()
Analyzing local data source tables... depending on size of tables, it may take a few minutes
[########################################]104/104-100.0%  A...zing completed!
Finished analyzing datasource: 
file://csv@qt_root/data/
3 table(s) out of 104 contain local data as summary below, to view complete list, print returned DataFrame
===============================tables with local data===============================
               Has_data Size_on_disk Record_count Record_start Record_end
table                                                                    
trade_calendar   True       1.8MB         70K          CFFEX        SZSE 
stock_basic      True       852KB          5K           None        None 
stock_daily      True      98.8MB        1.3M       20211112    20241231

データ ソース全体の全体的な情報を表示するには、各データ テーブルからのすべての情報を要約する必要があるため、数分かかる場合があります。

概要中に、qteasy は進行状況バーを表示し、すべてのテーブルの DataFrame を返し、主要な統計を出力します。

この概要には、データが入力された 3 つのテーブル (trade_calendarstock_basicstock_daily) が行数、ディスク使用量、開始日と終了日とともに表示されます。返された DataFrame を印刷して、すべてのテーブルを表示します。

>>> print(overview)
                   has_data   size records       pk1 records1       min1  \
table                                                                      
trade_calendar         True  1.8MB     70K  cal_date    12865   19901012   
hk_trade_calendar     False      0       0  cal_date  unknown        N/A   
us_trade_calendar     False      0       0  cal_date  unknown        N/A   
stock_basic            True  852KB      5K   ts_code     5396  000001.SZ   
hk_stock_basic        False      0       0   ts_code  unknown        N/A   
...                     ...    ...     ...       ...      ...        ...   
cn_cpi                False      0       0     month  unknown        N/A   
cn_ppi                False      0       0     month  unknown        N/A   
cn_money              False      0       0     month  unknown        N/A   
cn_sf                 False      0       0     month  unknown        N/A   
cn_pmi                False      0       0     month  unknown        N/A   

                        max1       pk2 records2   min2  max2  
table                                                         
trade_calendar      20251231  exchange        7  CFFEX  SZSE  
hk_trade_calendar        N/A      None     None   None  None  
us_trade_calendar        N/A      None     None   None  None  
stock_basic        920128.BJ      None     None   None  None  
hk_stock_basic           N/A      None     None   None  None  
...                      ...       ...      ...    ...   ...  
cn_cpi                   N/A      None     None   None  None  
cn_ppi                   N/A      None     None   None  None  
cn_money                 N/A      None     None   None  None  
cn_sf                    N/A      None     None   None  None  
cn_pmi                   N/A      None     None   None  None  

[104 rows x 11 columns]

5.4. 最も重要なデータテーブル

初めて使用するとき、テーブルは空であることがよくありますが、qteasy は財務データの取得と使用を簡素化するように設計されています。

基本データは簡単にダウンロードできますが、一部のテーブルはより重要です。他のテーブルはそれらと qteasy 自体に依存しているため、最初にデータを入力します。

  • trade_calendar — すべての取引所の取引カレンダー (取引日、取引所コード/名前)。 qteasy の核心: QTEASY1 がないと、多くの機能が失敗したり遅くなったりします。取引日とダウンロードの日付範囲を決定するために使用されます — 最初にこの表に記入してください

  • stock_basic — コード、名前、上場/上場廃止日、業界、地域などの株式基本表。株式日次 K ラインおよび財務表の基礎。 優先順位をこの表に記入してください。

  • index_basic — コード、名前、公開/上場廃止日などを含むインデックス基本テーブル。毎日の K ラインおよび構成要素テーブルのインデックスの基礎。 優先順位をこの表に記入してください。

  • fund_basic — コード、名前、タイプ、サイズなどを含むファンド基本テーブル。ファンドの毎日の K ラインおよび NAV テーブルの基礎。 優先順位をこの表に記入してください。

これらの主要なテーブルが満たされると、ほとんどの qteasy データ機能がスムーズに動作します。

qteasy は、ライブ取引記録用に 4 つのシステム テーブルも定義します。

  • sys_op_live_accounts — 口座 ID、名前、タイプ、ステータスなどを含むライブ取引口座マスター テーブル。

  • sys_op_positions — アカウント ID、セキュリティ コード/名前、数量、コストなどを含むライブ ポジション テーブル。

  • sys_op_trade_orders — アカウント ID、注文時間/種類、セキュリティ コード、数量、価格などを含むライブ注文テーブル。

  • sys_op_trade_results — アカウント ID、フィル時間、セキュリティ コード、数量、価格などを含むライブフィル テーブル。

これら 4 つのシステム テーブルはライブ取引を支えます。データは自動生成されます。手動で入力、表示、削除しないでください。

その他のテーブル

主要なテーブルに加えて、DataSource は、基本、日次 K ライン、財務、配当、収益レポート、マクロ データなどをカバーするさらに多くのデータを定義します。

  • 市場データ テーブル — 株式、ファンド、指数のさまざまな頻度での OHLCV

  • 基本表 — 株式、ファンド、指数、先物、オプションなど。

  • 指標表 — テクニカル、ファンダメンタルズ、マクロ指標など

  • 財務諸表表 — 貸借対照表、損益計算書、キャッシュ フローなど

  • 収益レポート表 — エクスプレスレポート、収益ガイダンス、予測など。

  • 配当とブロック取引テーブル — 配当、ブロック取引、株主取引など。

  • 参照テーブル — マクロ、業界、為替、その他の参照データ

テーブル定義とデータ型については、get_table_info() または次の章を参照してください。

5.5. テーブルからのデータの読み取り

入力したら、read_table_data() を使用して、ストレージの詳細を気にせずに日付/コード フィルターを使用して読み取ります。

大量の読み取りを回避するには、常にフィルターを渡します。 read_table_data() を使用すると、セキュリティ コードと日付範囲でフィルタリングできます。

  • shares: 1 つのセキュリティ コードまたはカンマ区切りコード。主キーにセキュリティコードが含まれている場合、それらのコードで出力をフィルタリングします。

  • start: “YYYYMMDD” 形式の日付。テーブルの主キーに時刻または日付が含まれている場合は、startend の間の行をフィルターします。 start/end はペアで指定する必要があります

  • end: “YYYYMMDD” 形式の日付。テーブルの主キーに時刻または日付が含まれている場合は、startend の間の行をフィルターします。 start/end はペアで指定する必要があります

DataSource は、次のような条件に基づいてデータを自動的にフィルタリングします。

2024-01-01 から 2024-01-15 までの stock_daily から 000651.SZ の毎日の K ライン データを読み取ります。

>>> ds.read_table_data(table='stock_daily', shares='000651.SZ', start='20240101', end='20240115')
                       open   high    low  ...  pct_chg        vol       amount
ts_code   trade_date                       ...                                 
000651.SZ 2024-01-03  32.00  32.08  31.70  ...  -0.7181  254468.92   810315.013
          2024-01-04  31.90  32.01  31.45  ...   0.4717  333398.05  1057458.411
          2024-01-08  33.12  33.21  32.85  ...  -0.2426  415911.34  1372722.050
          2024-01-02  32.17  32.20  31.96  ...  -0.4352  253797.30   814257.175
          2024-01-15  33.45  33.95  33.42  ...   0.6544  295681.34   996815.725
          2024-01-11  33.66  33.82  33.42  ...  -0.2376  284088.74   955075.100
          2024-01-09  32.81  33.55  32.65  ...   1.7933  438207.66  1454959.637
          2024-01-10  33.35  33.84  33.28  ...   0.5375  366485.52  1233441.572
          2024-01-12  33.50  33.83  33.42  ...   0.0893  224012.73   753931.821
          2024-01-05  32.05  33.29  31.62  ...   3.2238  832156.75  2738167.636

[10 rows x 9 columns]

DataSource は各テーブルに正しいフィルターを適用し、不要なパラメーターを無視します。たとえば、2 つの株式の基本情報をクエリする場合、取引日は必要ありません。qteasy は、通知付きで start/end を無視します。 shares パラメータは、株式だけでなく、ファンド、指数、先物、オプションにも機能します。

>>> ds.read_table_data(table='stock_basic', shares='000651.SZ,000700.SZ', start='20240101', end='20240131')
/Users/jackie/Projects/qteasy/qteasy/database.py:1314: RuntimeWarning: list index out of range
can not find date-like primary key in the table stock_basic!
passed start(2024-01-01) and end(2024-01-31) arguments will be ignored!
  warnings.warn(msg, RuntimeWarning)
           symbol  name area industry  ... list_status list_date delist_date is_hs
ts_code                                ...                                        
000651.SZ     651  格力电器   广东     家用电器  ...           L  19961118         NaN     S
000700.SZ     700  模塑科技   江苏     汽车配件  ...           L  19970228         NaN     S

[2 rows x 14 columns]

read_table_data() の詳細については、DataSource リファレンスを参照してください。

5.6. テーブルへのデータの追加

テーブルが空か不十分な場合、読み取りは失敗します。最初にテーブルを埋めます。

注記:

これは手動書き込みのみを対象としています。自動ダウンロード、クリーニング、補充については後で説明します。

update_table_data() を介してテーブルに入力し、3 つのパラメーターを含む DataFrame を書き込みます。

  • table: 書き込むターゲットテーブルの名前

  • df: テーブルに書き込むデータを保持する DataFrame

  • merge_type: update の場合、テーブル内の既存の行を更新します。 ignore の場合、重複する行をスキップします。

update_table_data() では、スキーマの正確な一致は必要ありません。qteasy は、書き込み前に形式を正規化し、重複を排除します。

サンプルデータはデモンストレーションのみを目的として以下に書かれています。

>>> import pandas as pd
>>> df = pd.DataFrame({
...         'ts_code':    ['000001.SZ', '000002.SZ', '000003.SZ', '000004.SZ', '000005.SZ',
...                        '000001.SZ', '000002.SZ', '000003.SZ', '000004.SZ', '000005.SZ'],
...         'trade_date': ['20211112', '20211112', '20211112', '20211112', '20211112',
...                        '20211113', '20211113', '20211113', '20211113', '20211113'],
...         'open':       [1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
...         'high':       [2., 3., 4., 5., 6., 7., 8., 9., 10., 1.],
...         'low':        [3., 4., 5., 6., 7., 8., 9., 10., 1., 2.],
...         'close':      [4., 5., 6., 7., 8., 9., 10., 1., 2., 3.]
...     })
>>> print(df)
     ts_code trade_date  open  high   low  close
0  000001.SZ   20211112   1.0   2.0   3.0    4.0
1  000002.SZ   20211112   2.0   3.0   4.0    5.0
2  000003.SZ   20211112   3.0   4.0   5.0    6.0
3  000004.SZ   20211112   4.0   5.0   6.0    7.0
4  000005.SZ   20211112   5.0   6.0   7.0    8.0
5  000001.SZ   20211113   6.0   7.0   8.0    9.0
6  000002.SZ   20211113   7.0   8.0   9.0   10.0
7  000003.SZ   20211113   8.0   9.0  10.0    1.0
8  000004.SZ   20211113   9.0  10.0   1.0    2.0
9  000005.SZ   20211113  10.0   1.0   2.0    3.0

上記のサンプルDataFrameindex_dailyに書き込まれます。現在、index_daily は空で、その schemaDataFrame とは若干異なります。

  • index_daily テーブル スキーマは 11 列を定義しますが、上記のサンプル DataFrame には 6 列しかありません。すべての DataFrame 列はまだ index_daily schema 内にあります。

  • index_daily テーブルは現在空であり、データは入力されていません。

>>> info = ds.get_table_info('index_daily')
<index_daily>--<指数日线行情>
0 MB/0 records on disc
primary keys: 
----------------------------------------
1:   ts_code:  <unknown> entries
     starts: N/A, end: N/A
2:   trade_date:  <unknown> entries
     starts: N/A, end: N/A

columns of table:
------------------------------------
       columns       dtypes  remarks
0      ts_code  varchar(20)     证券代码
1   trade_date         date     交易日期
2         open        float      开盘价
3         high        float      最高价
4          low        float      最低价
5        close        float      收盘价
6    pre_close        float      昨收价
7       change        float      涨跌额
8      pct_chg        float      涨跌幅
9          vol       double   成交量(手)
10      amount       double  成交额(千元)

次にデータを書き込みます。成功すると、メソッドは書き込まれた行を返します。

>>> ds.update_table_data(table='index_daily', df=df)
10

書き込み後、挿入したばかりのデータを読み戻すことができます。

書き込まれた df にはそれらのフィールドが含まれていなかったため、多くの列は NaN として読み取られます。

>>> df = ds.read_table_data('index_daily', shares='000001.SZ, 000002.SZ')
>>> print(df)
                      open  high  low  close  pre_close  change  pct_chg  vol  \
ts_code   trade_date                                                            
000001.SZ 2021-11-12   1.0   2.0  3.0    4.0        NaN     NaN      NaN  NaN   
000002.SZ 2021-11-12   2.0   3.0  4.0    5.0        NaN     NaN      NaN  NaN   
000001.SZ 2021-11-13   6.0   7.0  8.0    9.0        NaN     NaN      NaN  NaN   
000002.SZ 2021-11-13   7.0   8.0  9.0   10.0        NaN     NaN      NaN  NaN   

                      amount  
ts_code   trade_date          
000001.SZ 2021-11-12     NaN  
000002.SZ 2021-11-12     NaN  
000001.SZ 2021-11-13     NaN  
000002.SZ 2021-11-13     NaN  

5.7. テーブルを削除する — 注意してください。削除は元に戻せません!!

テーブル全体を削除することもできます。qteasy は部分的な削除をサポートしていません。十分注意してください。

DataSource は、頻繁な削除ではなく、ストレージと読み取り用に最適化されています。これは一般的なデータベースではなく、データ ウェアハウスです。

DataSource メソッド drop_table_data() はテーブル全体を削除するため、元に戻すことはできません

偶発的な落下を防ぐため、デフォルトでは drop_table_data() エラーが発生します。一時的な index_daily データを削除する場合:

>>> ds.drop_table_data('index_daily')
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[19], line 1
----> 1 ds.drop_table_data('index_daily')

File ~/Projects/qteasy/qteasy/database.py:1587, in DataSource.drop_table_data(self, table)
   1584 if not self.allow_drop_table:
   1585     err = RuntimeError('Can\'t drop table from current datasource according to setting, please check: '
   1586                        'datasource.allow_drop_table')
-> 1587     raise err
   1589 if self.source_type == 'db':
   1590     self._drop_db_table(db_table=table)

RuntimeError: Can't drop table from current datasource according to setting, please check: datasource.allow_drop_table

ドロップを許可するには、allow_drop_tableTrue に設定します。その後、False に戻してください。

以下のコードは index_daily をドロップします。その後、そのテーブルからの読み取りは失敗します。

>>> ds.allow_drop_table = True
>>> ds.drop_table_data('index_daily')
>>> ds.allow_drop_table = False
>>> df = ds.read_table_data(table='index_daily')
>>> print(df)
    
Empty DataFrame
Columns: []
Index: []

5.8. まとめ

これで、DataSource、qteasy の財務履歴データ管理のコア クラスが理解できました。次のものが含まれます。

  • DataSource とは何か、およびその作成方法

  • DataSource からデータを抽出しています

  • DataSource での作業

後の章ではさらに詳しく説明します。

  • DataSource にはどのような有用な財務データがありますか?

  • DataSourceをバッチダウンロードして埋めるにはどうすればよいですか?

  • DataSource からより効果的に情報を抽出するには?