[update] RestAPI更新、基础组件更新、T.D.X下载更新
This commit is contained in:
parent
6826564622
commit
ac1c90aa42
@ -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文件')
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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 = {}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
# 计算 3,5,7,,,,13笔的形态
|
||||||
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)
|
||||||
|
@ -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式")
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
"""加载多周期窗口"""
|
"""加载多周期窗口"""
|
||||||
|
@ -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:
|
|
||||||
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:
|
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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user