From cfdff34a9a8958b7186388a17da70956d470efd7 Mon Sep 17 00:00:00 2001 From: Edanflame <237397488@qq.com> Date: Thu, 11 Nov 2021 11:06:01 +0800 Subject: [PATCH 1/5] =?UTF-8?q?[Mod]=20=E6=B7=BB=E5=8A=A0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BD=BF=E7=94=A8=E4=BA=8B=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index b16ac7c..a34faff 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,9 @@ 注意:需要使用相应的数据服务权限,可以通过[该页面](https://www.tushare.pro)注册使用。 +## 数据使用事项 + +tushare数据源期货数据中,第一条夜盘k线数据是集合竞价数据,用户可以根据自己需求进行过滤或者合并。 ## 安装 From 04a1668842ca4a3d08b6e06863f78a2ec2ba31c7 Mon Sep 17 00:00:00 2001 From: Edanflame <237397488@qq.com> Date: Thu, 11 Nov 2021 11:15:43 +0800 Subject: [PATCH 2/5] =?UTF-8?q?[Fix]=20=E5=8F=8D=E8=BD=AC=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=A1=BA=E5=BA=8F=EF=BC=8C=E6=8C=89=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E5=8D=87=E5=BA=8F=E6=8E=92=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy_tushare/tushare_datafeed.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/vnpy_tushare/tushare_datafeed.py b/vnpy_tushare/tushare_datafeed.py index f1749a6..1cae3a6 100644 --- a/vnpy_tushare/tushare_datafeed.py +++ b/vnpy_tushare/tushare_datafeed.py @@ -1,6 +1,6 @@ from datetime import timedelta, datetime from pytz import timezone -from typing import List, Optional +from typing import Dict, List, Optional from copy import deepcopy import pandas as pd @@ -9,7 +9,7 @@ from vnpy.trader.setting import SETTINGS from vnpy.trader.datafeed import BaseDatafeed from vnpy.trader.constant import Exchange, Interval -from vnpy.trader.object import BarData, TickData, HistoryRequest +from vnpy.trader.object import BarData, HistoryRequest from vnpy.trader.utility import round_to INTERVAL_VT2TS = { @@ -190,6 +190,8 @@ def query_bar_history(self, req: HistoryRequest) -> Optional[List[BarData]]: ) df = pd.concat([df[:-1], d1]) + bar_keys: List[datetime] = [] + bar_dict: Dict[datetime, BarData] = {} data: List[BarData] = [] if df is not None: @@ -206,7 +208,7 @@ def query_bar_history(self, req: HistoryRequest) -> Optional[List[BarData]]: dt = CHINA_TZ.localize(dt) - bar = BarData( + bar: BarData = BarData( symbol=symbol, exchange=exchange, interval=interval, @@ -221,6 +223,11 @@ def query_bar_history(self, req: HistoryRequest) -> Optional[List[BarData]]: gateway_name="TS" ) - data.append(bar) + bar_dict[dt] = bar + + bar_keys = bar_dict.keys() + bar_keys = sorted(bar_keys, reverse=False) + for i in bar_keys: + data.append(bar_dict[i]) return data From 8c1636dd48e7726497b1f90b9205852f4150dbf2 Mon Sep 17 00:00:00 2001 From: Edanflame <237397488@qq.com> Date: Wed, 17 Nov 2021 14:18:45 +0800 Subject: [PATCH 3/5] =?UTF-8?q?[Fix]=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E5=80=BC=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy_tushare/tushare_datafeed.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vnpy_tushare/tushare_datafeed.py b/vnpy_tushare/tushare_datafeed.py index 1cae3a6..1077517 100644 --- a/vnpy_tushare/tushare_datafeed.py +++ b/vnpy_tushare/tushare_datafeed.py @@ -194,6 +194,9 @@ def query_bar_history(self, req: HistoryRequest) -> Optional[List[BarData]]: bar_dict: Dict[datetime, BarData] = {} data: List[BarData] = [] + # 处理原始数据中的NaN值 + df.fillna(0, inplace=True) + if df is not None: for ix, row in df.iterrows(): if row["open"] is None: From 3b473f79f8cb2fcb3ae7bafb81b216274cfea789 Mon Sep 17 00:00:00 2001 From: Edanflame <237397488@qq.com> Date: Wed, 17 Nov 2021 16:03:30 +0800 Subject: [PATCH 4/5] =?UTF-8?q?[Mod]=20=E5=A2=9E=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E8=82=A1=E7=A5=A8=E6=8C=87=E6=95=B0=E5=92=8C=E5=8C=97=E4=BA=A4?= =?UTF-8?q?=E6=89=80=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy_tushare/tushare_datafeed.py | 100 ++++++++++++++++++------------- 1 file changed, 60 insertions(+), 40 deletions(-) diff --git a/vnpy_tushare/tushare_datafeed.py b/vnpy_tushare/tushare_datafeed.py index 1077517..1e413ba 100644 --- a/vnpy_tushare/tushare_datafeed.py +++ b/vnpy_tushare/tushare_datafeed.py @@ -12,32 +12,44 @@ from vnpy.trader.object import BarData, HistoryRequest from vnpy.trader.utility import round_to +# 数据频率映射 INTERVAL_VT2TS = { Interval.MINUTE: "1min", Interval.HOUR: "60min", Interval.DAILY: "D", } -ASSET_VT2TS = { - Exchange.CFFEX: "FT", - Exchange.SHFE: "FT", - Exchange.CZCE: "FT", - Exchange.DCE: "FT", - Exchange.INE: "FT", - Exchange.SSE: "E", - Exchange.SZSE: "E", - Exchange.BITMEX: "C", - Exchange.BITSTAMP: "C", - Exchange.OKEX: "C", - Exchange.HUOBI: "C", - Exchange.BITFINEX: "C", - Exchange.BINANCE: "C", - Exchange.BYBIT: "C", - Exchange.COINBASE: "C", - Exchange.DERIBIT: "C", - Exchange.GATEIO: "C", -} - +# 股票支持列表 +STOCK_LIST = [ + Exchange.SSE, + Exchange.SZSE, + Exchange.BSE, +] + +# 期货支持列表 +FUTURE_LIST = [ + Exchange.CFFEX, + Exchange.SHFE, + Exchange.CZCE, + Exchange.DCE, + Exchange.INE, +] + +# 数字货币交易所支持列表 +CRYPTOCURRENCY_LIST = [ + Exchange.BITMEX, + Exchange.BITSTAMP, + Exchange.OKEX, + Exchange.HUOBI, + Exchange.BITFINEX, + Exchange.BINANCE, + Exchange.BYBIT, + Exchange.COINBASE, + Exchange.DERIBIT, + Exchange.GATEIO, +] + +# 交易所映射 EXCHANGE_VT2TS = { Exchange.CFFEX: "CFX", Exchange.SHFE: "SHF", @@ -48,41 +60,27 @@ Exchange.SZSE: "SZ", } +# 时间调整映射 INTERVAL_ADJUSTMENT_MAP = { Interval.MINUTE: timedelta(minutes=1), Interval.HOUR: timedelta(hours=1), Interval.DAILY: timedelta() } +# 中国上海时区 CHINA_TZ = timezone("Asia/Shanghai") def to_ts_symbol(symbol, exchange) -> Optional[str]: """将交易所代码转换为tushare代码""" # 股票 - if exchange in [Exchange.SSE, Exchange.SZSE]: + if exchange in STOCK_LIST: ts_symbol = f"{symbol}.{EXCHANGE_VT2TS[exchange]}" # 期货 - elif exchange in [ - Exchange.SHFE, - Exchange.CFFEX, - Exchange.DCE, - Exchange.CZCE, - Exchange.INE - ]: + elif exchange in FUTURE_LIST: ts_symbol = f"{symbol}.{EXCHANGE_VT2TS[exchange]}".upper() # 数字货币 - elif exchange in [ - Exchange.BITSTAMP, - Exchange.OKEX, - Exchange.HUOBI, - Exchange.BITFINEX, - Exchange.BINANCE, - Exchange.BYBIT, - Exchange.COINBASE, - Exchange.DERIBIT, - Exchange.BITSTAMP - ]: + elif exchange in CRYPTOCURRENCY_LIST: ts_symbol = symbol else: return None @@ -90,6 +88,28 @@ def to_ts_symbol(symbol, exchange) -> Optional[str]: return ts_symbol +def to_ts_asset(symbol, exchange) -> Optional[str]: + """生成tushare资产类别""" + # 股票 + if exchange in STOCK_LIST: + if exchange is Exchange.SSE and symbol[0] == "6": + asset = "E" + elif exchange is Exchange.SZSE and symbol[0] == "0" or symbol[0] == "3": + asset = "E" + else: + asset = "I" + # 期货 + elif exchange in FUTURE_LIST: + asset = "FT" + # 数字货币 + elif exchange in CRYPTOCURRENCY_LIST: + asset = "C" + else: + return None + + return asset + + class TushareDatafeed(BaseDatafeed): """TuShare数据服务接口""" @@ -121,9 +141,9 @@ def query_bar_history(self, req: HistoryRequest) -> Optional[List[BarData]]: interval = req.interval start = req.start.strftime("%Y%m%d") end = req.end.strftime("%Y%m%d") - asset = ASSET_VT2TS[exchange] ts_symbol = to_ts_symbol(symbol, exchange) + asset = to_ts_asset(symbol, exchange) ts_interval = INTERVAL_VT2TS.get(interval) if not ts_interval: From df2a04fc4e8f7b5cba31b53a6364a83a69e418c1 Mon Sep 17 00:00:00 2001 From: Edanflame <237397488@qq.com> Date: Wed, 17 Nov 2021 16:29:38 +0800 Subject: [PATCH 5/5] =?UTF-8?q?[Fix]=20=E5=A2=9E=E5=8A=A0=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy_tushare/tushare_datafeed.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vnpy_tushare/tushare_datafeed.py b/vnpy_tushare/tushare_datafeed.py index 1e413ba..21e029c 100644 --- a/vnpy_tushare/tushare_datafeed.py +++ b/vnpy_tushare/tushare_datafeed.py @@ -143,7 +143,12 @@ def query_bar_history(self, req: HistoryRequest) -> Optional[List[BarData]]: end = req.end.strftime("%Y%m%d") ts_symbol = to_ts_symbol(symbol, exchange) + if not ts_symbol: + return None + asset = to_ts_asset(symbol, exchange) + if not asset: + return None ts_interval = INTERVAL_VT2TS.get(interval) if not ts_interval: