From e3a071225388b05b99e839c6033c0081c7c11476 Mon Sep 17 00:00:00 2001 From: foolcage <5533061@qq.com> Date: Fri, 3 May 2024 13:18:07 +0800 Subject: [PATCH] stock tick --- examples/tag_utils.py | 18 +- examples/utils.py | 8 +- src/zvt/api/tag.py | 73 ------ src/zvt/broker/qmt/qmt_api.py | 219 +++++++++++++++++- src/zvt/domain/__init__.py | 1 - src/zvt/domain/meta/stock_meta.py | 16 +- src/zvt/domain/quotes/__init__.py | 33 ++- src/zvt/domain/quotes/stock/__init__.py | 18 +- .../quotes/stock/stock_l2quote_hfq_kdata.py | 18 -- .../quotes/stock/stock_l2quote_kdata.py | 18 -- src/zvt/domain/quotes/stock/stock_quote.py | 45 ++++ src/zvt/fill_project.py | 8 +- src/zvt/recorders/qmt/meta/__init__.py | 1 + .../qmt/meta/qmt_stock_meta_recorder.py | 23 ++ 14 files changed, 345 insertions(+), 154 deletions(-) delete mode 100644 src/zvt/api/tag.py delete mode 100644 src/zvt/domain/quotes/stock/stock_l2quote_hfq_kdata.py delete mode 100644 src/zvt/domain/quotes/stock/stock_l2quote_kdata.py create mode 100644 src/zvt/domain/quotes/stock/stock_quote.py create mode 100644 src/zvt/recorders/qmt/meta/__init__.py create mode 100644 src/zvt/recorders/qmt/meta/qmt_stock_meta_recorder.py diff --git a/examples/tag_utils.py b/examples/tag_utils.py index 8f2ebdd1..248711cb 100644 --- a/examples/tag_utils.py +++ b/examples/tag_utils.py @@ -4,11 +4,19 @@ from collections import Counter from zvt.api import china_stock_code_to_id, get_china_exchange -from zvt.api.selector import get_entity_ids_by_filter -from zvt.api.tag import tag_stock, get_stock_tags, get_limit_up_reasons -from zvt.contract.api import get_entities -from zvt.domain import BlockStock, Block, Stock -from zvt.utils import current_date, date_time_by_interval, pd_is_not_null + +from zvt.domain import BlockStock, Block, Stock, LimitUpInfo + + +def get_limit_up_reasons(entity_id): + info = LimitUpInfo.query_data( + entity_id=entity_id, order=LimitUpInfo.timestamp.desc(), limit=1, return_type="domain" + ) + + topics = [] + if info and info[0].reason: + topics = topics + info[0].reason.split("+") + return topics def get_concept(code): diff --git a/examples/utils.py b/examples/utils.py index b3b15bf8..9ea107ab 100644 --- a/examples/utils.py +++ b/examples/utils.py @@ -2,16 +2,11 @@ import json import logging import os -import pprint import time import eastmoneypy import pandas as pd -from zvt.api.selector import get_entity_ids_by_filter -from zvt.api.stats import get_top_performance_entities_by_periods -from zvt.api.tag import get_limit_up_reasons -from zvt.contract.api import get_entities, decode_entity_id from zvt.domain import StockNews, Stock, LimitUpInfo from zvt.utils import date_time_by_interval, today @@ -191,5 +186,4 @@ def get_hot_topics(start_timestamp=None, days_ago=20, limit=15): # entities = get_entities(provider="em", entity_type="stock", entity_ids=ids, return_type="domain") # # print(msg_group_stocks_by_topic(entities=entities, threshold=1)) - # get_hot_topics(days_ago=10) - print(get_limit_up_reasons(entity_id="stock_sz_300857")) + get_hot_topics(days_ago=10) diff --git a/src/zvt/api/tag.py b/src/zvt/api/tag.py deleted file mode 100644 index 0e445fc6..00000000 --- a/src/zvt/api/tag.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -import json - -from zvt.api import china_stock_code_to_id -from zvt.api.selector import get_entity_ids_by_filter -from zvt.contract.api import decode_entity_id, get_db_session -from zvt.domain import LimitUpInfo, Stock - - -def get_limit_up_reasons(entity_id): - info = LimitUpInfo.query_data( - entity_id=entity_id, order=LimitUpInfo.timestamp.desc(), limit=1, return_type="domain" - ) - - topics = [] - if info and info[0].reason: - topics = topics + info[0].reason.split("+") - return topics - - -def build_stock_tags_from_limit_up(): - normal_stock_ids = get_entity_ids_by_filter( - provider="em", ignore_delist=True, ignore_st=False, ignore_new_stock=False - ) - for entity_id in normal_stock_ids: - tags = get_limit_up_reasons(entity_id=entity_id) - for tag in tags: - tag_stock(entity_id=entity_id, tag=tag, core_tag=False) - - -def tag_stock(entity_id=None, code=None, name=None, tag=None, reason=None, provider="em", core_tag=True): - session = get_db_session(provider=provider, data_schema=Stock) - if not entity_id: - if code: - entity_id = china_stock_code_to_id(code=code) - - stock = Stock.get_by_id(provider=provider, id=entity_id) - if name: - assert stock.name == name - - if stock: - if stock.tags: - tags = json.loads(stock.tags) - if not reason: - reason = tags.get(tag) - else: - tags = {} - tags[tag] = reason - - stock.tags = json.dumps(tags, ensure_ascii=False) - if core_tag: - stock.core_tag = json.dumps({tag: reason}, ensure_ascii=False) - session.add(stock) - session.commit() - - -def get_stock_tags(entity_id=None, code=None, tags_only=False, provider="em"): - if not entity_id: - if code: - entity_id = china_stock_code_to_id(code=code) - - stock = Stock.query_data(provider=provider, entity_id=entity_id, return_type="domain") - if stock and stock[0].tags: - tags = json.loads(stock[0].tags) - if tags_only: - return list(tags.keys()) - return tags - - -def get_stock_core_tag(entity_id, provider="em"): - stock = Stock.query_data(provider=provider, entity_id=entity_id, return_type="domain") - if stock and stock[0].core_tag: - return json.loads(stock[0].core_tag) diff --git a/src/zvt/broker/qmt/qmt_api.py b/src/zvt/broker/qmt/qmt_api.py index b9207990..8bf179a4 100644 --- a/src/zvt/broker/qmt/qmt_api.py +++ b/src/zvt/broker/qmt/qmt_api.py @@ -1,13 +1,19 @@ # -*- coding: utf-8 -*- +import logging +from datetime import datetime + import pandas as pd from xtquant import xtdata from zvt.contract import IntervalLevel, AdjustType -from zvt.contract.api import decode_entity_id -from zvt.utils import to_time_str +from zvt.contract.api import decode_entity_id, df_to_db +from zvt.domain import StockQuotes, Stock +from zvt.utils import to_time_str, current_date, to_pd_timestamp + +# https://dict.thinktrader.net/nativeApi/start_now.html?id=e2M5nZ -# http://docs.thinktrader.net/vip/QMT-Simple/ +logger = logging.getLogger(__name__) def _to_qmt_code(entity_id): @@ -15,6 +21,12 @@ def _to_qmt_code(entity_id): return f"{code}.{exchange.upper()}" +def _to_zvt_entity_id(qmt_code): + code, exchange = qmt_code.split(".") + exchange = exchange.lower() + return f"stock_{exchange}_{code}" + + def _to_qmt_dividend_type(adjust_type: AdjustType): if adjust_type == AdjustType.qfq: return "front" @@ -24,6 +36,48 @@ def _to_qmt_dividend_type(adjust_type: AdjustType): return "none" +def _qmt_instrument_detail_to_stock(stock_detail): + exchange = stock_detail["ExchangeID"].lower() + code = stock_detail["InstrumentID"] + name = stock_detail["InstrumentName"] + list_date = to_pd_timestamp(stock_detail["OpenDate"]) + end_date = to_pd_timestamp(stock_detail["ExpireDate"]) + pre_close = stock_detail["PreClose"] + limit_up_price = stock_detail["UpStopPrice"] + limit_down_price = stock_detail["DownStopPrice"] + float_volume = stock_detail["FloatVolume"] + total_volume = stock_detail["TotalVolume"] + + entity_id = f"stock_{exchange}_{code}" + + return { + "id": entity_id, + "entity_id": entity_id, + "timestamp": list_date, + "entity_type": "stock", + "exchange": exchange, + "code": code, + "name": name, + "list_date": list_date, + "end_date": end_date, + "pre_close": pre_close, + "limit_up_price": limit_up_price, + "limit_down_price": limit_down_price, + "float_volume": float_volume, + "total_volume": total_volume, + } + + +def get_entity_list(): + stocks = xtdata.get_stock_list_in_sector("沪深A股") + entity_list = [] + for stock in stocks: + stock_detail = xtdata.get_instrument_detail(stock, False) + entity_list.append(_qmt_instrument_detail_to_stock(stock_detail)) + + return pd.DataFrame.from_records(data=entity_list) + + def get_kdata( entity_id, start_timestamp, @@ -52,5 +106,162 @@ def get_kdata( return pd.concat(dfs, axis=1) +def _tick_to_quotes(): + pass + + +def record_tick(): + stocks = xtdata.get_stock_list_in_sector("沪深A股") + logger.info(f"today stocks[{len(stocks)}]:{stocks}") + + df = Stock.query_data(provider="em", return_type="df", index="entity_id") + + def on_data(datas, stock_df=df): + dt = datetime.now() + var = { + "time": 1714460254000, + "lastPrice": 36.08, + "open": 35.4, + "high": 36.62, + "low": 35.13, + "lastClose": 34.1, + "amount": 67690300.0, + "volume": 18793, + "pvolume": 1879308, + "stockStatus": 0, + "openInt": 18, + "transactionNum": 0, + "lastSettlementPrice": 0.0, + "settlementPrice": 0.0, + "pe": 0.0, + "askPrice": [36.07, 0.0, 0.0, 0.0, 0.0], + "bidPrice": [36.07, 0.0, 0.0, 0.0, 0.0], + "askVol": [14, 0, 0, 0, 0], + "bidVol": [14, 12, 0, 0, 0], + "volRatio": 0.0, + "speed1Min": 0.0, + "speed5Min": 0.0, + } + # #: 是否涨停 + # is_limit_up = Column(Boolean) + # #: 封涨停金额 + # limit_up_amount = Column(Float) + # #: 是否跌停 + # is_limit_down = Column(Boolean) + # #: 封跌停金额 + # limit_down_amount = Column(Float) + # #: 5挡卖单金额 + # ask_amount = Column(Float) + # #: 5挡买单金额 + # bid_amount = Column(Float) + # #: 流通市值 + # float_cap = Column(Float) + # #: 总市值 + # total_cap = Column(Float) + tick_df = pd.DataFrame.from_dict(datas, orient="index") + tick_df.index = tick_df.index.map(_to_zvt_entity_id) + + meta_df = stock_df.loc[tick_df.index] + df = pd.concat([tick_df, meta_df], axis=1) + + df = df.rename(columns={"lastPrice": "price", "amount": "turnover"}) + df["timestamp"] = pd.to_datetime(df["time"], unit="ms") + df["turnover_rate"] = df["pvolume"] + df["change_pct"] = (df["price"] - df["lastClose"]) / df["lastClose"] + df["ask_amount"] = (df["askPrice"] * df["askVol"]).sum(axis=1) + df["bid_amount"] = (df["bidPrice"] * df["bidVol"]).sum(axis=1) + print(df) + df_to_db(df=df, data_schema=StockQuotes, provider="qmt") + + xtdata.subscribe_whole_quote(["SH", "SZ"], callback=on_data) + xtdata.run() + + +def record_kdata(entity_ids): + + stock_list = [_to_qmt_code(entity_id=entity_id) for entity_id in entity_ids] + now = datetime.now() + start_time = datetime(year=now.year, month=now.month, day=now.day, hour=9, minute=20, second=0) + start_time = to_time_str(start_time, fmt="YYYYMMDDHHmmss") + + end_time = datetime(year=now.year, month=now.month, day=now.day, hour=15, minute=0, second=0) + end_time = to_time_str(end_time, fmt="YYYYMMDDHHmmss") + while True: + records = xtdata.get_local_data( + stock_list=stock_list, + period="tick", + start_time=start_time, + end_time=end_time, + fill_data=False, + ) + datas = records.get(stock_list[0]) + start_time = to_time_str(to_pd_timestamp(int(datas[-1][0])), fmt="YYYYMMDDHHmmss") + logger.info(f"to {start_time}") + + if start_time == end_time: + logger.info("finished") + break + + if __name__ == "__main__": - print(get_kdata(entity_id="stock_sz_000338", start_timestamp="20230101", end_timestamp="20230329")) + print(get_kdata(entity_id="stock_sz_000001", start_timestamp="20230101", end_timestamp="20230329")) + # 'time' #时间戳 + # 'lastPrice' #最新价 + # 'open' #开盘价 + # 'high' #最高价 + # 'low' #最低价 + # 'lastClose' #前收盘价 + # 'amount' #成交总额 + # 'volume' #成交总量 + # 'pvolume' #原始成交总量 + # 'stockStatus' #证券状态 + # 'openInt' #持仓量 + # 'lastSettlementPrice' #前结算 + # 'askPrice' #委卖价 + # 'bidPrice' #委买价 + # 'askVol' #委卖量 + # 'bidVol' #委买量 + # 'transactionNum' #成交笔数 + { + "000001.SZ": { + "timetag": "20240425 14:57:36", + "lastPrice": 10.61, + "open": 10.5, + "high": 10.62, + "low": 10.48, + "lastClose": 10.53, + "amount": 1161898300, + "volume": 1100234, + "pvolume": 110023424, + "stockStatus": 0, + "openInt": 18, + "settlementPrice": 0, + "lastSettlementPrice": 0, + "askPrice": [10.6, 0, 0, 0, 0], + "bidPrice": [10.6, 0, 0, 0, 0], + "askVol": [3349, 0, 0, 0, 0], + "bidVol": [3349, 2600, 0, 0, 0], + }, + "000002.SZ": { + "timetag": "20240425 14:57:36", + "lastPrice": 6.55, + "open": 6.5, + "high": 6.68, + "low": 6.48, + "lastClose": 6.54, + "amount": 1242969100, + "volume": 1889977, + "pvolume": 188997683, + "stockStatus": 0, + "openInt": 18, + "settlementPrice": 0, + "lastSettlementPrice": 0, + "askPrice": [6.55, 0, 0, 0, 0], + "bidPrice": [6.55, 0, 0, 0, 0], + "askVol": [4030, 1032, 0, 0, 0], + "bidVol": [4030, 0, 0, 0, 0], + }, + } +# [(1713834900000, 0. , 0., 0. , 0. , 44.96, 0.00000000e+00, 0, 0, 0, 12, 0., list([44.95, 0.0, 0.0, 0.0, 0.0]), list([44.95, 0.0, 0.0, 0.0, 0.0]), list([8, 3, 0, 0, 0]), list([8, 0, 0, 0, 0]), 0., 0, 0.), +# (1713834909000, 0. , 0., 0. , 0. , 44.96, 0.00000000e+00, 0, 0, 0, 12, 0., list([44.95, 0.0, 0.0, 0.0, 0.0]), list([44.95, 0.0, 0.0, 0.0, 0.0]), list([13, 1, 0, 0, 0]), list([13, 0, 0, 0, 0]), 0., 0, 0.), +# diff --git a/src/zvt/domain/__init__.py b/src/zvt/domain/__init__.py index 36303622..ee78451b 100644 --- a/src/zvt/domain/__init__.py +++ b/src/zvt/domain/__init__.py @@ -179,7 +179,6 @@ def get_future_name(code): __all__ += _macro_all - # import all from submodule actor from .actor import * from .actor import __all__ as _actor_all diff --git a/src/zvt/domain/meta/stock_meta.py b/src/zvt/domain/meta/stock_meta.py index 2b4c852b..c82f59fb 100644 --- a/src/zvt/domain/meta/stock_meta.py +++ b/src/zvt/domain/meta/stock_meta.py @@ -13,8 +13,16 @@ @register_entity(entity_type="stock") class Stock(StockMetaBase, TradableEntity): __tablename__ = "stock" - tags = Column(String) - core_tag = Column(String) + #: 昨日收盘价 + pre_close = Column(Float) + #: 今日涨停价 + limit_up_price = Column(Float) + # :今日跌停价 + limit_down_price = Column(Float) + #: 流通股本 + float_volume = Column(BigInteger) + #: 总股份 + total_volume = Column(BigInteger) #: 个股详情 @@ -48,6 +56,8 @@ class StockDetail(StockMetaBase, TradableEntity): net_winning_rate = Column(Float) -register_schema(providers=["exchange", "joinquant", "eastmoney", "em"], db_name="stock_meta", schema_base=StockMetaBase) +register_schema( + providers=["exchange", "joinquant", "eastmoney", "em", "qmt"], db_name="stock_meta", schema_base=StockMetaBase +) # the __all__ is generated __all__ = ["Stock", "StockDetail"] diff --git a/src/zvt/domain/quotes/__init__.py b/src/zvt/domain/quotes/__init__.py index f7d95c4b..dad905cc 100644 --- a/src/zvt/domain/quotes/__init__.py +++ b/src/zvt/domain/quotes/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from sqlalchemy import String, Column, Float +from sqlalchemy import String, Column, Float, Integer, JSON from zvt.contract import Mixin @@ -31,17 +31,30 @@ class KdataCommon(Mixin): class TickCommon(Mixin): - provider = Column(String(length=32)) - code = Column(String(length=32)) - name = Column(String(length=32)) - level = Column(String(length=32)) - - order = Column(String(length=32)) - price = Column(Float) + #: UNIX时间戳 + time = Column(Integer) + #: 开盘价 + open = Column(Float) + #: 收盘价/当前价格 + close = Column(Float) + #: 最高价 + high = Column(Float) + #: 最低价 + low = Column(Float) + #: 成交量 volume = Column(Float) + #: 成交金额 turnover = Column(Float) - direction = Column(String(length=32)) - order_type = Column(String(length=32)) + #: 委卖价 + ask_price = Column(Float) + #: 委买价 + bid_price = Column(Float) + #: 委卖量 + ask_vol = Column(JSON) + #: 委买量 + bid_vol = Column(JSON) + #: 成交笔数 + transaction_num = Column(Integer) class BlockKdataCommon(KdataCommon): diff --git a/src/zvt/domain/quotes/stock/__init__.py b/src/zvt/domain/quotes/stock/__init__.py index b967e13b..baabcb24 100644 --- a/src/zvt/domain/quotes/stock/__init__.py +++ b/src/zvt/domain/quotes/stock/__init__.py @@ -67,12 +67,6 @@ __all__ += _stock_30m_hfq_kdata_all -# import all from submodule stock_l2quote_hfq_kdata -from .stock_l2quote_hfq_kdata import * -from .stock_l2quote_hfq_kdata import __all__ as _stock_l2quote_hfq_kdata_all - -__all__ += _stock_l2quote_hfq_kdata_all - # import all from submodule stock_1mon_hfq_kdata from .stock_1mon_hfq_kdata import * from .stock_1mon_hfq_kdata import __all__ as _stock_1mon_hfq_kdata_all @@ -97,12 +91,6 @@ __all__ += _stock_1h_hfq_kdata_all -# import all from submodule stock_l2quote_kdata -from .stock_l2quote_kdata import * -from .stock_l2quote_kdata import __all__ as _stock_l2quote_kdata_all - -__all__ += _stock_l2quote_kdata_all - # import all from submodule stock_1m_kdata from .stock_1m_kdata import * from .stock_1m_kdata import __all__ as _stock_1m_kdata_all @@ -121,6 +109,12 @@ __all__ += _stock_1d_hfq_kdata_all +# import all from submodule stock_quote +from .stock_quote import * +from .stock_quote import __all__ as _stock_quote_all + +__all__ += _stock_quote_all + # import all from submodule stock_30m_kdata from .stock_30m_kdata import * from .stock_30m_kdata import __all__ as _stock_30m_kdata_all diff --git a/src/zvt/domain/quotes/stock/stock_l2quote_hfq_kdata.py b/src/zvt/domain/quotes/stock/stock_l2quote_hfq_kdata.py deleted file mode 100644 index cf5e55a7..00000000 --- a/src/zvt/domain/quotes/stock/stock_l2quote_hfq_kdata.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# this file is generated by gen_kdata_schema function, dont't change it -from sqlalchemy.orm import declarative_base - -from zvt.contract.register import register_schema -from zvt.domain.quotes import StockKdataCommon - -KdataBase = declarative_base() - - -class StockL2quoteHfqKdata(KdataBase, StockKdataCommon): - __tablename__ = "stock_l2quote_hfq_kdata" - - -register_schema(providers=["em", "qmt", "joinquant"], db_name="stock_l2quote_hfq_kdata", schema_base=KdataBase, entity_type="stock") - -# the __all__ is generated -__all__ = ["StockL2quoteHfqKdata"] diff --git a/src/zvt/domain/quotes/stock/stock_l2quote_kdata.py b/src/zvt/domain/quotes/stock/stock_l2quote_kdata.py deleted file mode 100644 index a76ad4cf..00000000 --- a/src/zvt/domain/quotes/stock/stock_l2quote_kdata.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# this file is generated by gen_kdata_schema function, dont't change it -from sqlalchemy.orm import declarative_base - -from zvt.contract.register import register_schema -from zvt.domain.quotes import StockKdataCommon - -KdataBase = declarative_base() - - -class StockL2quoteKdata(KdataBase, StockKdataCommon): - __tablename__ = "stock_l2quote_kdata" - - -register_schema(providers=["em", "qmt", "joinquant"], db_name="stock_l2quote_kdata", schema_base=KdataBase, entity_type="stock") - -# the __all__ is generated -__all__ = ["StockL2quoteKdata"] diff --git a/src/zvt/domain/quotes/stock/stock_quote.py b/src/zvt/domain/quotes/stock/stock_quote.py new file mode 100644 index 00000000..f5a0ae96 --- /dev/null +++ b/src/zvt/domain/quotes/stock/stock_quote.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from sqlalchemy import String, Column, Float, Integer, JSON, Boolean +from sqlalchemy.orm import declarative_base + +from zvt.contract import Mixin +from zvt.contract.register import register_schema + +StockQuotesBase = declarative_base() + + +class StockQuotes(StockQuotesBase, Mixin): + __tablename__ = "stock_quotes" + + #: UNIX时间戳 + time = Column(Integer) + #: 最新价 + price = Column(Float) + # 涨跌幅 + change_pct = Column(Float) + # 成交金额 + turnover = Column(Float) + # 换手率 + turnover_rate = Column(Float) + #: 是否涨停 + is_limit_up = Column(Boolean) + #: 封涨停金额 + limit_up_amount = Column(Float) + #: 是否跌停 + is_limit_down = Column(Boolean) + #: 封跌停金额 + limit_down_amount = Column(Float) + #: 5挡卖单金额 + ask_amount = Column(Float) + #: 5挡买单金额 + bid_amount = Column(Float) + #: 流通市值 + float_cap = Column(Float) + #: 总市值 + total_cap = Column(Float) + + +register_schema(providers=["qmt"], db_name="stock_quotes", schema_base=StockQuotesBase, entity_type="stock") + +# the __all__ is generated +__all__ = ["StockQuotes"] diff --git a/src/zvt/fill_project.py b/src/zvt/fill_project.py index fa89203c..e6cec900 100644 --- a/src/zvt/fill_project.py +++ b/src/zvt/fill_project.py @@ -14,7 +14,9 @@ def gen_kdata_schemas(): pkg="zvt", providers=["em", "qmt", "joinquant"], entity_type="stock", - levels=[level for level in IntervalLevel if level != IntervalLevel.LEVEL_TICK], + levels=[ + level for level in IntervalLevel if level not in (IntervalLevel.LEVEL_L2_QUOTE, IntervalLevel.LEVEL_TICK) + ], adjust_types=[None, AdjustType.hfq], entity_in_submodule=True, ) @@ -94,6 +96,6 @@ def gen_kdata_schemas(): # gen_exports('trader') # gen_exports('autocode') # gen_exports("ml") - # gen_kdata_schemas() + gen_kdata_schemas() # gen_exports("recorders") - gen_exports("tag") + # gen_exports("tag") diff --git a/src/zvt/recorders/qmt/meta/__init__.py b/src/zvt/recorders/qmt/meta/__init__.py new file mode 100644 index 00000000..40a96afc --- /dev/null +++ b/src/zvt/recorders/qmt/meta/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/src/zvt/recorders/qmt/meta/qmt_stock_meta_recorder.py b/src/zvt/recorders/qmt/meta/qmt_stock_meta_recorder.py new file mode 100644 index 00000000..157a40dc --- /dev/null +++ b/src/zvt/recorders/qmt/meta/qmt_stock_meta_recorder.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from zvt.broker.qmt import qmt_api +from zvt.contract.api import df_to_db +from zvt.contract.recorder import Recorder +from zvt.domain import Stock + + +class QMTStockRecorder(Recorder): + provider = "qmt" + data_schema = Stock + + def run(self): + df = qmt_api.get_entity_list() + self.logger.info(df) + df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=True) + + +if __name__ == "__main__": + recorder = QMTStockRecorder() + recorder.run() +# the __all__ is generated +__all__ = ["QMTStockRecorder"]