[update] 币安接口、欧式期权接口、t.d.x选择IP
This commit is contained in:
parent
c14bb707d9
commit
35df2e2412
11
README.md
11
README.md
@ -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 和分笔成交数据下载
|
||||
|
@ -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}
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user