[update] RestAPI更新、基础组件更新、T.D.X下载更新

This commit is contained in:
msincenselee 2021-11-01 10:03:50 +08:00
parent 6826564622
commit ac1c90aa42
13 changed files with 138 additions and 50 deletions

View File

@ -110,9 +110,21 @@ if __name__ == "__main__":
# 更新数量
grid['volume'] = adj_volume
# 更新开仓\平仓\止损价格
open_price = grid['open_price']
new_open_price = round(float(open_price * adj_rate), 3)
close_price = grid['close_price']
new_close_price = round(float(close_price * adj_rate), 3)
stop_price = grid['stop_price']
new_stop_price = round(float(stop_price * adj_rate), 3)
# 更新执行日期
grid['snapshot'].update({'adjusted_date': dividOperateDate})
msg = f'{strategy_name}:{vt_symbol}[{name}]发生除权调整:{cur_volume}=>{adj_volume}'
msg = f'{strategy_name}:{vt_symbol}[{name}]发生除权调整:持仓{cur_volume}=>{adj_volume},' \
f'开仓价:{open_price}=>{new_open_price},' \
f'平仓价:{close_price}=>{new_close_price},' \
f'止损价:{stop_price}=>{new_stop_price}'
send_wx_msg(msg)
print(msg)
append_data(adj_record_file, dict_data={
@ -126,8 +138,8 @@ if __name__ == "__main__":
'pre_back_adj': pre_data.get('backAdjustFactor'),
'last_back_adj': last_data.get('backAdjustFactor')
})
changed = True
changed = True
if changed:
print('保存更新后的Grids.json文件')

View File

@ -107,7 +107,7 @@ def refill(symbol_info):
data_df = data_df.sort_index()
# print(data_df.head())
print(data_df.tail())
data_df.to_csv(bar_file_path, index=True)
data_df.to_csv(bar_file_path, index=True, encoding='utf8')
d2 = datetime.now()
microseconds = (d1 - d1).microseconds
print(f'{progress}% 首次更新{stock_code} {stock_name}数据 {microseconds} 毫秒=> 文件{bar_file_path}')
@ -176,8 +176,11 @@ if __name__ == '__main__':
for symbol in symbol_dict.keys():
info = copy(symbol_dict[symbol])
stock_code = info['code']
if ('stock_type' in info.keys() and info['stock_type'] in ['stock_cn',
'cb_cn']) or stock_code in stock_list:
# 股票/可转债; 或 存在指定下载文件中
if ('stock_type' in info.keys() \
and info['stock_type'] in ['stock_cn', 'cb_cn']) \
or stock_code in stock_list:
info['period'] = period
tasks.append(info)
# if len(tasks) > 12:

View File

@ -46,6 +46,7 @@ class Request(object):
params: dict,
data: Union[dict, str, bytes],
headers: dict,
cookies: Union[requests.cookies.RequestsCookieJar, dict]=None,
callback: CALLBACK_TYPE = None,
on_failed: ON_FAILED_TYPE = None,
on_error: ON_ERROR_TYPE = None,
@ -61,7 +62,7 @@ class Request(object):
self.params = params
self.data = data
self.headers = headers
self.cookies = cookies
self.stream = stream
self.on_connected = on_connected
self.processing_line: Optional[str] = ''
@ -258,6 +259,7 @@ class RestClient(object):
params: dict = None,
data: Union[dict, str, bytes] = None,
headers: dict = None,
cookies: Union[requests.cookies.RequestsCookieJar, dict]=None,
on_failed: ON_FAILED_TYPE = None,
on_error: ON_ERROR_TYPE = None,
extra: Any = None,
@ -281,6 +283,7 @@ class RestClient(object):
params=params,
data=data,
headers=headers,
cookies=cookies,
callback=callback,
on_failed=on_failed,
on_error=on_error,
@ -416,6 +419,7 @@ class RestClient(object):
headers = request.headers
params = request.params
data = request.data
cookies = request.cookies
self._log("[%s] sending request %s %s, headers:%s, params:%s, data:%s",
uid, method, url,
headers, params, data)
@ -425,6 +429,7 @@ class RestClient(object):
headers=headers,
params=params,
data=data,
cookies=cookies,
proxies=self.proxies,
stream=stream,
)
@ -498,6 +503,7 @@ class RestClient(object):
params: dict = None,
data: dict = None,
headers: dict = None,
cookies: Union[requests.cookies.RequestsCookieJar, dict]=None
):
"""
Add a new request.
@ -514,6 +520,7 @@ class RestClient(object):
params,
data,
headers,
cookies=cookies,
client=self,
)
request = self.sign(request)
@ -526,6 +533,7 @@ class RestClient(object):
headers=request.headers,
params=request.params,
data=request.data,
proxies=self.proxies,
cookies=request.cookies,
proxies=self.proxies
)
return response

View File

@ -367,10 +367,10 @@ class BackTestingEngine(object):
self.volume_tick.update({vt_symbol: volume_tick})
def get_volume_tick(self, vt_symbol: str):
return self.volume_tick.get(vt_symbol, 1)
return self.volume_tick.get(vt_symbol, 100)
def set_contract(self, symbol: str, exchange: Exchange, product: Product, name: str, size: int,
price_tick: float, volume_tick: float = 1, margin_rate: float = 0.1):
price_tick: float, volume_tick: float = 100, margin_rate: float = 0.1):
"""设置合约信息"""
vt_symbol = '.'.join([symbol, exchange.value])
if vt_symbol not in self.contract_dict:
@ -580,7 +580,7 @@ class BackTestingEngine(object):
product=Product(symbol_data.get('product', "股票")),
size=symbol_data.get('symbol_size', 1),
price_tick=symbol_data.get('price_tick', 0.01),
volume_tick=symbol_data.get('min_volume', 10),
volume_tick=symbol_data.get('min_volume', 100),
margin_rate=margin_rate
)

View File

@ -1825,7 +1825,8 @@ class CtaProFutureTemplate(CtaProTemplate):
self.write_log(u'撤单逻辑 => 重新开仓')
# 开空委托单
if order_info['direction'] == Direction.SHORT:
short_price = self.cur_mi_price - self.price_tick
cur_price = self.cta_engine.get_price(order_vt_symbol)
short_price = cur_price - self.price_tick
if order_grid.volume != order_volume and order_volume > 0:
self.write_log(
u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume))
@ -1845,7 +1846,8 @@ class CtaProFutureTemplate(CtaProTemplate):
else:
self.write_error(u'撤单后,重新委托开空仓失败')
else:
buy_price = self.cur_mi_price + self.price_tick
cur_price = self.cta_engine.get_price(order_vt_symbol)
buy_price = cur_price + self.price_tick
if order_grid.volume != order_volume and order_volume > 0:
self.write_log(
u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume))

View File

@ -16,7 +16,7 @@ from datetime import datetime
import pandas as pd
import traceback
from vnpy.component.cta_line_bar import CtaHourBar
from vnpy.component.cta_line_bar import CtaMinuteBar, CtaHourBar, CtaDayBar, CtaLineBar, get_cta_bar_type
from vnpy.component.cta_renko_bar import CtaRenkoBar
from vnpy.trader.object import BarData, TickData
from vnpy.trader.utility import get_folder_path, get_trading_date
@ -60,9 +60,12 @@ class FundKline(object):
self.write_log(u'使用CtaRenkoBar')
self.kline = CtaRenkoBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting)
else:
self.write_log(u'使用CtaHourBar')
self.kline = CtaHourBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting)
# self.kline = CtaDayBar(strategy=self, onBarFunc=self.onBar, setting=self.setting)
kline_setting = self.setting
kline_period = kline_setting.pop('kline_period', 'H1') # 默认使用1小时K线
kline_class, kline_bar_interval = get_cta_bar_type(kline_period)
self.write_log(u'使用{}'.format(kline_period))
kline_setting['bar_interval'] = kline_bar_interval # X分钟K线, X秒K线X小时K线
self.kline = kline_class(strategy=self, cb_on_bar=self.on_bar, setting=kline_setting)
self.inited = False
self.long_pos_dict = {}

View File

@ -6240,13 +6240,14 @@ class CtaLineBar(object):
if bi_len < 3:
return
if self.cur_fenxing.is_rt:
return
# if self.cur_fenxing.is_rt:
# return
bi_n = min(15, bi_len)
price = self.cur_bi.low if self.cur_bi.direction == -1 else self.cur_bi.high
# 计算 35713笔的形态
for n in range(3, bi_n, 2):
# => 信号
if n == 3:
@ -6294,7 +6295,7 @@ class CtaLineBar(object):
'end': self.cur_bi.end,
'price': price,
'signal': qsbc_2nd})
if cur_signal and self.export_xt_filename:
if cur_signal is not None and self.export_xt_filename:
self.append_data(
file_name=self.export_xt_filename.replace('_n_', f'_2nd_'),
dict_data=cur_signal,
@ -6304,6 +6305,23 @@ class CtaLineBar(object):
else:
self.xt_2nd_signals[-1].update({'end': self.cur_bi.end, 'price': price, 'signal': qsbc_2nd})
def get_xt_signal(self, xt_name, x=0):
"""
获取n笔形态/信号的倒x笔结果
:param n:
:param x: 倒x笔如倒1笔
:return: {}
"""
xt_signals = getattr(self, xt_name)
if xt_signals is None:
return {}
if len(xt_signals) > x:
return xt_signals[-1-x]
else:
return {}
def write_log(self, content):
"""记录CTA日志"""
self.strategy.write_log(u'[' + self.name + u']' + content)

View File

@ -96,7 +96,7 @@ def check_bi_not_rt(kline, direction: Direction) -> bool:
and kline.cur_fenxing.index == kline.index_list[-1] \
and kline.line_bar[-1].datetime.strftime('%Y-%m-%d %H:%M:%S') > kline.cur_fenxing.index \
and kline.line_bar[-1].low_price > float(kline.cur_fenxing.low) \
and kline.line_bar[-1].high_price < kline.line_bar[-2].high_price:
and kline.line_bar[-1].high_price > kline.line_bar[-2].high_price:
return True
return False
@ -382,7 +382,7 @@ def check_chan_xt_five_bi(kline, bi_list: List[ChanObject]):
# 五笔三买要求bi_5.high是最高点, 或者bi_4.height超过笔2、笔3两倍
if min_low < max(bi_1.low, bi_3.low) < min(bi_1.high, bi_3.high) < bi_5.low:
if bi_5.high == max_high:
if bi_5.high == max_high: # and max(bi_1.high, bi_3.high) < bi_5.low
v = ChanSignals.LI0.value # 类三买, 五笔
elif bi_3.low == min_low and bi_1.high == max_high \
and bi_4.height > max(bi_1.height, bi_2.height, bi_3.height) \
@ -418,7 +418,7 @@ def check_chan_xt_five_bi(kline, bi_list: List[ChanObject]):
# 五笔三卖要求bi_5.low是最低点中枢可能是1~3
if min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_5.high:
if bi_5.low == min_low:
if bi_5.low == min_low: # and min(bi_1.low, bi_3.low) > bi_5.high
return ChanSignals.SI0.value
elif bi_3.high == max_high and bi_1.low == min_low \
and bi_4.height > max(bi_1.height, bi_2.height, bi_3.height) \
@ -572,7 +572,7 @@ def check_chan_xt_nine_bi(kline, bi_list: List[ChanObject]):
and min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high \
and min(bi_6.high, bi_8.high) > max(bi_6.low, bi_8.low) \
and min(bi_2.low, bi_4.low) > max(bi_6.high, bi_8.high) \
and bi_9.height < bi_5.height and bi_9.atan <= bi_5.atan:
and (bi_9.height < bi_5.height or bi_9.atan <= bi_5.atan):
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔aAb式')
# 九笔GG 类三买1357构成中枢最低点在3或5
@ -639,7 +639,7 @@ def check_chan_xt_nine_bi(kline, bi_list: List[ChanObject]):
and bi_6.low > min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) \
and min(bi_6.high, bi_8.high) > max(bi_6.low, bi_8.low) \
and max(bi_2.high, bi_4.high) < min(bi_6.low, bi_8.low) \
and bi_9.height < bi_5.height and bi_9.atan <= bi_5.atan:
and (bi_9.height < bi_5.height or bi_9.atan <= bi_5.atan):
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔aAbBc式')
# 九笔类三卖
@ -812,7 +812,7 @@ def check_chan_xt_thirteen_bi(kline, bi_list: List[ChanObject]):
if direction == -1:
if min_low == bi_13.low and max_high == bi_1.high:
# ABC式类一买A5B3C5
if bi_5.low < min(bi_1.low, bi_3.low) and bi_9.high > max(bi_11.high, bi_13.high) \
if bi_5.low < max(bi_1.low, bi_3.low) and bi_9.high > max(bi_11.high, bi_13.high) \
and bi_8.high > bi_6.low and bi_1.high - bi_5.low > bi_9.high - bi_13.low:
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B3C5式")
@ -827,12 +827,13 @@ def check_chan_xt_thirteen_bi(kline, bi_list: List[ChanObject]):
and min(bi_6.high, bi_8.high, bi_10.high) > max(bi_6.low, bi_8.low, bi_10.low) \
and bi_1.high - bi_5.low > bi_11.high - bi_13.low:
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B5C3式")
# AB式底背驰 aAbBc
# 上涨线段时,判断背驰类型
elif direction == 1:
if max_high == bi_13.high and min_low == bi_1.low:
# ABC式顶背驰A5B3C5
if bi_5.high > max(bi_3.high, bi_1.high) and bi_9.low < min(bi_11.low, bi_13.low) \
if bi_5.high > min(bi_3.high, bi_1.high) and bi_9.low < min(bi_11.low, bi_13.low) \
and bi_8.low < bi_6.high and bi_5.high - bi_1.low > bi_13.high - bi_9.low:
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="13笔A5B3C5式")

View File

@ -16,6 +16,8 @@ import pickle
import bz2
import traceback
import pandas as pd
import random
from time import sleep
from datetime import datetime, timedelta
from logging import ERROR
@ -94,8 +96,8 @@ class TdxStockData(object):
self.config = get_cache_config(TDX_STOCK_CONFIG)
self.symbol_dict = self.config.get('symbol_dict', {})
self.cache_time = self.config.get('cache_time', datetime.now() - timedelta(days=7))
self.best_ip = self.config.get('best_ip',{})
self.exclude_ips = self.config.get('exclude_ips',[])
self.best_ip = self.config.get('best_ip', {})
self.exclude_ips = self.config.get('exclude_ips', [])
if len(self.symbol_dict) == 0 or self.cache_time < datetime.now() - timedelta(days=1):
self.cache_config()
@ -201,8 +203,8 @@ class TdxStockData(object):
self.connection_status = True
except Exception as ex:
self.write_log(u'连接服务器{}tdx异常:{},{}'.format(self.best_ip,str(ex), traceback.format_exc()))
cur_ip = self.best_ip.get('ip',None)
self.write_log(u'连接服务器{}tdx异常:{},{}'.format(self.best_ip, str(ex), traceback.format_exc()))
cur_ip = self.best_ip.get('ip', None)
if cur_ip is not None and cur_ip not in self.exclude_ips:
self.write_log(f'排除{cur_ip}')
self.exclude_ips.append(cur_ip)
@ -320,7 +322,7 @@ class TdxStockData(object):
self.write_log('{}开始下载tdx股票: {},代码:{} {}数据, {} to {}.'
.format(datetime.now(), name, tdx_code, tdx_period, qry_start_date, qry_end_date))
stock_type = get_stock_type(tdx_code,market_id)
stock_type = get_stock_type(tdx_code, market_id)
if stock_type == 'index_cn':
get_bar_func = self.api.get_index_bars
else:
@ -349,6 +351,7 @@ class TdxStockData(object):
if len(_bars) == 0:
self.write_error('{} Handling {}, len1={}..., continue'.format(
str(datetime.now()), tdx_code, len(_bars)))
sleep(3 * random.random())
return False, ret_bars
current_datetime = datetime.now()

View File

@ -92,7 +92,7 @@ class MainEngine:
# 缺省使用了接口自己定义的gateway_name
gateway = gateway_class(self.event_engine)
gateway_name = gateway.gateway_name
self.write_log(f'添加{gateway_name}网关')
self.gateways[gateway_name] = gateway
# Add gateway supported exchanges into engine

View File

@ -1563,9 +1563,12 @@ class GridKline(QtWidgets.QWidget):
# 配置项12: bi_file / duan_file / bi_zs_file / duan_zs_file支持缠论的画线
def __init__(self, parent=None, kline_settings={}, title='', relocate=True):
def __init__(self, parent=None, kline_settings={}, title='', relocate=True,screen_file=""):
self.parent = parent
super(GridKline, self).__init__(parent)
self.width = 1920
self.height = 1080
# widget的标题
if title:
self.setWindowTitle(title)
@ -1590,6 +1593,9 @@ class GridKline(QtWidgets.QWidget):
self.setLayout(self.grid_layout)
self.relocate = relocate
self.screen_file = screen_file
self.init_ui()
def init_ui(self):
@ -1598,13 +1604,14 @@ class GridKline(QtWidgets.QWidget):
id = 1
for kline_name, kline_setting in self.kline_settings.items():
canvas = getattr(self, f'canvas_{id}')
canvas = getattr(self, f'canvas_{id}',None)
if id > 8:
print(f'最多支持8个K线同时展现', file=sys.stderr)
continue
# 创建K线图表
canvas = KLineWidget(display_vol=False, display_sub=True)
if canvas is None:
# 创建K线图表
canvas = KLineWidget(display_vol=False, display_sub=True)
setattr(self, f'canvas_{id}', canvas)
canvas.show()
# K线标题
canvas.KLtitle.setText(f'{kline_name}', size='18pt')
@ -1644,11 +1651,16 @@ class GridKline(QtWidgets.QWidget):
if len(kline_names) == 0:
break
row += 1
self.show()
if len(self.screen_file) == 0:
self.show()
self.load_multi_kline()
if len(self.screen_file) > 0:
p = self.grab()
p.save(self.screen_file,'png')
self.close()
# ----------------------------------------------------------------------
def load_multi_kline(self):
"""加载多周期窗口"""

View File

@ -10,8 +10,9 @@ import ctypes
import bz2
import pickle
import zlib
from time import sleep
import pandas as pd
from pyqtgraph import QtGui
from vnpy.trader.ui.kline.crosshair import Crosshair
from vnpy.trader.ui.kline.kline import *
@ -29,7 +30,8 @@ class UiSnapshot(object):
tns_file: str = "",
dist_file: str = "",
dist_include_list=[],
use_grid=True):
use_grid=True,
export_file=""):
"""
显示切片
:param snapshot_file: 切片文件路径通过这个方法可读取历史切片
@ -119,14 +121,38 @@ class UiSnapshot(object):
k: setting
}
)
# K线界面
try:
if use_grid:
w = GridKline(kline_settings=kline_settings, title=d.get('strategy', ''), relocate=True)
w.showMaximized()
else:
w = MultiKlineWindow(kline_settings=kline_settings, title=d.get('strategy', ''))
w.showMaximized()
try:
if len(export_file) == 0:
# K线界面
if use_grid:
w = GridKline(kline_settings=kline_settings, title=d.get('strategy', ''), relocate=True)
w.showMaximized()
else:
w = MultiKlineWindow(kline_settings=kline_settings, title=d.get('strategy', ''))
w.showMaximized()
else:
w = GridKline(kline_settings=kline_settings, title=d.get('strategy',''),relocate=False,screen_file=export_file)
print('sleep')
sleep(1)
print('close')
w.close()
except Exception as ex:
print(u'exception:{},trace:{}'.format(str(ex), traceback.format_exc()))
def export(self,
snapshot_file: str,
d: dict = None,
trade_file: str = "",
tns_file: str = "",
dist_file: str = "",
dist_include_list=[],
export_file:str=""
):
self.show(snapshot_file=snapshot_file,
d=d,
trade_file=trade_file,
dist_file=dist_file,
dist_include_list=dist_include_list,
export_file=export_file)

View File

@ -350,7 +350,7 @@ def get_csv_last_dt(file_name, dt_index=0, dt_format='%Y-%m-%d %H:%M:%S', line_l
if not os.path.exists(file_name):
return False
with open(file_name, 'r') as f:
with open(file_name, 'r', encoding='utf8') as f:
f_size = os.path.getsize(file_name)
if f_size < line_length:
line_length = f_size