[update] 币安接口、欧式期权接口、t.d.x选择IP

This commit is contained in:
msincenselee 2021-02-25 19:04:33 +08:00
parent c14bb707d9
commit 35df2e2412
8 changed files with 68 additions and 22 deletions

View File

@ -16,14 +16,14 @@ gitee 链接: https://gitee.com/vnpy2/vnpy
+ 直接使用无需pip install easytrader
+ 任然需要安装组件 pip install -r vnpy/api/easytrader/requirement.txt
- vnpy.gateway.gj 国金证券的gateway
+ 使用了tdx作为股票基础数据
+ 使用了天勤作为行情服务
+ 使用了t.d.x作为股票基础数据
+ 使用了天..作为行情服务
+ 使用了easytrader的remote_client作为接入.
- prod.stock_qj 运行例子
+ run_es_restful_server.py 放在A机器安装国金全能客户端。
+ run_main_gj01.py 放在B机器运行vn_trader客户端
15、天勤行情接入
15、天..行情接入
- vnpy.data.tq 定制downloder扩展下载字段
- prod.jobs.refill_tq_future.ticks 下载tick
@ -113,7 +113,7 @@ gitee 链接: https://gitee.com/vnpy2/vnpy
- 提供指数行情订阅
- 使用RabbitMQ指数源或tdx单一数据源
- 使用RabbitMQ指数源或t.d.x单一数据源
- 提供自定义合约功能实时提供其合成后的tick行情
- 增加天勤行情实现上期所5档行情和指数行情
@ -124,8 +124,7 @@ gitee 链接: https://gitee.com/vnpy2/vnpy
4、 增加App: tick_recorder, 直接异步写入csv文件
3、 增加tdx 免费数据源,包括
3、 增加t.d.x 免费数据源,包括
- 提供主力合约/指数合约的信息获取
- 提供期货/股票数据bar 和分笔成交数据下载

View File

@ -26,9 +26,9 @@ class Area(Enum):
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~2:30
NIGHT_MARKET_SQ1 = {'AU': 0.05, 'AG': 1, 'SC': 0.1}
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~1:00
NIGHT_MARKET_SQ2 = {'CU': 10, 'PB': 5, 'AL': 5, 'ZN': 5, 'WR': 1, 'NI': 10}
NIGHT_MARKET_SQ2 = {'CU': 10, 'PB': 5, 'AL': 5, 'ZN': 5, 'WR': 1, 'NI': 10, 'SS':5,'BC':10}
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_SQ3 = {'RU': 5, 'RB': 1, 'HC': 1, 'SP': 2, 'FU': 1, 'BU': 2, 'NR': 5, 'C': 1, 'CS': 1, 'LU':1}
NIGHT_MARKET_SQ3 = {'RU': 5, 'RB': 1, 'HC': 1, 'SP': 2, 'FU': 1, 'BU': 2, 'NR': 5, 'C': 1, 'CS': 1, 'LU':1,'PF':2}
# 郑商所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_ZZ = {'TA': 2, 'JR': 1, 'OI': 0, 'RO': 1, 'PM': 1, 'WH': 1, 'CF': 5, 'SR': 0, 'FG': 1,
'MA': 1, 'RS': 1, 'RM': 1, 'RI': 1, 'ZC': 0.2}
@ -42,7 +42,7 @@ MARKET_ZJ = {'IC': 0.2, 'IF': 0.2, 'IH': 0.2, 'T': 0.005, 'TF': 0.005, 'TS': 0.0
# 只有日盘得合约
MARKET_DAY_ONLY = {'IC': 0.2, 'IF': 0.2, 'IH': 0.2, 'T': 0.005, 'TF': 0.005, 'TS': 0.005,
'JD': 1, 'BB': 0.05, 'CS': 1, 'FB': 0.05, 'L': 5, 'V': 5,
'JR': 1, 'LR': 1, 'PM': 1, 'RI': 1, 'RS': 1, 'SM': 2, 'WH': 1, 'AP': 1, 'CJ': 1, 'UR': 1}
'JR': 1, 'LR': 1, 'PM': 1, 'RI': 1, 'RS': 1, 'SM': 2, 'WH': 1, 'AP': 1, 'CJ': 1, 'UR': 1,"LH":5,'PK':2}
# 夜盘23:00收盘的合约
NIGHT_MARKET_23 = {**NIGHT_MARKET_DL, **NIGHT_MARKET_ZZ, **NIGHT_MARKET_SQ3}

View File

@ -854,7 +854,7 @@ class CtaGridTrade(CtaComponent):
except Exception:
pass
def save(self):
def save(self, **kwargs):
"""
保存网格至本地Json文件
2017/11/23 update: 保存时空的列表也保存
@ -865,7 +865,9 @@ class CtaGridTrade(CtaComponent):
return
# 更新开仓均价
self.recount_avg_open_price()
if not kwargs.get('count_avg_price', True):
self.recount_avg_open_price()
grids_save_path = get_folder_path('data')
# 确保json名字与策略一致
@ -893,7 +895,7 @@ class CtaGridTrade(CtaComponent):
self.write_log(u'GrideTrade保存文件{}完成'.format(grid_json_file))
def load(self, direction, open_status_filter=[]):
def load(self, direction, open_status_filter=[], **kwargs):
"""
加载本地Json至网格
:param direction: Direction.SHORT,做空网格Direction.LONG做多网格
@ -950,7 +952,8 @@ class CtaGridTrade(CtaComponent):
grids.append(grid)
# 更新开仓均价
self.recount_avg_open_price()
if not kwargs.get('count_avg_price',True):
self.recount_avg_open_price()
return grids
def change_strategy_name(self, old_name, new_name):

View File

@ -152,6 +152,43 @@ class BinanceFutureData(RestClient):
return bars
def get_fund_rate(self, symbol=""):
params = {}
if symbol:
params.update({"symbol": symbol})
# Get response from server
resp = self.request(
"GET",
"/fapi/v1/premiumIndex",
data={},
params=params
)
# Break if request failed with other status code
if resp.status_code // 100 != 2:
msg = f"获取资费失败,状态码:{resp.status_code},信息:{resp.text}"
self.write_log(msg)
return {} if symbol else []
else:
datas = resp.json()
if not datas:
msg = f"获取资费为空"
self.write_log(msg)
return {} if symbol else []
if isinstance(datas, list):
for d in datas:
for k in list(d.keys()):
if k in ['nextFundingTime', 'time']:
d.update({k: datetime.fromtimestamp(d.get(k) / 1000).strftime('%Y-%m-%d %H:%M:%S')})
elif isinstance(datas, dict):
for k in list(datas.keys()):
if k in ['nextFundingTime', 'time']:
datas.update({k: datetime.fromtimestamp(datas.get(k) / 1000).strftime('%Y-%m-%d %H:%M:%S')})
return datas
def export_to(self, bars, file_name):
"""导出bar到文件"""
if len(bars) == 0:
@ -201,7 +238,7 @@ class BinanceFutureData(RestClient):
"name": name,
"price_tick": pricetick,
"symbol_size": 20,
"margin_rate": round(float(d['requiredMarginPercent']) / 100, 5),
"margin_rate" : round(float(d['requiredMarginPercent']) / 100,5),
"min_volume": min_volume,
"product": Product.FUTURES.value,
"commission_rate": 0.005
@ -218,6 +255,7 @@ class BinanceFutureData(RestClient):
contracts = load_json(f, auto_save=False)
return contracts
def save_contracts(self):
"""保存合约配置"""
contracts = self.get_contracts()

View File

@ -191,9 +191,12 @@ class TdxFutureData(object):
if last_datetime_str:
try:
last_datetime = datetime.strptime(last_datetime_str, '%Y-%m-%d %H:%M:%S')
if (datetime.now() - last_datetime).total_seconds() > 60 * 60 * 2:
ip = self.best_ip.get('ip')
is_bad_ip = ip and ip in self.best_ip.get('exclude_ips',[])
if (datetime.now() - last_datetime).total_seconds() > 60 * 60 * 2 or is_bad_ip :
self.best_ip = {}
self.exclude_ips = []
if not is_bad_ip:
self.exclude_ips = []
except Exception as ex: # noqa
self.best_ip = {}
else:

View File

@ -60,7 +60,8 @@ STATUS_BINANCEF2VT: Dict[str, Status] = {
ORDERTYPE_VT2BINANCEF: Dict[OrderType, str] = {
OrderType.LIMIT: "LIMIT",
OrderType.MARKET: "MARKET"
OrderType.MARKET: "MARKET",
OrderType.STOP: "STOP_MARKET"
}
ORDERTYPE_BINANCEF2VT: Dict[str, OrderType] = {v: k for k, v in ORDERTYPE_VT2BINANCEF.items()}
@ -172,7 +173,7 @@ class BinancefGateway(BaseGateway):
self.status.update({'con': True})
self.count += 1
if self.count < 2:
if self.count < 60:
return
self.count = 0
if len(self.query_functions) > 0:

View File

@ -198,7 +198,7 @@ class BinanceoGateway(BaseGateway):
self.status.update({'con': True})
self.count += 1
if self.count < 2:
if self.count < 60:
return
self.count = 0
if len(self.query_functions) > 0:

View File

@ -608,10 +608,10 @@ def save_images_to_excel(file_name, sheet_name, image_names):
print(u'save_images_to_excel exception:{}'.format(str(ex)), traceback.format_exc(), file=sys.stderr)
return False
def display_dual_axis(df, columns1, columns2=[], invert_yaxis1=False, invert_yaxis2=False, file_name=None,
sheet_name=None,
image_name=None):
image_name=None,
label_column='index'):
"""
显示(保存)双Y轴的走势图
:param df: DataFrame
@ -622,6 +622,7 @@ def display_dual_axis(df, columns1, columns2=[], invert_yaxis1=False, invert_yax
:param file_name: 保存的excel 文件名称
:param sheet_name: excel 的sheet
:param image_name: 保存的image 文件名
:param label_cloumn: 显示在x轴的label所在字段例如 df的index或者 'datetime'
颜色色系:https://www.osgeo.cn/matplotlib/tutorials/colors/colormaps.html
:return:
"""
@ -648,7 +649,8 @@ def display_dual_axis(df, columns1, columns2=[], invert_yaxis1=False, invert_yax
# 修改x轴得label为时间
xt = ax1.get_xticks()
xt2 = [df.index[int(i)] for i in xt[1:-2]]
label_values = df.index.values if label_column == 'index' else df[label_column].values
xt2 = [label_values[int(i)] for i in xt[1:-2]]
xt2.insert(0, '')
xt2.append('')
ax1.set_xticklabels(xt2)