diff --git a/docs/source/_static/compare_cn_us.png b/docs/source/_static/compare_cn_us.png new file mode 100644 index 00000000..7b538462 Binary files /dev/null and b/docs/source/_static/compare_cn_us.png differ diff --git a/docs/source/contributor.rst b/docs/source/contributor.rst new file mode 100644 index 00000000..af08c432 --- /dev/null +++ b/docs/source/contributor.rst @@ -0,0 +1,27 @@ +==================== +Contributor +==================== + +Thanks, my friends. + +* 隋鹏飞 +* `Tiger `_ +* 蓝小球 +* 青玄 +* \*崇 +* \*阳 +* 张凯 +* Rubicon_陈小虾 +* `看门大爷 `_ +* 芝华 +* 雨多田光 +* 叶金荣 +* 冷冷 +* Landy +* Sunny +* Ccc国毅 +* Jim Tong +* tom +* 小七 +* 小强 +* Cascara Latte- 刘可烁 diff --git a/docs/source/data/adding_new_entity.rst b/docs/source/data/adding_new_entity.rst index b82c3e7a..1dfd1be7 100644 --- a/docs/source/data/adding_new_entity.rst +++ b/docs/source/data/adding_new_entity.rst @@ -1,4 +1,4 @@ -.. _add_new_entity: +.. _adding_new_entity: ================= Adding new entity @@ -6,14 +6,8 @@ Adding new entity It's human nature to like the new and hate the old. Adding new TradableEntity is easy in zvt. -And from a higher perspective, trading is everywhere. you make trading everytime when you make the -decision. - -So you could treat Country as TradableEntity and make trading when making decision where to live or invest. - - Adding new entity is nothing than a specific case of :ref:`Adding data `. -Let's show the key steps below. +Let's show the key steps below which add :class:`~.zvt.domain.meta.future_meta.Future`. Define entity Schema -------------------------- @@ -21,52 +15,20 @@ Define entity Schema :: # -*- coding: utf-8 -*- + from sqlalchemy.ext.declarative import declarative_base - from sqlalchemy import Column, String, Float - from sqlalchemy.orm import declarative_base - - from zvt.contract.schema import TradableEntity from zvt.contract.register import register_schema, register_entity + from zvt.contract.schema import TradableEntity - CountryMetaBase = declarative_base() - - - @register_entity(entity_type="country") - class Country(CountryMetaBase, TradableEntity): - __tablename__ = "country" - - #: 区域 - #: region - region = Column(String(length=128)) - #: 首都 - #: capital city - capital_city = Column(String(length=128)) - #: 收入水平 - #: income level - income_level = Column(String(length=64)) - #: 贷款类型 - #: lending type - lending_type = Column(String(length=64)) - #: 经度 - #: longitude - longitude = Column(Float) - #: 纬度 - #: latitude - latitude = Column(Float) - - - register_schema(providers=["wb"], db_name="country_meta", schema_base=CountryMetaBase) - -entity_type, exchange and code define the entity, for country, it's in following way: + FutureMetaBase = declarative_base() -:: - entity_type = "country" - exchange = "galaxy" - code = "iso code" + @register_entity(entity_type="future") + class Future(FutureMetaBase, TradableEntity): + __tablename__ = "future" -e.g. country_galaxy_CN = China, country_galaxy_US = United States of America + register_schema(providers=["em"], db_name="future_meta", schema_base=FutureMetaBase) Implement recorder for the entity --------------------------------- @@ -75,88 +37,121 @@ Implement recorder for the entity from zvt.contract.api import df_to_db from zvt.contract.recorder import Recorder - from zvt.domain.meta.country_meta import Country - from zvt.recorders.wb import wb_api + from zvt.domain import Future + from zvt.recorders.em import em_api - class WBCountryRecorder(Recorder): - provider = "wb" - data_schema = Country + class EMFutureRecorder(Recorder): + provider = "em" + data_schema = Future def run(self): - df = wb_api.get_countries() + df = em_api.get_tradable_list(entity_type="future") + self.logger.info(df) df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update) -Define schema for the entity ----------------------------- -e.g treasury yield of the country +Define OHLC schema(kdata) for the entity +---------------------------------------- + +zvt provide a standard way to generate OHLC schema for the tradable entity. +All `OHLC schemas `_ is generated by +`fill project script `_. + +e.g generate Future OHLC schema. + :: - # -*- coding: utf-8 -*- - from sqlalchemy import Column, String, Float - from sqlalchemy.orm import declarative_base + gen_kdata_schema( + pkg="zvt", + providers=["em"], + entity_type="future", + levels=[IntervalLevel.LEVEL_1DAY], + entity_in_submodule=True, + ) + +The OHLC schema definition principle is: **one level one file** - from zvt.contract import Mixin - from zvt.contract.register import register_schema +So we would define a common OHLC schema for each entity type in `quotes module `_. - CurrencyBase = declarative_base() +e.g. Future common OHLC schema +:: + + class FutureKdataCommon(KdataCommon): + #: 持仓量 + interest = Column(Float) + #: 结算价 + settlement = Column(Float) + #: 涨跌幅(按收盘价) + # change_pct = Column(Float) + #: 涨跌幅(按结算价) + change_pct1 = Column(Float) + +And we could relate the common kdata schema with the recorder and route level to specific schema automatically. - class TreasuryYield(CurrencyBase, Mixin): - __tablename__ = "treasury_yield" +Implement recorder for OHLC schema(kdata) +----------------------------------------- - code = Column(String(length=32)) +Check `em quotes recorder `_ for +the details. - # 2年期 - yield_2 = Column(Float) - # 5年期 - yield_5 = Column(Float) - # 10年期 - yield_10 = Column(Float) - # 30年期 - yield_30 = Column(Float) +:: + class EMFutureKdataRecorder(BaseEMStockKdataRecorder): + entity_provider = "em" + entity_schema = Future - register_schema(providers=["em"], db_name="currency", schema_base=CurrencyBase) + data_schema = FutureKdataCommon -And the `recorder `_ for the schema Use them in zvt way ------------------- -Find the rich country: +Fetch the entity list: :: - >>> from zvt.domain import Country - >>> Country.record_data() - >>> df = Country.query_data() - >>> df[df['income_level']=='High income'] - - id entity_id timestamp entity_type exchange code name list_date end_date region capital_city income_level lending_type longitude latitude - 0 country_galaxy_AW country_galaxy_AW None country galaxy AW Aruba None None Latin America & Caribbean Oranjestad High income Not classified -70.016700 12.516700 - 7 country_galaxy_AD country_galaxy_AD None country galaxy AD Andorra None None Europe & Central Asia Andorra la Vella High income Not classified 1.521800 42.507500 - 9 country_galaxy_AE country_galaxy_AE None country galaxy AE United Arab Emirates None None Middle East & North Africa Abu Dhabi High income Not classified 54.370500 24.476400 - 13 country_galaxy_AG country_galaxy_AG None country galaxy AG Antigua and Barbuda None None Latin America & Caribbean Saint John's High income IBRD -61.845600 17.117500 - 14 country_galaxy_AU country_galaxy_AU None country galaxy AU Australia None None East Asia & Pacific Canberra High income Not classified 149.129000 -35.282000 - .. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... - 277 country_galaxy_TW country_galaxy_TW None country galaxy TW Taiwan, China None None East Asia & Pacific High income Not classified NaN NaN - 282 country_galaxy_UY country_galaxy_UY None country galaxy UY Uruguay None None Latin America & Caribbean Montevideo High income IBRD -56.067500 -34.894100 - 283 country_galaxy_US country_galaxy_US None country galaxy US United States None None North America Washington D.C. High income Not classified -77.032000 38.889500 - 287 country_galaxy_VG country_galaxy_VG None country galaxy VG British Virgin Islands None None Latin America & Caribbean Road Town High income Not classified -64.623056 18.431389 - 288 country_galaxy_VI country_galaxy_VI None country galaxy VI Virgin Islands (U.S.) None None Latin America & Caribbean Charlotte Amalie High income Not classified -64.896300 18.335800 + >>> from zvt.domain import Future + >>> Future.record_data() + >>> df = Future.query_data() + >>> print(df) - [80 rows x 15 columns] + id entity_id timestamp entity_type exchange code name list_date end_date + 0 future_cffex_IC future_cffex_IC NaT future cffex IC 中证当月连续 NaT None + 1 future_cffex_IF future_cffex_IF NaT future cffex IF 沪深当月连续 NaT None + 2 future_cffex_IH future_cffex_IH NaT future cffex IH 上证当月连续 NaT None + 3 future_cffex_T future_cffex_T NaT future cffex T 十债当季连续 NaT None + 4 future_cffex_TF future_cffex_TF NaT future cffex TF 五债当季连续 NaT None + .. ... ... ... ... ... ... ... ... ... + 65 future_ine_LU future_ine_LU 2020-06-22 future ine LU 低硫燃油主力 2020-06-22 None + 66 future_czce_PF future_czce_PF 2020-10-12 future czce PF 短纤主力 2020-10-12 None + 67 future_ine_BC future_ine_BC 2020-11-19 future ine BC 国际铜主力 2020-11-19 None + 68 future_dce_LH future_dce_LH 2021-01-08 future dce LH 生猪主力 2021-01-08 None + 69 future_czce_PK future_czce_PK 2021-02-01 future czce PK 花生主力 2021-02-01 None + [70 rows x 9 columns] -Compare treasury yields of different maturities: +Fetch the quotes: :: - >>> from zvt.domain import TreasuryYield - >>> from zvt.api.intent import compare - >>> TreasuryYield.record_data() - >>> compare(codes=["US"], schema=TreasuryYield, columns=["yield_2", "yield_10", "yield_30"]) - -.. image:: ../_static/compare_yields.png \ No newline at end of file + >>> from zvt.domain import Future1dKdata + >>> Future1dKdata.record_data(code="CU") + >>> df = Future1dKdata.query_data(code="CU") + >>> print(df) + + id entity_id timestamp provider code name level open close high low volume turnover change_pct turnover_rate interest settlement change_pct1 + 0 future_shfe_CU_1996-04-03 future_shfe_CU 1996-04-03 em CU 沪铜主力 1d 22930.0 22840.0 23000.0 22840.0 353.0 0.000000e+00 0.0000 0.0 None None None + 1 future_shfe_CU_1996-04-04 future_shfe_CU 1996-04-04 em CU 沪铜主力 1d 22700.0 22750.0 22820.0 22650.0 251.0 0.000000e+00 -0.0039 0.0 None None None + 2 future_shfe_CU_1996-04-05 future_shfe_CU 1996-04-05 em CU 沪铜主力 1d 22520.0 22780.0 22820.0 22500.0 298.0 0.000000e+00 0.0013 0.0 None None None + 3 future_shfe_CU_1996-04-08 future_shfe_CU 1996-04-08 em CU 沪铜主力 1d 22660.0 22650.0 22680.0 22600.0 98.0 0.000000e+00 -0.0057 0.0 None None None + 4 future_shfe_CU_1996-04-09 future_shfe_CU 1996-04-09 em CU 沪铜主力 1d 22830.0 22810.0 22860.0 22810.0 56.0 0.000000e+00 0.0071 0.0 None None None + ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... + 6343 future_shfe_CU_2022-04-21 future_shfe_CU 2022-04-21 em CU 沪铜主力 1d 74140.0 74480.0 74750.0 74140.0 48008.0 1.787678e+10 -0.0004 0.0 None None None + 6344 future_shfe_CU_2022-04-22 future_shfe_CU 2022-04-22 em CU 沪铜主力 1d 74800.0 75010.0 75200.0 74690.0 58874.0 2.205633e+10 0.0073 0.0 None None None + 6345 future_shfe_CU_2022-04-25 future_shfe_CU 2022-04-25 em CU 沪铜主力 1d 74900.0 73660.0 75190.0 73660.0 107455.0 3.989090e+10 -0.0168 0.0 None None None + 6346 future_shfe_CU_2022-04-26 future_shfe_CU 2022-04-26 em CU 沪铜主力 1d 73170.0 73260.0 73750.0 72500.0 113019.0 4.130931e+10 -0.0132 0.0 None None None + 6347 future_shfe_CU_2022-04-27 future_shfe_CU 2022-04-27 em CU 沪铜主力 1d 72990.0 73100.0 73560.0 72910.0 61563.0 2.254089e+10 0.0000 0.0 None None None + + [6348 rows x 18 columns] diff --git a/docs/source/data/index.rst b/docs/source/data/index.rst index 3628432e..5ed8a7f7 100644 --- a/docs/source/data/index.rst +++ b/docs/source/data/index.rst @@ -22,3 +22,4 @@ Data record_and_query extending_data adding_new_entity + trading_anything diff --git a/docs/source/data/trading_anything.rst b/docs/source/data/trading_anything.rst new file mode 100644 index 00000000..261d60bc --- /dev/null +++ b/docs/source/data/trading_anything.rst @@ -0,0 +1,162 @@ +.. trading_anything: + +======================= +Capital without country +======================= + +From a higher perspective, trading is everywhere. you make trading everytime when you make the +decision. + +So you could treat Country as TradableEntity and make trading when making decision where to live or invest. + +It's nothing than a specific case of :ref:`Adding new entity `. + +Let's show the key steps below. + +Define entity Schema +-------------------------- + +:: + + # -*- coding: utf-8 -*- + + from sqlalchemy import Column, String, Float + from sqlalchemy.orm import declarative_base + + from zvt.contract.schema import TradableEntity + from zvt.contract.register import register_schema, register_entity + + CountryMetaBase = declarative_base() + + + @register_entity(entity_type="country") + class Country(CountryMetaBase, TradableEntity): + __tablename__ = "country" + + #: 区域 + #: region + region = Column(String(length=128)) + #: 首都 + #: capital city + capital_city = Column(String(length=128)) + #: 收入水平 + #: income level + income_level = Column(String(length=64)) + #: 贷款类型 + #: lending type + lending_type = Column(String(length=64)) + #: 经度 + #: longitude + longitude = Column(Float) + #: 纬度 + #: latitude + latitude = Column(Float) + + + register_schema(providers=["wb"], db_name="country_meta", schema_base=CountryMetaBase) + +entity_type, exchange and code define the entity, for country, it's in following way: + +:: + + entity_type = "country" + exchange = "galaxy" + code = "iso code" + +e.g. country_galaxy_CN = China, country_galaxy_US = United States of America + + +Implement recorder for the entity +--------------------------------- + +:: + + from zvt.contract.api import df_to_db + from zvt.contract.recorder import Recorder + from zvt.domain.meta.country_meta import Country + from zvt.recorders.wb import wb_api + + + class WBCountryRecorder(Recorder): + provider = "wb" + data_schema = Country + + def run(self): + df = wb_api.get_countries() + df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update) + +Define schema for the entity +---------------------------- + +e.g treasury yield of the country +:: + + # -*- coding: utf-8 -*- + from sqlalchemy import Column, String, Float + from sqlalchemy.orm import declarative_base + + from zvt.contract import Mixin + from zvt.contract.register import register_schema + + MonetaryBase = declarative_base() + + + class TreasuryYield(MonetaryBase, Mixin): + __tablename__ = "treasury_yield" + + code = Column(String(length=32)) + + # 2年期 + yield_2 = Column(Float) + # 5年期 + yield_5 = Column(Float) + # 10年期 + yield_10 = Column(Float) + # 30年期 + yield_30 = Column(Float) + + + register_schema(providers=["em"], db_name="monetary", schema_base=MonetaryBase) + # the __all__ is generated + __all__ = ["TreasuryYield"] + +And the `recorder `_ for the schema + +Use them in zvt way +------------------- + +Find the rich country: + +:: + + >>> from zvt.domain import Country + >>> Country.record_data() + >>> df = Country.query_data() + >>> df[df['income_level']=='High income'] + + id entity_id timestamp entity_type exchange code name list_date end_date region capital_city income_level lending_type longitude latitude + 0 country_galaxy_AW country_galaxy_AW None country galaxy AW Aruba None None Latin America & Caribbean Oranjestad High income Not classified -70.016700 12.516700 + 7 country_galaxy_AD country_galaxy_AD None country galaxy AD Andorra None None Europe & Central Asia Andorra la Vella High income Not classified 1.521800 42.507500 + 9 country_galaxy_AE country_galaxy_AE None country galaxy AE United Arab Emirates None None Middle East & North Africa Abu Dhabi High income Not classified 54.370500 24.476400 + 13 country_galaxy_AG country_galaxy_AG None country galaxy AG Antigua and Barbuda None None Latin America & Caribbean Saint John's High income IBRD -61.845600 17.117500 + 14 country_galaxy_AU country_galaxy_AU None country galaxy AU Australia None None East Asia & Pacific Canberra High income Not classified 149.129000 -35.282000 + .. ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... + 277 country_galaxy_TW country_galaxy_TW None country galaxy TW Taiwan, China None None East Asia & Pacific High income Not classified NaN NaN + 282 country_galaxy_UY country_galaxy_UY None country galaxy UY Uruguay None None Latin America & Caribbean Montevideo High income IBRD -56.067500 -34.894100 + 283 country_galaxy_US country_galaxy_US None country galaxy US United States None None North America Washington D.C. High income Not classified -77.032000 38.889500 + 287 country_galaxy_VG country_galaxy_VG None country galaxy VG British Virgin Islands None None Latin America & Caribbean Road Town High income Not classified -64.623056 18.431389 + 288 country_galaxy_VI country_galaxy_VI None country galaxy VI Virgin Islands (U.S.) None None Latin America & Caribbean Charlotte Amalie High income Not classified -64.896300 18.335800 + + [80 rows x 15 columns] + + +Compare treasury yields of different maturities: + +:: + + >>> from zvt.domain import TreasuryYield + >>> from zvt.api.intent import compare + >>> TreasuryYield.record_data() + >>> compare(codes=["US"], schema=TreasuryYield, columns=["yield_2", "yield_10", "yield_30"]) + +.. image:: ../_static/compare_yields.png \ No newline at end of file diff --git a/docs/source/drawer/drawer_concepts.rst b/docs/source/drawer/drawer_concepts.rst index 34c6122f..5c580086 100644 --- a/docs/source/drawer/drawer_concepts.rst +++ b/docs/source/drawer/drawer_concepts.rst @@ -6,22 +6,34 @@ Drawer concepts Intent ------------------------------ There are many kinds of charts, but the intent is much less. zvt classify -intent as change, distribute, composite and compare. +intent as compare, distribute and composite. We could analyze the entity itself or look at it in the whole market by comparing with others. :ref:`NormalData` uses -different structure to express different intent. +different structure to express different intent.s -one entity -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Compare +------------------------------ +Based on zvt's world view and data model, you could compare anything you care about. +Think about that you want to compare S&P 500 index with Shanghai index. It's easy +and comfortable with no pain. -multiple entities -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: -* compare + >>> from zvt.api.intent import compare + >>> from zvt.domain import Indexus1dKdata, Index, Indexus, Index1dKdata + >>> Index.record_data(provider="em") + >>> Indexus.record_data(provider="em") + >>> Index1dKdata.record_data(entity_id="index_sh_000001", provider="em") + >>> Indexus1dKdata.record_data(entity_id="indexus_us_SPX", provider="em") + >>> compare(entity_ids=["index_sh_000001", "indexus_us_SPX"], start_timestamp="2000-01-01", scale_value=100) -Drawer ------------------------------- -Drawer is who can draw the picture with NormalData by Intent. \ No newline at end of file +.. image:: ../_static/compare_cn_us.png + +Try some other style: + +:: + + >>> compare(entity_ids=["index_sh_000001", "indexus_us_SPX"], start_timestamp="2000-01-01", schema_map_columns={Index1dKdata:["close"],Indexus1dKdata:["close"]}) diff --git a/docs/source/index.rst b/docs/source/index.rst index 1f6fb9a2..86d36672 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -14,6 +14,7 @@ Contents trader/index ml/index drawer/index + contributor api/index Indices and tables diff --git a/examples/data_runner/index_runner.py b/examples/data_runner/index_runner.py index 3b27f079..ca3736c0 100644 --- a/examples/data_runner/index_runner.py +++ b/examples/data_runner/index_runner.py @@ -24,8 +24,9 @@ def record_index(): @sched.scheduled_job("cron", hour=16, minute=20) def record_index_kdata(): + run_data_recorder(domain=Index, data_provider="em") run_data_recorder( - domain=Index1dKdata, data_provider="em", entity_provider="exchange", codes=IMPORTANT_INDEX, day_data=True + domain=Index1dKdata, data_provider="em", entity_provider="em", codes=IMPORTANT_INDEX, day_data=True ) diff --git a/examples/intent/intent.py b/examples/intent/intent.py index d6c0216a..c00eb7f9 100644 --- a/examples/intent/intent.py +++ b/examples/intent/intent.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from zvt.api.intent import compare -from zvt.domain import Indexus1dKdata, Index, Indexus, Index1dKdata +from zvt.domain import Indexus1dKdata, Index, Indexus, Index1dKdata, Currency, Currency1dKdata from zvt.domain import TreasuryYield @@ -57,9 +57,21 @@ def compare_udi_and_stock(): ) +def compare_cny_and_stock(): + Currency1dKdata.record_data(entity_id="currency_forex_USDCNYC") + entity_ids = ["index_sh_000001", "currency_forex_USDCNYC"] + compare( + entity_ids=entity_ids, + start_timestamp="2005-01-01", + scale_value=100, + schema_map_columns={Currency1dKdata: ["close"], Index1dKdata: ["close"]}, + ) + + if __name__ == "__main__": # compare_kline() # us_yield_and_stock() # commodity_and_stock() # compare_metal() - compare_udi_and_stock() + # compare_udi_and_stock() + compare_cny_and_stock() diff --git a/src/zvt/contract/__init__.py b/src/zvt/contract/__init__.py index 7114857d..d88a23f3 100644 --- a/src/zvt/contract/__init__.py +++ b/src/zvt/contract/__init__.py @@ -158,6 +158,9 @@ class TradableType(Enum): #: A股(中国) #: China stock stock = "stock" + #: A股指数(中国) + #: China index + index = "index" #: A股板块(中国) #: China stock block block = "block" @@ -225,10 +228,12 @@ class Exchange(Enum): #: 外汇交易所(虚拟) #: currency exchange(virtual) forex = "forex" + #: 人民币中间价 tradable_type_map_exchanges = { TradableType.block: [Exchange.cn], + TradableType.index: [Exchange.sh, Exchange.sz], TradableType.stock: [Exchange.sh, Exchange.sz], TradableType.stockhk: [Exchange.hk], TradableType.stockus: [Exchange.nasdaq, Exchange.nyse], diff --git a/src/zvt/domain/macro/__init__.py b/src/zvt/domain/macro/__init__.py index e4556534..96244dbe 100644 --- a/src/zvt/domain/macro/__init__.py +++ b/src/zvt/domain/macro/__init__.py @@ -6,11 +6,11 @@ # common code of the package # export interface in __all__ which contains __all__ of its sub modules -# import all from submodule currency -from .currency import * -from .currency import __all__ as _currency_all +# import all from submodule monetary +from .monetary import * +from .monetary import __all__ as _monetary_all -__all__ += _currency_all +__all__ += _monetary_all # import all from submodule macro from .macro import * diff --git a/src/zvt/domain/macro/macro.py b/src/zvt/domain/macro/macro.py index 68bc4fef..f17b96d7 100644 --- a/src/zvt/domain/macro/macro.py +++ b/src/zvt/domain/macro/macro.py @@ -38,21 +38,6 @@ class Economy(MacroBase, Mixin): fdi_of_gdp = Column(Float) -class TreasuryYield(MacroBase, Mixin): - __tablename__ = "treasury_yield" - - code = Column(String(length=32)) - - # 2年期 - yield_2 = Column(Float) - # 5年期 - yield_5 = Column(Float) - # 10年期 - yield_10 = Column(Float) - # 30年期 - yield_30 = Column(Float) - - register_schema(providers=["wb"], db_name="macro", schema_base=MacroBase) # the __all__ is generated -__all__ = ["Economy", "TreasuryYield"] +__all__ = ["Economy"] diff --git a/src/zvt/domain/macro/currency.py b/src/zvt/domain/macro/monetary.py similarity index 76% rename from src/zvt/domain/macro/currency.py rename to src/zvt/domain/macro/monetary.py index ffce48b0..239a1b10 100644 --- a/src/zvt/domain/macro/currency.py +++ b/src/zvt/domain/macro/monetary.py @@ -5,10 +5,10 @@ from zvt.contract import Mixin from zvt.contract.register import register_schema -CurrencyBase = declarative_base() +MonetaryBase = declarative_base() -class TreasuryYield(CurrencyBase, Mixin): +class TreasuryYield(MonetaryBase, Mixin): __tablename__ = "treasury_yield" code = Column(String(length=32)) @@ -23,6 +23,6 @@ class TreasuryYield(CurrencyBase, Mixin): yield_30 = Column(Float) -register_schema(providers=["em"], db_name="currency", schema_base=CurrencyBase) +register_schema(providers=["em"], db_name="monetary", schema_base=MonetaryBase) # the __all__ is generated __all__ = ["TreasuryYield"] diff --git a/src/zvt/domain/meta/index_meta.py b/src/zvt/domain/meta/index_meta.py index c100c318..5539f0b8 100644 --- a/src/zvt/domain/meta/index_meta.py +++ b/src/zvt/domain/meta/index_meta.py @@ -27,6 +27,6 @@ class IndexStock(IndexMetaBase, PortfolioStockHistory): __tablename__ = "index_stock" -register_schema(providers=["exchange"], db_name="index_meta", schema_base=IndexMetaBase) +register_schema(providers=["em", "exchange"], db_name="index_meta", schema_base=IndexMetaBase) # the __all__ is generated __all__ = ["Index", "IndexStock"] diff --git a/src/zvt/fill_project.py b/src/zvt/fill_project.py index 81484f10..0ab7d38d 100644 --- a/src/zvt/fill_project.py +++ b/src/zvt/fill_project.py @@ -89,11 +89,11 @@ def gen_kdata_schemas(): # gen_exports("contract", export_modules=["schema"]) # gen_exports("ml") # gen_exports("utils") - gen_exports("recorders") - # gen_exports("domain") # gen_exports('informer') # gen_exports('api') # gen_exports('trader') # gen_exports('autocode') # gen_exports("ml") gen_kdata_schemas() + gen_exports("recorders") + gen_exports("domain") diff --git a/src/zvt/plugin.py b/src/zvt/plugin.py index 209d2554..38809760 100644 --- a/src/zvt/plugin.py +++ b/src/zvt/plugin.py @@ -30,5 +30,5 @@ def export(): if __name__ == "__main__": - gen_plugin_project(dir_path="../../", entity_type="macro", providers=["zvt"]) + gen_plugin_project(dir_path="../../../", entity_type="macro", providers=["zvt"]) main() diff --git a/src/zvt/recorders/em/em_api.py b/src/zvt/recorders/em/em_api.py index 32f01498..4e77c819 100644 --- a/src/zvt/recorders/em/em_api.py +++ b/src/zvt/recorders/em/em_api.py @@ -424,7 +424,14 @@ def get_tradable_list( ex_flag = to_em_entity_flag(exchange=exchange) entity_flag = f"fs=m:{ex_flag}" - if entity_type == TradableType.indexus: + if entity_type == TradableType.index: + if exchange == Exchange.sh: + entity_flag = "fs=i:1.000001,i:1.000002,i:1.000003,i:1.000009,i:1.000010,i:1.000011,i:1.000012,i:1.000016,i:1.000300,i:1.000903,i:1.000905,i:1.000906,i:1.000688" + if exchange == Exchange.sz: + entity_flag = "fs=i:0.399001,i:0.399002,i:0.399003,i:0.399004,i:0.399005,i:0.399006,i:0.399100,i:0.399106,i:0.399305,i:0.399550" + elif entity_type == TradableType.currency: + entity_flag = "fs=m:119,m:120" + elif entity_type == TradableType.indexus: # 纳斯达克,道琼斯,标普500,美元指数 entity_flag = "fs=i:100.NDX,i:100.DJIA,i:100.SPX,i:100.UDI" # m为交易所代码,t为交易类型 @@ -569,7 +576,7 @@ def to_em_fc(entity_id): def to_em_entity_flag(exchange: Union[Exchange, str]): exchange = Exchange(exchange) - return exchange_map_em_flag.get(exchange) + return exchange_map_em_flag.get(exchange, exchange) def to_em_fq_flag(adjust_type: AdjustType): @@ -607,6 +614,8 @@ def to_em_sec_id(entity_id): # 主力合约 if entity_type == "future" and code[-1].isalpha(): code = code + "m" + if entity_type == "currency" and "CNYC" in code: + return f"120.{code}" return f"{to_em_entity_flag(exchange)}.{code}" @@ -649,7 +658,8 @@ def to_zvt_code(code): # print(len(df)) # df = get_tradable_list(entity_type="block") # df = get_tradable_list(entity_type="indexus") - df = get_tradable_list(entity_type="currency") + # df = get_tradable_list(entity_type="currency") + df = get_tradable_list(entity_type="index") # df = get_kdata(entity_id="index_us_SPX", level="1d") # print(df) # df = get_treasury_yield(pn=1, ps=50, fetch_all=False) diff --git a/src/zvt/recorders/em/macro/em_treasury_yield_recorder.py b/src/zvt/recorders/em/macro/em_treasury_yield_recorder.py index 8e15356a..e69e44f9 100644 --- a/src/zvt/recorders/em/macro/em_treasury_yield_recorder.py +++ b/src/zvt/recorders/em/macro/em_treasury_yield_recorder.py @@ -5,7 +5,7 @@ from zvt.contract.api import df_to_db from zvt.contract.recorder import FixedCycleDataRecorder from zvt.domain import Country -from zvt.domain.macro import TreasuryYield +from zvt.domain.macro.monetary import TreasuryYield from zvt.recorders.em import em_api diff --git a/src/zvt/recorders/em/meta/__init__.py b/src/zvt/recorders/em/meta/__init__.py index 06cbd013..490b2e4e 100644 --- a/src/zvt/recorders/em/meta/__init__.py +++ b/src/zvt/recorders/em/meta/__init__.py @@ -6,6 +6,12 @@ # common code of the package # export interface in __all__ which contains __all__ of its sub modules +# import all from submodule em_index_meta_recorder +from .em_index_meta_recorder import * +from .em_index_meta_recorder import __all__ as _em_index_meta_recorder_all + +__all__ += _em_index_meta_recorder_all + # import all from submodule em_stockus_meta_recorder from .em_stockus_meta_recorder import * from .em_stockus_meta_recorder import __all__ as _em_stockus_meta_recorder_all diff --git a/src/zvt/recorders/em/meta/em_index_meta_recorder.py b/src/zvt/recorders/em/meta/em_index_meta_recorder.py new file mode 100644 index 00000000..cff1bf34 --- /dev/null +++ b/src/zvt/recorders/em/meta/em_index_meta_recorder.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from zvt.contract.api import df_to_db +from zvt.contract.recorder import Recorder +from zvt.domain import Index +from zvt.recorders.em import em_api + + +class EMIndexRecorder(Recorder): + provider = "em" + data_schema = Index + + def run(self): + df = em_api.get_tradable_list(entity_type="index") + self.logger.info(df) + df_to_db(df=df, data_schema=self.data_schema, provider=self.provider, force_update=self.force_update) + + +if __name__ == "__main__": + recorder = EMIndexRecorder() + recorder.run() +# the __all__ is generated +__all__ = ["EMIndexRecorder"] diff --git a/src/zvt/recorders/em/quotes/em_kdata_recorder.py b/src/zvt/recorders/em/quotes/em_kdata_recorder.py index 9872ddbd..5758bb30 100644 --- a/src/zvt/recorders/em/quotes/em_kdata_recorder.py +++ b/src/zvt/recorders/em/quotes/em_kdata_recorder.py @@ -128,7 +128,7 @@ class EMStockhkKdataRecorder(BaseEMStockKdataRecorder): class EMIndexKdataRecorder(BaseEMStockKdataRecorder): - entity_provider = "exchange" + entity_provider = "em" entity_schema = Index data_schema = IndexKdataCommon @@ -177,4 +177,5 @@ class EMCurrencyKdataRecorder(BaseEMStockKdataRecorder): "EMIndexusKdataRecorder", "EMBlockKdataRecorder", "EMFutureKdataRecorder", + "EMCurrencyKdataRecorder", ] diff --git a/src/zvt/utils/utils.py b/src/zvt/utils/utils.py index aa47e034..15ec7daf 100644 --- a/src/zvt/utils/utils.py +++ b/src/zvt/utils/utils.py @@ -221,7 +221,7 @@ def set_one_and_only_one(**kwargs): if __name__ == "__main__": url = url_unquote( - "https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=2&invt=2&fields=f1,f2,f3,f4,f12,f13,f14&pn=1&pz=30&fid=f3&po=1&fs=i:119.USDNZD,i:119.THBUSD,i:119.AUDUSD,i:119.ZARUSD,i:119.EURUSD,i:119.CZKUSD,i:119.DKKUSD,i:119.SEKUSD,i:119.MXNUSD,i:119.NOKUSD,i:119.PLNUSD,i:119.SGDUSD,i:119.GBPUSD,i:119.USDHKD,i:119.INRUSD,i:119.HUFUSD,i:119.TRYUSD,i:119.SARUSD,i:119.HKDUSD,i:119.USDJPY,i:119.USDCHF,i:119.USDGBP,i:119.USDSGD,i:119.USDCAD,i:119.USDTHB,i:119.USDNOK,i:119.USDDKK,i:119.USDSEK,i:119.USDEUR,i:119.USDAUD&ut=f057cbcbce2a86e2866ab8877db1d059&forcect=1&cb=cbCallback&&callback=jQuery34105658946316352569_1650874211986&_=1650874211988" + "https://push2.eastmoney.com/api/qt/clist/get?cb=jQuery341011493786409034579_1651073788955&ut=bd1d9ddb04089700cf9c27f6f7426281&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f23,f24,f25,f22,f11,f62,f104,f105,f111,f128,f136,f115,f148,f152&np=1&fltt=2&invt=2&pn=1&fs=i:1.000001,i:1.000002,i:1.000003,i:1.000009,i:1.000010,i:1.000011,i:1.000012,i:1.000016,i:1.000300,i:1.000903,i:1.000905,i:1.000906,i:0.399001,i:0.399002,i:0.399003,i:0.399004,i:0.399005,i:0.399006,i:0.399100,i:0.399106,i:0.399305,i:0.399550,i:1.000688&fid=f3&po=1&pz=40&_=1651073788967" ) print(url)