From 6e400336ce7693d21a1d1dbe51e84db2c3e4d610 Mon Sep 17 00:00:00 2001 From: foolcage <5533061@qq.com> Date: Sun, 20 Oct 2024 21:37:55 +0800 Subject: [PATCH] 1)Add change_main_tag api 2)Add get_top_vol api 3)Add gfex exchange --- api-tests/tag/change_main_tag.http | 8 +++++ src/zvt/api/selector.py | 50 +++++++++++++++++++----------- src/zvt/contract/__init__.py | 3 ++ src/zvt/recorders/em/em_api.py | 27 ++++++++++------ src/zvt/rest/work.py | 6 ++++ src/zvt/tag/tag_models.py | 5 +++ src/zvt/tag/tag_service.py | 41 ++++++++++++++++++++++-- 7 files changed, 110 insertions(+), 30 deletions(-) create mode 100644 api-tests/tag/change_main_tag.http diff --git a/api-tests/tag/change_main_tag.http b/api-tests/tag/change_main_tag.http new file mode 100644 index 00000000..48cb614e --- /dev/null +++ b/api-tests/tag/change_main_tag.http @@ -0,0 +1,8 @@ +POST http://127.0.0.1:8090/api/work/change_main_tag +accept: application/json +Content-Type: application/json + +{ + "current_main_tag": "医疗器械", + "new_main_tag": "医药" +} \ No newline at end of file diff --git a/src/zvt/api/selector.py b/src/zvt/api/selector.py index 21174721..3d1c83d1 100644 --- a/src/zvt/api/selector.py +++ b/src/zvt/api/selector.py @@ -4,8 +4,8 @@ import pandas as pd from sqlalchemy import or_, and_ -from zvt.api.kdata import default_adjust_type, get_kdata_schema -from zvt.contract import IntervalLevel +from zvt.api.kdata import default_adjust_type, get_kdata_schema, get_latest_kdata_date +from zvt.contract import IntervalLevel, AdjustType from zvt.contract.api import get_entity_ids from zvt.domain import DragonAndTiger, Stock1dHfqKdata, Stock, LimitUpInfo, StockQuote, StockQuoteLog from zvt.utils.pd_utils import pd_is_not_null @@ -335,6 +335,34 @@ def get_shoot_today(up_change_pct=0.03, down_change_pct=-0.03, interval=2): return up.index.tolist(), down.index.tolist() +def get_top_vol( + entity_ids, + target_date=None, + limit=500, + provider="qmt", +): + if provider == "qmt": + df = StockQuote.query_data( + entity_ids=entity_ids, + columns=[StockQuote.entity_id], + order=StockQuote.turnover.desc(), + limit=limit, + ) + return df["entity_id"].to_list() + else: + if not target_date: + target_date = get_latest_kdata_date(provider="em", entity_type="stock", adjust_type=AdjustType.hfq) + df = Stock1dHfqKdata.query_data( + provider="em", + filters=[Stock1dHfqKdata.timestamp == to_pd_timestamp(target_date)], + entity_ids=entity_ids, + columns=[Stock1dHfqKdata.entity_id], + order=Stock1dHfqKdata.turnover.desc(), + limit=limit, + ) + return df["entity_id"].to_list() + + def get_top_down_today(n=100): df = StockQuote.query_data(columns=[StockQuote.entity_id], order=StockQuote.change_pct.asc(), limit=n) if pd_is_not_null(df): @@ -348,22 +376,8 @@ def get_limit_down_today(): if __name__ == "__main__": - # target_date = get_latest_kdata_date(provider="em", entity_type="stock", adjust_type=AdjustType.hfq) - # big = get_big_cap_stock(timestamp=target_date) - # print(len(big)) - # print(big) - # middle = get_middle_cap_stock(timestamp=target_date) - # print(len(middle)) - # print(middle) - # small = get_small_cap_stock(timestamp=target_date) - # print(len(small)) - # print(small) - # mini = get_mini_cap_stock(timestamp=target_date) - # print(len(mini)) - # print(mini) - # df = get_player_performance(start_timestamp="2022-01-01") - # print((get_entity_ids_by_filter(ignore_new_stock=False))) - print(get_limit_up_stocks(timestamp="2023-12-2")) + stocks = get_top_vol(entity_ids=None, provider="em") + assert len(stocks) == 500 # the __all__ is generated diff --git a/src/zvt/contract/__init__.py b/src/zvt/contract/__init__.py index 3cd9f856..b95c1fd4 100644 --- a/src/zvt/contract/__init__.py +++ b/src/zvt/contract/__init__.py @@ -232,6 +232,9 @@ class Exchange(Enum): #: 上海国际能源交易中心 ine = "ine" + #: 广州期货所 + gfex = "gfex" + #: 外汇交易所(虚拟) #: currency exchange(virtual) forex = "forex" diff --git a/src/zvt/recorders/em/em_api.py b/src/zvt/recorders/em/em_api.py index 99c8346c..b8d24790 100644 --- a/src/zvt/recorders/em/em_api.py +++ b/src/zvt/recorders/em/em_api.py @@ -569,12 +569,16 @@ def get_future_list(): entity["exchange"] = "cffex" entity["code"] = to_zvt_code(entity["code"]) else: - entity["exchange"] = Exchange(entity["exchange"].lower()).value - if entity["code"][-1].lower() == "m": - entity["code"] = entity["code"][:-1] - else: - assert False - entity["code"] = entity["code"].upper() + try: + entity["exchange"] = Exchange(entity["exchange"].lower()).value + if entity["code"][-1].lower() == "m": + entity["code"] = entity["code"][:-1] + else: + assert False + entity["code"] = entity["code"].upper() + except Exception as e: + logger.error(f"wrong item: {item}", e) + continue entity["entity_type"] = "future" entity["name"] = item["name"] @@ -764,10 +768,13 @@ def get_hot_topic(session: Session = None): if data_list: hot_topics = [] for position, data in enumerate(data_list): - entity_ids = [ - market_code_to_entity_id(market=stock["qMarket"], code=stock["qCode"]) - for stock in data["stockList"] - ] + if data["stockList"]: + entity_ids = [ + market_code_to_entity_id(market=stock["qMarket"], code=stock["qCode"]) + for stock in data["stockList"] + ] + else: + entity_ids = [] topic_id = data["topicid"] entity_id = f"hot_topic_{topic_id}" hot_topics.append( diff --git a/src/zvt/rest/work.py b/src/zvt/rest/work.py index 7d552bbf..b2559706 100644 --- a/src/zvt/rest/work.py +++ b/src/zvt/rest/work.py @@ -28,6 +28,7 @@ MainTagIndustryRelation, MainTagSubTagRelation, IndustryInfoModel, + ChangeMainTagModel, ) from zvt.tag.tag_schemas import ( StockTags, @@ -250,3 +251,8 @@ def build_main_tag_sub_tag_relation(relation: MainTagSubTagRelation): tag_service.build_main_tag_sub_tag_relation(main_tag_sub_tag_relation=relation) tag_service.activate_sub_tags(activate_sub_tags_model=ActivateSubTagsModel(sub_tags=relation.sub_tag_list)) return "success" + + +@work_router.post("/change_main_tag", response_model=List[StockTagsModel]) +def change_main_tag(change_main_tag_model: ChangeMainTagModel): + return tag_service.change_main_tag(change_main_tag_model=change_main_tag_model) diff --git a/src/zvt/tag/tag_models.py b/src/zvt/tag/tag_models.py index f2dbded6..bf69cbe7 100644 --- a/src/zvt/tag/tag_models.py +++ b/src/zvt/tag/tag_models.py @@ -37,6 +37,11 @@ class MainTagSubTagRelation(CustomModel): sub_tag_list: List[str] +class ChangeMainTagModel(CustomModel): + current_main_tag: str + new_main_tag: str + + class StockTagsModel(MixinModel): main_tag: Optional[str] = Field(default=None) main_tag_reason: Optional[str] = Field(default=None) diff --git a/src/zvt/tag/tag_service.py b/src/zvt/tag/tag_service.py index ab3373b4..3910fb88 100644 --- a/src/zvt/tag/tag_service.py +++ b/src/zvt/tag/tag_service.py @@ -22,6 +22,7 @@ StockTagOptions, MainTagIndustryRelation, MainTagSubTagRelation, + ChangeMainTagModel, ) from zvt.tag.tag_schemas import ( StockTags, @@ -748,9 +749,45 @@ def build_main_tag_sub_tag_relation(main_tag_sub_tag_relation: MainTagSubTagRela session.commit() +def change_main_tag(change_main_tag_model: ChangeMainTagModel): + new_main_tag = change_main_tag_model.new_main_tag + _create_main_tag_if_not_existed(main_tag=new_main_tag, main_tag_reason=new_main_tag) + with contract_api.DBSession(provider="zvt", data_schema=StockTags)() as session: + stock_tags: List[StockTags] = StockTags.query_data( + filters=[StockTags.main_tag == change_main_tag_model.current_main_tag], + session=session, + return_type="domain", + ) + + for stock_tag in stock_tags: + tag_parameter: TagParameter = build_tag_parameter( + tag_type=TagType.main_tag, + tag=new_main_tag, + tag_reason=new_main_tag, + stock_tag=stock_tag, + ) + set_stock_tags_model = SetStockTagsModel( + entity_id=stock_tag.entity_id, + main_tag=tag_parameter.main_tag, + main_tag_reason=tag_parameter.main_tag_reason, + sub_tag=tag_parameter.sub_tag, + sub_tag_reason=tag_parameter.sub_tag_reason, + active_hidden_tags=stock_tag.active_hidden_tags, + ) + + build_stock_tags( + set_stock_tags_model=set_stock_tags_model, + timestamp=now_pd_timestamp(), + set_by_user=True, + keep_current=False, + ) + session.refresh(stock_tag) + return stock_tags + + if __name__ == "__main__": - # activate_default_main_tag(industry="半导体") - activate_sub_tags(ActivateSubTagsModel(sub_tags=["航天概念", "天基互联", "北斗导航", "通用航空"])) + activate_industry_list(industry_list=["半导体"]) + # activate_sub_tags(ActivateSubTagsModel(sub_tags=["航天概念", "天基互联", "北斗导航", "通用航空"])) # the __all__ is generated