[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 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}) 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) send_wx_msg(msg)
print(msg) print(msg)
append_data(adj_record_file, dict_data={ append_data(adj_record_file, dict_data={
@ -126,8 +138,8 @@ if __name__ == "__main__":
'pre_back_adj': pre_data.get('backAdjustFactor'), 'pre_back_adj': pre_data.get('backAdjustFactor'),
'last_back_adj': last_data.get('backAdjustFactor') 'last_back_adj': last_data.get('backAdjustFactor')
}) })
changed = True
changed = True
if changed: if changed:
print('保存更新后的Grids.json文件') print('保存更新后的Grids.json文件')

View File

@ -107,7 +107,7 @@ def refill(symbol_info):
data_df = data_df.sort_index() data_df = data_df.sort_index()
# print(data_df.head()) # print(data_df.head())
print(data_df.tail()) 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() d2 = datetime.now()
microseconds = (d1 - d1).microseconds microseconds = (d1 - d1).microseconds
print(f'{progress}% 首次更新{stock_code} {stock_name}数据 {microseconds} 毫秒=> 文件{bar_file_path}') print(f'{progress}% 首次更新{stock_code} {stock_name}数据 {microseconds} 毫秒=> 文件{bar_file_path}')
@ -176,8 +176,11 @@ if __name__ == '__main__':
for symbol in symbol_dict.keys(): for symbol in symbol_dict.keys():
info = copy(symbol_dict[symbol]) info = copy(symbol_dict[symbol])
stock_code = info['code'] 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 info['period'] = period
tasks.append(info) tasks.append(info)
# if len(tasks) > 12: # if len(tasks) > 12:

View File

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

View File

@ -367,10 +367,10 @@ class BackTestingEngine(object):
self.volume_tick.update({vt_symbol: volume_tick}) self.volume_tick.update({vt_symbol: volume_tick})
def get_volume_tick(self, vt_symbol: str): 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, 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]) vt_symbol = '.'.join([symbol, exchange.value])
if vt_symbol not in self.contract_dict: if vt_symbol not in self.contract_dict:
@ -580,7 +580,7 @@ class BackTestingEngine(object):
product=Product(symbol_data.get('product', "股票")), product=Product(symbol_data.get('product', "股票")),
size=symbol_data.get('symbol_size', 1), size=symbol_data.get('symbol_size', 1),
price_tick=symbol_data.get('price_tick', 0.01), 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 margin_rate=margin_rate
) )

View File

@ -1825,7 +1825,8 @@ class CtaProFutureTemplate(CtaProTemplate):
self.write_log(u'撤单逻辑 => 重新开仓') self.write_log(u'撤单逻辑 => 重新开仓')
# 开空委托单 # 开空委托单
if order_info['direction'] == Direction.SHORT: 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: if order_grid.volume != order_volume and order_volume > 0:
self.write_log( self.write_log(
u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume)) u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume))
@ -1845,7 +1846,8 @@ class CtaProFutureTemplate(CtaProTemplate):
else: else:
self.write_error(u'撤单后,重新委托开空仓失败') self.write_error(u'撤单后,重新委托开空仓失败')
else: 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: if order_grid.volume != order_volume and order_volume > 0:
self.write_log( self.write_log(
u'网格volume:{},order_volume:{}不一致,修正'.format(order_grid.volume, order_volume)) 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 pandas as pd
import traceback 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.component.cta_renko_bar import CtaRenkoBar
from vnpy.trader.object import BarData, TickData from vnpy.trader.object import BarData, TickData
from vnpy.trader.utility import get_folder_path, get_trading_date from vnpy.trader.utility import get_folder_path, get_trading_date
@ -60,9 +60,12 @@ class FundKline(object):
self.write_log(u'使用CtaRenkoBar') self.write_log(u'使用CtaRenkoBar')
self.kline = CtaRenkoBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting) self.kline = CtaRenkoBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting)
else: else:
self.write_log(u'使用CtaHourBar') kline_setting = self.setting
self.kline = CtaHourBar(strategy=self, cb_on_bar=self.on_bar, setting=self.setting) kline_period = kline_setting.pop('kline_period', 'H1') # 默认使用1小时K线
# self.kline = CtaDayBar(strategy=self, onBarFunc=self.onBar, setting=self.setting) 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.inited = False
self.long_pos_dict = {} self.long_pos_dict = {}

View File

@ -6240,13 +6240,14 @@ class CtaLineBar(object):
if bi_len < 3: if bi_len < 3:
return return
if self.cur_fenxing.is_rt: # if self.cur_fenxing.is_rt:
return # return
bi_n = min(15, bi_len) bi_n = min(15, bi_len)
price = self.cur_bi.low if self.cur_bi.direction == -1 else self.cur_bi.high 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): for n in range(3, bi_n, 2):
# => 信号 # => 信号
if n == 3: if n == 3:
@ -6294,7 +6295,7 @@ class CtaLineBar(object):
'end': self.cur_bi.end, 'end': self.cur_bi.end,
'price': price, 'price': price,
'signal': qsbc_2nd}) '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( self.append_data(
file_name=self.export_xt_filename.replace('_n_', f'_2nd_'), file_name=self.export_xt_filename.replace('_n_', f'_2nd_'),
dict_data=cur_signal, dict_data=cur_signal,
@ -6304,6 +6305,23 @@ class CtaLineBar(object):
else: else:
self.xt_2nd_signals[-1].update({'end': self.cur_bi.end, 'price': price, 'signal': qsbc_2nd}) 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): def write_log(self, content):
"""记录CTA日志""" """记录CTA日志"""
self.strategy.write_log(u'[' + self.name + u']' + content) 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.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].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].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 True
return False 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两倍 # 五笔三买要求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 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 # 类三买, 五笔 v = ChanSignals.LI0.value # 类三买, 五笔
elif bi_3.low == min_low and bi_1.high == max_high \ 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) \ 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 # 五笔三卖要求bi_5.low是最低点中枢可能是1~3
if min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_5.high: 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 return ChanSignals.SI0.value
elif bi_3.high == max_high and bi_1.low == min_low \ 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) \ 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_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_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 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式') return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔aAb式')
# 九笔GG 类三买1357构成中枢最低点在3或5 # 九笔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 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 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 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式') 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 direction == -1:
if min_low == bi_13.low and max_high == bi_1.high: if min_low == bi_13.low and max_high == bi_1.high:
# ABC式类一买A5B3C5 # 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: 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式") 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 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: 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式") return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B5C3式")
# AB式底背驰 aAbBc
# 上涨线段时,判断背驰类型 # 上涨线段时,判断背驰类型
elif direction == 1: elif direction == 1:
if max_high == bi_13.high and min_low == bi_1.low: if max_high == bi_13.high and min_low == bi_1.low:
# ABC式顶背驰A5B3C5 # 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: 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式") 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 bz2
import traceback import traceback
import pandas as pd import pandas as pd
import random
from time import sleep
from datetime import datetime, timedelta from datetime import datetime, timedelta
from logging import ERROR from logging import ERROR
@ -94,8 +96,8 @@ class TdxStockData(object):
self.config = get_cache_config(TDX_STOCK_CONFIG) self.config = get_cache_config(TDX_STOCK_CONFIG)
self.symbol_dict = self.config.get('symbol_dict', {}) self.symbol_dict = self.config.get('symbol_dict', {})
self.cache_time = self.config.get('cache_time', datetime.now() - timedelta(days=7)) self.cache_time = self.config.get('cache_time', datetime.now() - timedelta(days=7))
self.best_ip = self.config.get('best_ip',{}) self.best_ip = self.config.get('best_ip', {})
self.exclude_ips = self.config.get('exclude_ips',[]) self.exclude_ips = self.config.get('exclude_ips', [])
if len(self.symbol_dict) == 0 or self.cache_time < datetime.now() - timedelta(days=1): if len(self.symbol_dict) == 0 or self.cache_time < datetime.now() - timedelta(days=1):
self.cache_config() self.cache_config()
@ -201,8 +203,8 @@ class TdxStockData(object):
self.connection_status = True self.connection_status = True
except Exception as ex: except Exception as ex:
self.write_log(u'连接服务器{}tdx异常:{},{}'.format(self.best_ip,str(ex), traceback.format_exc())) self.write_log(u'连接服务器{}tdx异常:{},{}'.format(self.best_ip, str(ex), traceback.format_exc()))
cur_ip = self.best_ip.get('ip',None) cur_ip = self.best_ip.get('ip', None)
if cur_ip is not None and cur_ip not in self.exclude_ips: if cur_ip is not None and cur_ip not in self.exclude_ips:
self.write_log(f'排除{cur_ip}') self.write_log(f'排除{cur_ip}')
self.exclude_ips.append(cur_ip) self.exclude_ips.append(cur_ip)
@ -320,7 +322,7 @@ class TdxStockData(object):
self.write_log('{}开始下载tdx股票: {},代码:{} {}数据, {} to {}.' self.write_log('{}开始下载tdx股票: {},代码:{} {}数据, {} to {}.'
.format(datetime.now(), name, tdx_code, tdx_period, qry_start_date, qry_end_date)) .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': if stock_type == 'index_cn':
get_bar_func = self.api.get_index_bars get_bar_func = self.api.get_index_bars
else: else:
@ -349,6 +351,7 @@ class TdxStockData(object):
if len(_bars) == 0: if len(_bars) == 0:
self.write_error('{} Handling {}, len1={}..., continue'.format( self.write_error('{} Handling {}, len1={}..., continue'.format(
str(datetime.now()), tdx_code, len(_bars))) str(datetime.now()), tdx_code, len(_bars)))
sleep(3 * random.random())
return False, ret_bars return False, ret_bars
current_datetime = datetime.now() current_datetime = datetime.now()

View File

@ -92,7 +92,7 @@ class MainEngine:
# 缺省使用了接口自己定义的gateway_name # 缺省使用了接口自己定义的gateway_name
gateway = gateway_class(self.event_engine) gateway = gateway_class(self.event_engine)
gateway_name = gateway.gateway_name gateway_name = gateway.gateway_name
self.write_log(f'添加{gateway_name}网关')
self.gateways[gateway_name] = gateway self.gateways[gateway_name] = gateway
# Add gateway supported exchanges into engine # 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支持缠论的画线 # 配置项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 self.parent = parent
super(GridKline, self).__init__(parent) super(GridKline, self).__init__(parent)
self.width = 1920
self.height = 1080
# widget的标题 # widget的标题
if title: if title:
self.setWindowTitle(title) self.setWindowTitle(title)
@ -1590,6 +1593,9 @@ class GridKline(QtWidgets.QWidget):
self.setLayout(self.grid_layout) self.setLayout(self.grid_layout)
self.relocate = relocate self.relocate = relocate
self.screen_file = screen_file
self.init_ui() self.init_ui()
def init_ui(self): def init_ui(self):
@ -1598,13 +1604,14 @@ class GridKline(QtWidgets.QWidget):
id = 1 id = 1
for kline_name, kline_setting in self.kline_settings.items(): 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: if id > 8:
print(f'最多支持8个K线同时展现', file=sys.stderr) print(f'最多支持8个K线同时展现', file=sys.stderr)
continue continue
if canvas is None:
# 创建K线图表 # 创建K线图表
canvas = KLineWidget(display_vol=False, display_sub=True) canvas = KLineWidget(display_vol=False, display_sub=True)
setattr(self, f'canvas_{id}', canvas)
canvas.show() canvas.show()
# K线标题 # K线标题
canvas.KLtitle.setText(f'{kline_name}', size='18pt') canvas.KLtitle.setText(f'{kline_name}', size='18pt')
@ -1644,11 +1651,16 @@ class GridKline(QtWidgets.QWidget):
if len(kline_names) == 0: if len(kline_names) == 0:
break break
row += 1 row += 1
if len(self.screen_file) == 0:
self.show() self.show()
self.load_multi_kline() 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): def load_multi_kline(self):
"""加载多周期窗口""" """加载多周期窗口"""

View File

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