[update] 缠论、其他
This commit is contained in:
parent
48205283b6
commit
d79157dd8e
@ -1,6 +1,6 @@
|
|||||||
six
|
six
|
||||||
PyQt5
|
PyQt5
|
||||||
pyqtgraph
|
pyqtgraph==0.10.0
|
||||||
dataclasses; python_version<="3.6"
|
dataclasses; python_version<="3.6"
|
||||||
qdarkstyle
|
qdarkstyle
|
||||||
requests
|
requests
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
from .utils.misc import file2dict
|
from .utils.misc import file2dict
|
||||||
|
from vnpy.rpc import RpcClient
|
||||||
|
|
||||||
|
|
||||||
def use(broker, host, port=1430, **kwargs):
|
|
||||||
return RemoteClient(broker, host, port)
|
|
||||||
|
|
||||||
|
|
||||||
|
TIMEOUT = 10
|
||||||
class RemoteClient:
|
class RemoteClient:
|
||||||
def __init__(self, broker, host, port=1430, **kwargs):
|
def __init__(self, broker, host, port=1430, **kwargs):
|
||||||
self._s = requests.session()
|
self._s = requests.session()
|
||||||
@ -44,7 +43,8 @@ class RemoteClient:
|
|||||||
|
|
||||||
params["broker"] = self._broker
|
params["broker"] = self._broker
|
||||||
|
|
||||||
response = self._s.post(self._api + "/prepare", json=params)
|
# prepare需要启动同花顺客户端,需要的时间比较长,所以超时给长一些时间
|
||||||
|
response = self._s.post(self._api + "/prepare", json=params, timeout=60)
|
||||||
if response.status_code >= 300:
|
if response.status_code >= 300:
|
||||||
raise Exception(response.json()["error"])
|
raise Exception(response.json()["error"])
|
||||||
return response.json()
|
return response.json()
|
||||||
@ -76,7 +76,7 @@ class RemoteClient:
|
|||||||
return self.common_get("exit")
|
return self.common_get("exit")
|
||||||
|
|
||||||
def common_get(self, endpoint):
|
def common_get(self, endpoint):
|
||||||
response = self._s.get(self._api + "/" + endpoint)
|
response = self._s.get(self._api + "/" + endpoint, timeout=TIMEOUT)
|
||||||
if response.status_code >= 300:
|
if response.status_code >= 300:
|
||||||
print(Exception(response.json()["error"]))
|
print(Exception(response.json()["error"]))
|
||||||
return response.json()
|
return response.json()
|
||||||
@ -85,7 +85,7 @@ class RemoteClient:
|
|||||||
params = locals().copy()
|
params = locals().copy()
|
||||||
params.pop("self")
|
params.pop("self")
|
||||||
|
|
||||||
response = self._s.post(self._api + "/buy", json=params)
|
response = self._s.post(self._api + "/buy", json=params, timeout=TIMEOUT)
|
||||||
if response.status_code >= 300:
|
if response.status_code >= 300:
|
||||||
raise Exception(response.json()["error"])
|
raise Exception(response.json()["error"])
|
||||||
return response.json()
|
return response.json()
|
||||||
@ -94,7 +94,7 @@ class RemoteClient:
|
|||||||
params = locals().copy()
|
params = locals().copy()
|
||||||
params.pop("self")
|
params.pop("self")
|
||||||
|
|
||||||
response = self._s.post(self._api + "/sell", json=params)
|
response = self._s.post(self._api + "/sell", json=params, timeout=TIMEOUT)
|
||||||
if response.status_code >= 300:
|
if response.status_code >= 300:
|
||||||
raise Exception(response.json()["error"])
|
raise Exception(response.json()["error"])
|
||||||
return response.json()
|
return response.json()
|
||||||
@ -103,7 +103,69 @@ class RemoteClient:
|
|||||||
params = locals().copy()
|
params = locals().copy()
|
||||||
params.pop("self")
|
params.pop("self")
|
||||||
|
|
||||||
response = self._s.post(self._api + "/cancel_entrust", json=params)
|
response = self._s.post(self._api + "/cancel_entrust", json=params, timeout=TIMEOUT)
|
||||||
if response.status_code >= 300:
|
if response.status_code >= 300:
|
||||||
raise Exception(response.json()["error"])
|
raise Exception(response.json()["error"])
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
|
###########
|
||||||
|
# written by 黄健威
|
||||||
|
# 以下是新增加的ZMQ Client
|
||||||
|
# 整个接口对外保持和原来的一致
|
||||||
|
# 通过对原requests接口的“鸭子类型替换”来实现透明化
|
||||||
|
|
||||||
|
def use(broker, host, port=1430, use_zmq=True, **kwargs):
|
||||||
|
if use_zmq:
|
||||||
|
return ZMQRemoteClient(broker, host, port)
|
||||||
|
else:
|
||||||
|
return RemoteClient(broker, host, port)
|
||||||
|
|
||||||
|
class ZMQResponse(object):
|
||||||
|
# 这个类是模仿requests的返回结果
|
||||||
|
def __init__(self, status_code, data) -> None:
|
||||||
|
self.data = data
|
||||||
|
self.status_code = status_code
|
||||||
|
|
||||||
|
def json(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
class MyRpcClient(RpcClient):
|
||||||
|
# 这个类把vnpy原生的rpc组件中的超时输出去除
|
||||||
|
# 原版rpc组件中,如果上一个请求后30秒内没有新的请求,会输出一段提示
|
||||||
|
def on_disconnected(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ZMQSession(object):
|
||||||
|
# 这个类是模仿requests的Session
|
||||||
|
def __init__(self, host, port) -> None:
|
||||||
|
req_addr = "tcp://{}:{}".format(host, port)
|
||||||
|
sub_addr = "tcp://{}:{}".format(host, port+1)
|
||||||
|
|
||||||
|
self._rpc_client = MyRpcClient()
|
||||||
|
self._rpc_client.start(req_addr, sub_addr)
|
||||||
|
|
||||||
|
def post(self, url, json=None, timeout=10):
|
||||||
|
name = url.split("/")[-1]
|
||||||
|
data, status_code = self._rpc_client.call_func(name, json)
|
||||||
|
resp = ZMQResponse(status_code, data)
|
||||||
|
return resp
|
||||||
|
|
||||||
|
def get(self, url, json=None, timeout=10):
|
||||||
|
return self.post(url, json, timeout)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
# 当进程开始销毁对象时,显式调用stop来杀死后台的zmq线程,避免死锁无法退出
|
||||||
|
self._rpc_client.stop()
|
||||||
|
|
||||||
|
class ZMQRemoteClient(RemoteClient):
|
||||||
|
# 对原RemoteClient的重载
|
||||||
|
def __init__(self, broker, host, port=1430, **kwargs):
|
||||||
|
self._broker = broker
|
||||||
|
|
||||||
|
# api这个项目已经不需要了
|
||||||
|
self._api = ""
|
||||||
|
# 替换Session
|
||||||
|
self._s = ZMQSession(host, port)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
del self._s
|
@ -15,6 +15,7 @@ from collections import defaultdict
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from time import sleep
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from copy import copy
|
from copy import copy
|
||||||
@ -1072,6 +1073,10 @@ class CtaEngine(BaseEngine):
|
|||||||
self.write_log(f'{strategy_name} => 启动交易')
|
self.write_log(f'{strategy_name} => 启动交易')
|
||||||
self.start_strategy(strategy_name)
|
self.start_strategy(strategy_name)
|
||||||
|
|
||||||
|
# 等待3秒,避免快速重新请求rest数据
|
||||||
|
self.write_log(f'等待3秒')
|
||||||
|
sleep(3)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
msg = f'{strategy_name} => 执行on_init异常:{str(ex)}'
|
msg = f'{strategy_name} => 执行on_init异常:{str(ex)}'
|
||||||
self.write_error(msg)
|
self.write_error(msg)
|
||||||
@ -1822,6 +1827,7 @@ class CtaEngine(BaseEngine):
|
|||||||
self.strategy_setting = load_json(self.setting_filename)
|
self.strategy_setting = load_json(self.setting_filename)
|
||||||
|
|
||||||
for strategy_name, strategy_config in self.strategy_setting.items():
|
for strategy_name, strategy_config in self.strategy_setting.items():
|
||||||
|
self.write_log(f'开始加载{strategy_name}')
|
||||||
self.add_strategy(
|
self.add_strategy(
|
||||||
class_name=strategy_config["class_name"],
|
class_name=strategy_config["class_name"],
|
||||||
strategy_name=strategy_name,
|
strategy_name=strategy_name,
|
||||||
@ -1831,6 +1837,7 @@ class CtaEngine(BaseEngine):
|
|||||||
auto_start=strategy_config.get('auto_start', False)
|
auto_start=strategy_config.get('auto_start', False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_strategy_setting(self, strategy_name: str, setting: dict, auto_init: bool = False,
|
def update_strategy_setting(self, strategy_name: str, setting: dict, auto_init: bool = False,
|
||||||
auto_start: bool = False):
|
auto_start: bool = False):
|
||||||
"""
|
"""
|
||||||
|
@ -335,6 +335,7 @@ class PortfolioTestingEngine(BackTestingEngine):
|
|||||||
last_trading_day = bar.trading_day
|
last_trading_day = bar.trading_day
|
||||||
|
|
||||||
# 第二个交易日,撤单
|
# 第二个交易日,撤单
|
||||||
|
if not symbol.startswith('future_renko'):
|
||||||
self.cancel_orders()
|
self.cancel_orders()
|
||||||
# 更新持仓缓存
|
# 更新持仓缓存
|
||||||
self.update_pos_buffer()
|
self.update_pos_buffer()
|
||||||
|
@ -1386,6 +1386,7 @@ class CtaProFutureTemplate(CtaProTemplate):
|
|||||||
if active_order['offset'] != Offset.OPEN:
|
if active_order['offset'] != Offset.OPEN:
|
||||||
grid.open_status = False
|
grid.open_status = False
|
||||||
grid.close_status = True
|
grid.close_status = True
|
||||||
|
grid.open_time = None
|
||||||
|
|
||||||
self.write_log(f'{grid.direction.value}单已平仓完毕,order_price:{order.price}'
|
self.write_log(f'{grid.direction.value}单已平仓完毕,order_price:{order.price}'
|
||||||
+ f',volume:{order.volume}')
|
+ f',volume:{order.volume}')
|
||||||
@ -1396,6 +1397,7 @@ class CtaProFutureTemplate(CtaProTemplate):
|
|||||||
# 开仓完毕( buy, short)
|
# 开仓完毕( buy, short)
|
||||||
else:
|
else:
|
||||||
grid.open_status = True
|
grid.open_status = True
|
||||||
|
grid.open_time = self.cur_datetime
|
||||||
self.write_log(f'{grid.direction.value}单已开仓完毕,order_price:{order.price}'
|
self.write_log(f'{grid.direction.value}单已开仓完毕,order_price:{order.price}'
|
||||||
+ f',volume:{order.volume}')
|
+ f',volume:{order.volume}')
|
||||||
|
|
||||||
|
@ -5535,6 +5535,11 @@ class CtaLineBar(object):
|
|||||||
# 当前bar已计算
|
# 当前bar已计算
|
||||||
self.chanlun_calculated = True
|
self.chanlun_calculated = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cur_fenxing(self):
|
||||||
|
"""当前分型"""
|
||||||
|
return self.fenxing_list[-1] if len(self.fenxing_list) > 0 else None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fenxing_list(self):
|
def fenxing_list(self):
|
||||||
if not self.chanlun_calculated:
|
if not self.chanlun_calculated:
|
||||||
@ -5590,12 +5595,6 @@ class CtaLineBar(object):
|
|||||||
self.__count_chanlun()
|
self.__count_chanlun()
|
||||||
return self._duan_zs_list
|
return self._duan_zs_list
|
||||||
|
|
||||||
@property
|
|
||||||
def duan_zs_list(self):
|
|
||||||
if not self.chanlun_calculated:
|
|
||||||
self.__count_chanlun()
|
|
||||||
return self._duan_zs_list
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cur_duan_zs(self):
|
def cur_duan_zs(self):
|
||||||
"""当前段中枢"""
|
"""当前段中枢"""
|
||||||
@ -6106,6 +6105,7 @@ class CtaLineBar(object):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
from vnpy.trader.constant import ChanSignals, Direction
|
from vnpy.trader.constant import ChanSignals, Direction
|
||||||
from vnpy.component.chanlun.pyChanlun import ChanBi, ChanDuan, ChanObject
|
from vnpy.component.chanlun.pyChanlun import ChanBi, ChanDuan, ChanObject
|
||||||
from vnpy.component.cta_line_bar import CtaLineBar
|
from vnpy.component.cta_line_bar import CtaLineBar
|
||||||
from typing import List
|
from typing import List, Union
|
||||||
|
|
||||||
# 所有底背驰信号集合
|
# 所有底背驰信号集合
|
||||||
DI_BEICHI_SIGNALS = [ChanSignals.LA0.value, ChanSignals.LA1.value, ChanSignals.LA2.value, ChanSignals.LA3.value,
|
DI_BEICHI_SIGNALS = [ChanSignals.LA0.value, ChanSignals.LA1.value, ChanSignals.LA2.value, ChanSignals.LA3.value,
|
||||||
@ -60,7 +60,7 @@ def check_duan_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
|||||||
|
|
||||||
def check_bi_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
def check_bi_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
||||||
"""
|
"""
|
||||||
检查某一个K线当前分笔是否非实时
|
检查某一个K线当前分笔是否非实时并符合判断方向
|
||||||
:param kline:
|
:param kline:
|
||||||
:param Direction:
|
:param Direction:
|
||||||
:return:
|
:return:
|
||||||
@ -82,6 +82,68 @@ def check_bi_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_fx_power(kline: CtaLineBar, direction: Direction) -> str:
|
||||||
|
"""
|
||||||
|
获取分型强弱
|
||||||
|
:param kline: 本级别K线
|
||||||
|
:param direction: 分型方向: 1:顶分型;-1:底分型
|
||||||
|
:return: 强,普通,弱,不匹配
|
||||||
|
"""
|
||||||
|
ret = '不匹配'
|
||||||
|
|
||||||
|
# 不存在分型,或者分型还没结束,不做判断
|
||||||
|
if not kline.cur_fenxing or kline.cur_fenxing.is_rt:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
direction = 1 if direction == Direction.LONG else -1
|
||||||
|
|
||||||
|
# 分型方向不一致
|
||||||
|
if kline.cur_fenxing.direction != direction:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# 分型前x根bar
|
||||||
|
pre_bars = [bar for bar in kline.line_bar[-10:] if
|
||||||
|
bar.datetime.strftime('%Y-%m-%d %H:%M:%S') < kline.cur_fenxing.index]
|
||||||
|
|
||||||
|
if len(pre_bars) == 0:
|
||||||
|
return ret
|
||||||
|
pre_bar = pre_bars[-1]
|
||||||
|
|
||||||
|
# 分型后x根bar
|
||||||
|
extra_bars = \
|
||||||
|
[bar for bar in kline.line_bar[-10:] if bar.datetime.strftime('%Y-%m-%d %H:%M:%S') > kline.cur_fenxing.index]
|
||||||
|
|
||||||
|
# 分型后,有三根bar
|
||||||
|
if len(extra_bars) < 3:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# 处理顶分型
|
||||||
|
if kline.cur_fenxing.direction == 1:
|
||||||
|
# 顶分型后第一根bar的低点,没有超过前bar的低点
|
||||||
|
if extra_bars[0].low_price >= pre_bar.low_price:
|
||||||
|
return '普通'
|
||||||
|
|
||||||
|
# 找到正确形态,第二、第三根bar,都站在顶分型之下
|
||||||
|
if pre_bar.low_price >= extra_bars[1].high_price > extra_bars[2].high_price:
|
||||||
|
return '强'
|
||||||
|
|
||||||
|
return '普通'
|
||||||
|
|
||||||
|
# 处理底分型
|
||||||
|
if kline.cur_fenxing.direction == -1:
|
||||||
|
# 底分型后第一根bar的高点,没有超过前bar的高点
|
||||||
|
if extra_bars[0].high_price <= pre_bar.high_price:
|
||||||
|
return '弱'
|
||||||
|
|
||||||
|
# 找到正确形态,第二、第三根bar,都站在底分型之上
|
||||||
|
if pre_bar.high_price <= extra_bars[1].low_price < extra_bars[2].low_price:
|
||||||
|
return '强'
|
||||||
|
|
||||||
|
return '普通'
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def check_chan_xt(kline: CtaLineBar, bi_list: List[ChanObject]) -> str:
|
def check_chan_xt(kline: CtaLineBar, bi_list: List[ChanObject]) -> str:
|
||||||
"""
|
"""
|
||||||
获取缠论得形态
|
获取缠论得形态
|
||||||
@ -100,8 +162,8 @@ def check_chan_xt(kline: CtaLineBar, bi_list: List[ChanObject]) -> str:
|
|||||||
return check_chan_xt_nine_bi(kline, bi_list)
|
return check_chan_xt_nine_bi(kline, bi_list)
|
||||||
if len(bi_list) == 11:
|
if len(bi_list) == 11:
|
||||||
return check_chan_xt_eleven_bi(kline, bi_list)
|
return check_chan_xt_eleven_bi(kline, bi_list)
|
||||||
if len(bi_list) == 13:
|
if len(bi_list) >= 13:
|
||||||
return check_chan_xt_thirteen_bi(kline, bi_list)
|
return check_chan_xt_thirteen_bi(kline, bi_list[-13:])
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
|
||||||
@ -201,9 +263,10 @@ def check_chan_xt_five_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if (min_low == bi_3.low and bi_5.low < bi_1.low) or (min_low == bi_5.low):
|
if (min_low == bi_3.low and bi_5.low < bi_1.low) or (min_low == bi_5.low):
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# 类趋势底背驰
|
# 类趋势底背驰( 笔5 的强度比笔1、笔3低)
|
||||||
if max_high == bi_1.high and min_low == bi_5.low and bi_4.high < bi_2.low and bi_5.height < max(bi_3.height,
|
if max_high == bi_1.high and min_low == bi_5.low and bi_4.high < bi_2.low \
|
||||||
bi_1.height):
|
and bi_5.height < max(bi_3.height, bi_1.height) \
|
||||||
|
and bi_5.atan < max(bi_3.atan, bi_1.atan):
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# 上颈线突破
|
# 上颈线突破
|
||||||
@ -231,8 +294,10 @@ def check_chan_xt_five_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# 类趋势顶背驰
|
# 类趋势顶背驰
|
||||||
if min_low == bi_1.low and max_high == bi_5.high and bi_5.height < max(bi_1.height,
|
if min_low == bi_1.low and max_high == bi_5.high \
|
||||||
bi_3.height) and bi_4.low > bi_2.high:
|
and bi_5.height < max(bi_1.height, bi_3.height) \
|
||||||
|
and bi_5.atan < max(bi_1.atan, bi_3.atan) \
|
||||||
|
and bi_4.low > bi_2.high:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# 下颈线突破
|
# 下颈线突破
|
||||||
@ -240,7 +305,7 @@ def check_chan_xt_five_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
or (max_high == bi_3.high and bi_5.low < bi_3.low < bi_5.high < max_high):
|
or (max_high == bi_3.high and bi_5.low < bi_3.low < bi_5.high < max_high):
|
||||||
v = ChanSignals.SG0.value
|
v = ChanSignals.SG0.value
|
||||||
|
|
||||||
# 五笔三卖,要求bi_5.low是最低点
|
# 五笔三卖,要求bi_5.low是最低点,中枢可能是1~3
|
||||||
if min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_5.high and bi_5.low == min_low:
|
if min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_5.high and bi_5.low == min_low:
|
||||||
v = ChanSignals.SI0.value
|
v = ChanSignals.SI0.value
|
||||||
|
|
||||||
@ -271,21 +336,26 @@ def check_chan_xt_seven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
|
|
||||||
if bi_7.direction == -1:
|
if bi_7.direction == -1:
|
||||||
if bi_1.high == max_high and bi_7.low == min_low:
|
if bi_1.high == max_high and bi_7.low == min_low:
|
||||||
# aAbcd式底背驰
|
# aAbcd式底背驰, d.高度斜率 小于 b.高度斜率
|
||||||
if min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high and bi_7.height < bi_5.height:
|
if min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high \
|
||||||
|
and bi_7.height < bi_5.height and bi_7.atan <= bi_5.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# abcAd式底背驰
|
# abcAd式底背驰
|
||||||
if bi_2.low > min(bi_4.high, bi_6.high) > max(bi_4.low, bi_6.low) and bi_7.height < (bi_1.high - bi_3.low):
|
if bi_2.low > min(bi_4.high, bi_6.high) > max(bi_4.low, bi_6.low) \
|
||||||
|
and bi_7.height < (bi_1.high - bi_3.low) \
|
||||||
|
and bi_7.atan < (bi_1.atan + bi_3.atan) / 2:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# aAb式底背驰
|
# aAb式底背驰
|
||||||
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) and bi_7.height < bi_1.height:
|
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) \
|
||||||
|
and bi_7.height < bi_1.height and bi_7.atan <= bi_1.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# 类趋势底背驰
|
# 类趋势底背驰
|
||||||
if bi_2.low > bi_4.high and bi_4.low > bi_6.high and bi_7.height < max(bi_5.height, bi_3.height,
|
if bi_2.low > bi_4.high and bi_4.low > bi_6.high \
|
||||||
bi_1.height):
|
and bi_7.height < max(bi_5.height, bi_3.height, bi_1.height)\
|
||||||
|
and bi_7.atan < max(bi_5.atan, bi_3.atan, bi_1.atan):
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# 向上中枢完成
|
# 向上中枢完成
|
||||||
@ -304,20 +374,25 @@ def check_chan_xt_seven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
# 顶背驰
|
# 顶背驰
|
||||||
if bi_1.low == min_low and bi_7.high == max_high:
|
if bi_1.low == min_low and bi_7.high == max_high:
|
||||||
# aAbcd式顶背驰
|
# aAbcd式顶背驰
|
||||||
if bi_6.low > min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) and bi_7.height < bi_5.height:
|
if bi_6.low > min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) \
|
||||||
|
and bi_7.height < bi_5.height and bi_7.atan <= bi_5.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# abcAd式顶背驰
|
# abcAd式顶背驰
|
||||||
if min(bi_4.high, bi_6.high) > max(bi_4.low, bi_6.low) > bi_2.high and bi_7.height < (bi_3.high - bi_1.low):
|
if min(bi_4.high, bi_6.high) > max(bi_4.low, bi_6.low) > bi_2.high \
|
||||||
|
and bi_7.height < (bi_3.high - bi_1.low) \
|
||||||
|
and bi_7.atan < (bi_1.atan + bi_3.atan) / 2:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# aAb式顶背驰
|
# aAb式顶背驰
|
||||||
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) and bi_7.height < bi_1.height:
|
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) \
|
||||||
|
and bi_7.height < bi_1.height and bi_7.atan <= bi_1.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# 类趋势顶背驰
|
# 类趋势顶背驰
|
||||||
if bi_2.high < bi_4.low and bi_4.high < bi_6.low and bi_7.height < max(bi_5.height, bi_3.height,
|
if bi_2.high < bi_4.low and bi_4.high < bi_6.low \
|
||||||
bi_1.height):
|
and bi_7.height < max(bi_5.height, bi_3.height, bi_1.height)\
|
||||||
|
and bi_7.atan < max(bi_5.atan, bi_3.atan, bi_1.atan):
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# 向下中枢完成
|
# 向下中枢完成
|
||||||
@ -327,7 +402,7 @@ def check_chan_xt_seven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if min(bi_1.high, bi_3.high) > min(bi_5.low, bi_7.low):
|
if min(bi_1.high, bi_3.high) > min(bi_5.low, bi_7.low):
|
||||||
v = ChanSignals.SH0.value
|
v = ChanSignals.SH0.value
|
||||||
|
|
||||||
# 七笔三卖,567回调
|
# 七笔三卖,567回调,中枢可能在1~3
|
||||||
if bi_5.low == min_low and bi_5.low < bi_7.low \
|
if bi_5.low == min_low and bi_5.low < bi_7.low \
|
||||||
and min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_7.high > bi_5.high:
|
and min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_7.high > bi_5.high:
|
||||||
v = ChanSignals.SI0.value
|
v = ChanSignals.SI0.value
|
||||||
@ -357,17 +432,18 @@ def check_chan_xt_nine_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high \
|
if 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.height < bi_5.height and bi_7.atan <= bi_5.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# aAb式底背驰
|
# aAb式底背驰
|
||||||
if min(bi_2.high, bi_4.high, bi_6.high, bi_8.high) > max(bi_2.low, bi_4.low, bi_6.low, bi_8.low) \
|
if min(bi_2.high, bi_4.high, bi_6.high, bi_8.high) > max(bi_2.low, bi_4.low, bi_6.low, bi_8.low) \
|
||||||
and bi_9.height < bi_1.height and bi_3.low >= bi_1.low and bi_7.high <= bi_9.high:
|
and bi_9.height < bi_1.height and bi_9.atan <= bi_1.atan \
|
||||||
|
and bi_3.low >= bi_1.low and bi_7.high <= bi_9.high:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# aAbcd式底背驰
|
# aAbcd式底背驰
|
||||||
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) > bi_8.high \
|
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) > bi_8.high \
|
||||||
and bi_9.height < bi_7.height:
|
and bi_9.height < bi_7.height and bi_9.atan <= bi_7.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# ABC式底背驰
|
# ABC式底背驰
|
||||||
@ -376,7 +452,7 @@ def check_chan_xt_nine_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and (bi_1.high - bi_3.low) > (bi_7.high - bi_9.low):
|
and (bi_1.high - bi_3.low) > (bi_7.high - bi_9.low):
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# 九笔三买
|
# 九笔三买(789回调)中枢可能在3~7内
|
||||||
if min_low == bi_1.low and max_high == bi_9.high \
|
if min_low == bi_1.low and max_high == bi_9.high \
|
||||||
and bi_9.low > min([x.high for x in [bi_3, bi_5, bi_7]]) > max([x.low for x in [bi_3, bi_5, bi_7]]):
|
and bi_9.low > min([x.high for x in [bi_3, bi_5, bi_7]]) > max([x.low for x in [bi_3, bi_5, bi_7]]):
|
||||||
v = ChanSignals.LI0.value
|
v = ChanSignals.LI0.value
|
||||||
@ -387,17 +463,18 @@ def check_chan_xt_nine_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if bi_6.low > min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) \
|
if 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.height < bi_5.height and bi_9.atan <= bi_5.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# aAb式顶背驰
|
# aAb式顶背驰
|
||||||
if min(bi_2.high, bi_4.high, bi_6.high, bi_8.high) > max(bi_2.low, bi_4.low, bi_6.low, bi_8.low) \
|
if min(bi_2.high, bi_4.high, bi_6.high, bi_8.high) > max(bi_2.low, bi_4.low, bi_6.low, bi_8.low) \
|
||||||
and bi_9.height < bi_1.height and bi_3.high <= bi_1.high and bi_7.low >= bi_9.low:
|
and bi_9.height < bi_1.height and bi_9.atan <= bi_1.atan \
|
||||||
|
and bi_3.high <= bi_1.high and bi_7.low >= bi_9.low:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# aAbcd式顶背驰
|
# aAbcd式顶背驰
|
||||||
if bi_8.low > min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) \
|
if bi_8.low > min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) \
|
||||||
and bi_9.height < bi_7.height:
|
and bi_9.height < bi_7.height and bi_9.atan <= bi_7.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# ABC式顶背驰
|
# ABC式顶背驰
|
||||||
@ -435,14 +512,14 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) > bi_8.high \
|
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) > bi_8.high \
|
||||||
and min(bi_8.high, bi_10.high) > max(bi_8.low, bi_10.low) \
|
and min(bi_8.high, bi_10.high) > max(bi_8.low, bi_10.low) \
|
||||||
and min(bi_2.low, bi_4.low, bi_6.low) > max(bi_8.high, bi_10.high) \
|
and min(bi_2.low, bi_4.low, bi_6.low) > max(bi_8.high, bi_10.high) \
|
||||||
and bi_11.height < bi_7.height:
|
and bi_11.height < bi_7.height and bi_11.atan <= bi_7.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# aAbBc式底背驰,bi_6-bi_10构成B
|
# aAbBc式底背驰,bi_6-bi_10构成B
|
||||||
if min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high \
|
if 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, 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 min(bi_2.low, bi_4.low) > max(bi_6.high, bi_8.high, bi_10.high) \
|
and min(bi_2.low, bi_4.low) > max(bi_6.high, bi_8.high, bi_10.high) \
|
||||||
and bi_11.height < bi_5.height:
|
and bi_11.height < bi_5.height and bi_11.atan <= bi_5.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# ABC式底背驰,A5B3C3
|
# ABC式底背驰,A5B3C3
|
||||||
@ -460,7 +537,7 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_6.high > bi_4.low and bi_1.high - bi_3.low > bi_7.high - bi_11.low:
|
and bi_6.high > bi_4.low and bi_1.high - bi_3.low > bi_7.high - bi_11.low:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
# C内部背驰
|
# C内部背驰
|
||||||
if bi_11.height < max(bi_9.height, bi_7.height):
|
if bi_11.height < max(bi_9.height, bi_7.height) and bi_11.atan <= max(bi_9.atan, bi_7.atan):
|
||||||
v = ChanSignals.LB0.value
|
v = ChanSignals.LB0.value
|
||||||
|
|
||||||
# ABC式底背驰,A3B5C3
|
# ABC式底背驰,A3B5C3
|
||||||
@ -468,7 +545,7 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_9.high > bi_11.high and bi_1.high - bi_3.low > bi_9.high - bi_11.low:
|
and bi_9.high > bi_11.high and bi_1.high - bi_3.low > bi_9.high - bi_11.low:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
# C内部背驰
|
# C内部背驰
|
||||||
if bi_11.height < max(bi_9.height, bi_7.height):
|
if bi_11.height < max(bi_9.height, bi_7.height) and bi_11.atan <= max(bi_9.atan, bi_7.atan):
|
||||||
v = ChanSignals.LB0.value
|
v = ChanSignals.LB0.value
|
||||||
|
|
||||||
elif direction == 1:
|
elif direction == 1:
|
||||||
@ -477,14 +554,14 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if bi_8.low > min(bi_2.high, bi_4.high, bi_6.high) >= max(bi_2.low, bi_4.low, bi_6.low) \
|
if bi_8.low > min(bi_2.high, bi_4.high, bi_6.high) >= max(bi_2.low, bi_4.low, bi_6.low) \
|
||||||
and min(bi_8.high, bi_10.high) >= max(bi_8.low, bi_10.low) \
|
and min(bi_8.high, bi_10.high) >= max(bi_8.low, bi_10.low) \
|
||||||
and max(bi_2.high, bi_4.high, bi_6.high) < min(bi_8.low, bi_10.low) \
|
and max(bi_2.high, bi_4.high, bi_6.high) < min(bi_8.low, bi_10.low) \
|
||||||
and bi_11.height < bi_7.height:
|
and bi_11.height < bi_7.height and bi_11.atan <= bi_7.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# aAbBC式顶背驰,bi_6-bi_10构成B
|
# aAbBC式顶背驰,bi_6-bi_10构成B
|
||||||
if bi_6.low > min(bi_2.high, bi_4.high) >= max(bi_2.low, bi_4.low) \
|
if 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, 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 max(bi_2.high, bi_4.high) < min(bi_6.low, bi_8.low, bi_10.low) \
|
and max(bi_2.high, bi_4.high) < min(bi_6.low, bi_8.low, bi_10.low) \
|
||||||
and bi_11.height < bi_7.height:
|
and bi_11.height < bi_7.height and bi_11.atan <= bi_7.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# ABC式顶背驰,A5B3C3
|
# ABC式顶背驰,A5B3C3
|
||||||
@ -492,7 +569,7 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_8.low < bi_6.high and bi_11.high - bi_9.low < bi_5.high - bi_1.low:
|
and bi_8.low < bi_6.high and bi_11.high - bi_9.low < bi_5.high - bi_1.low:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
# C内部背驰
|
# C内部背驰
|
||||||
if bi_11.height < bi_9.height:
|
if bi_11.height < bi_9.height and bi_11.atan <= bi_9.atan:
|
||||||
v = ChanSignals.SB0.value
|
v = ChanSignals.SB0.value
|
||||||
|
|
||||||
# ABC式顶背驰,A3B3C5
|
# ABC式顶背驰,A3B3C5
|
||||||
@ -500,7 +577,7 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_6.low < bi_4.high and bi_11.high - bi_7.low < bi_3.high - bi_1.low:
|
and bi_6.low < bi_4.high and bi_11.high - bi_7.low < bi_3.high - bi_1.low:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
# C内部背驰
|
# C内部背驰
|
||||||
if bi_11.height < max(bi_9.height, bi_7.height):
|
if bi_11.height < max(bi_9.height, bi_7.height) and bi_11.atan <= max(bi_9.atan, bi_7.atan):
|
||||||
v = ChanSignals.SB0.value
|
v = ChanSignals.SB0.value
|
||||||
|
|
||||||
# ABC式顶背驰,A3B5C3
|
# ABC式顶背驰,A3B5C3
|
||||||
@ -508,7 +585,7 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_9.low < bi_11.low and bi_3.high - bi_1.low > bi_11.high - bi_9.low:
|
and bi_9.low < bi_11.low and bi_3.high - bi_1.low > bi_11.high - bi_9.low:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
# C内部背驰
|
# C内部背驰
|
||||||
if bi_11.height < max(bi_9.height, bi_7.height):
|
if bi_11.height < max(bi_9.height, bi_7.height) and bi_11.atan <= max(bi_9.atan, bi_7.atan):
|
||||||
v = ChanSignals.SB0.value
|
v = ChanSignals.SB0.value
|
||||||
|
|
||||||
return v
|
return v
|
||||||
@ -536,7 +613,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) > bi_8.high \
|
if min(bi_2.high, bi_4.high, bi_6.high) > max(bi_2.low, bi_4.low, bi_6.low) > bi_8.high \
|
||||||
and min(bi_8.high, bi_10.high, bi_12.high) > max(bi_8.low, bi_10.low, bi_12.low) \
|
and min(bi_8.high, bi_10.high, bi_12.high) > max(bi_8.low, bi_10.low, bi_12.low) \
|
||||||
and min(bi_2.low, bi_4.low, bi_6.low) > max(bi_8.high, bi_10.high, bi_12.high) \
|
and min(bi_2.low, bi_4.low, bi_6.low) > max(bi_8.high, bi_10.high, bi_12.high) \
|
||||||
and bi_13.height < bi_7.height:
|
and bi_13.height < bi_7.height and bi_13.atan <= bi_7.atan:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
# ABC式底背驰,A5B3C5
|
# ABC式底背驰,A5B3C5
|
||||||
@ -544,7 +621,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
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:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
if bi_13.height < max(bi_11.height, bi_9.height):
|
if bi_13.height < max(bi_11.height, bi_9.height) and bi_13.atan <= max(bi_11.atan, bi_9.atan):
|
||||||
v = ChanSignals.LB0.value
|
v = ChanSignals.LB0.value
|
||||||
|
|
||||||
# ABC式底背驰,A3B5C5
|
# ABC式底背驰,A3B5C5
|
||||||
@ -553,7 +630,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_1.high - bi_3.low > bi_9.high - bi_13.low:
|
and bi_1.high - bi_3.low > bi_9.high - bi_13.low:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
if bi_13.height < max(bi_11.height, bi_9.height):
|
if bi_13.height < max(bi_11.height, bi_9.height) and bi_13.atan <= max(bi_11.atan, bi_9.atan):
|
||||||
v = ChanSignals.LB0.value
|
v = ChanSignals.LB0.value
|
||||||
|
|
||||||
# ABC式底背驰,A5B5C3
|
# ABC式底背驰,A5B5C3
|
||||||
@ -562,7 +639,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
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:
|
||||||
v = ChanSignals.LA0.value
|
v = ChanSignals.LA0.value
|
||||||
|
|
||||||
if bi_13.height < bi_11.height:
|
if bi_13.height < bi_11.height and bi_13.atan <= bi_11.atan:
|
||||||
v = ChanSignals.LB0.value
|
v = ChanSignals.LB0.value
|
||||||
|
|
||||||
# 上涨线段时,判断背驰类型
|
# 上涨线段时,判断背驰类型
|
||||||
@ -572,7 +649,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
if bi_8.low > min(bi_2.high, bi_4.high, bi_6.high) >= max(bi_2.low, bi_4.low, bi_6.low) \
|
if bi_8.low > min(bi_2.high, bi_4.high, bi_6.high) >= max(bi_2.low, bi_4.low, bi_6.low) \
|
||||||
and min(bi_8.high, bi_10.high, bi_12.high) >= max(bi_8.low, bi_10.low, bi_12.low) \
|
and min(bi_8.high, bi_10.high, bi_12.high) >= max(bi_8.low, bi_10.low, bi_12.low) \
|
||||||
and max(bi_2.high, bi_4.high, bi_6.high) < min(bi_8.low, bi_10.low, bi_12.low) \
|
and max(bi_2.high, bi_4.high, bi_6.high) < min(bi_8.low, bi_10.low, bi_12.low) \
|
||||||
and bi_13.height < bi_7.height:
|
and bi_13.height < bi_7.height and bi_13.atan <= bi_7.atan:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
|
|
||||||
# ABC式顶背驰,A5B3C5
|
# ABC式顶背驰,A5B3C5
|
||||||
@ -580,7 +657,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
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:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
# C内部顶背驰,形成双重顶背驰
|
# C内部顶背驰,形成双重顶背驰
|
||||||
if bi_13.height < max(bi_11.height, bi_9.height):
|
if bi_13.height < max(bi_11.height, bi_9.height) and bi_13.atan <= max(bi_11.atan, bi_9.atan):
|
||||||
v = ChanSignals.SB0.value
|
v = ChanSignals.SB0.value
|
||||||
|
|
||||||
# ABC式顶背驰,A3B5C5
|
# ABC式顶背驰,A3B5C5
|
||||||
@ -589,7 +666,7 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_3.high - bi_1.low > bi_13.high - bi_9.low:
|
and bi_3.high - bi_1.low > bi_13.high - bi_9.low:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
# C内部顶背驰,形成双重顶背驰
|
# C内部顶背驰,形成双重顶背驰
|
||||||
if bi_13.height < max(bi_11.height, bi_9.height):
|
if bi_13.height < max(bi_11.height, bi_9.height) and bi_13.atan <= max(bi_11.atan, bi_9.atan):
|
||||||
v = ChanSignals.SB0.value
|
v = ChanSignals.SB0.value
|
||||||
|
|
||||||
# ABC式顶背驰,A5B5C3
|
# ABC式顶背驰,A5B5C3
|
||||||
@ -598,6 +675,561 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
|||||||
and bi_5.high - bi_1.low > bi_13.high - bi_11.low:
|
and bi_5.high - bi_1.low > bi_13.high - bi_11.low:
|
||||||
v = ChanSignals.SA0.value
|
v = ChanSignals.SA0.value
|
||||||
# C内部顶背驰,形成双重顶背驰
|
# C内部顶背驰,形成双重顶背驰
|
||||||
if bi_13.height < bi_11.height:
|
if bi_13.height < bi_11.height and bi_13.atan <= bi_11.atan:
|
||||||
v = ChanSignals.SB0.value
|
v = ChanSignals.SB0.value
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
def check_pzbc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||||
|
"""
|
||||||
|
判断中枢盘整背驰1买/1卖信号
|
||||||
|
big_kline当前线段为调整段,与信号方向相反,线段具有盘整一个中枢,
|
||||||
|
进入中枢与离开中枢的一笔力度对比(高度、斜率)
|
||||||
|
:param big_kline: 本级别K线
|
||||||
|
:param small_kline: 次级别K线(可选,可以是None)
|
||||||
|
:param signal_direction: 信号方向
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
direction = 1 if signal_direction == Direction.LONG else -1
|
||||||
|
|
||||||
|
# 排除
|
||||||
|
# 没有前线段、没有笔中枢
|
||||||
|
# 当前线段方向与判断方向一致、
|
||||||
|
# 前线段比当前线段高度小
|
||||||
|
if not big_kline.pre_duan \
|
||||||
|
or not big_kline.cur_bi_zs \
|
||||||
|
or big_kline.cur_duan.direction == direction \
|
||||||
|
or big_kline.pre_duan.height < big_kline.cur_duan.height:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 如果有次级别K线时,也要判断方向
|
||||||
|
if small_kline and (not small_kline.pre_duan or small_kline.cur_duan.direction == direction):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段必须有5笔
|
||||||
|
if len(big_kline.cur_duan.bi_list) < 5:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 线段内,只允许有一个中枢
|
||||||
|
if len([zs for zs in big_kline.bi_zs_list[-3:] if zs.start > big_kline.cur_duan.start]) > 1:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前笔中枢必须在当前线段之内
|
||||||
|
if big_kline.cur_bi_zs.start < big_kline.cur_duan.start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段的高低点,与最高、最低分笔一致(不会出现区间套)
|
||||||
|
if signal_direction == Direction.LONG:
|
||||||
|
# 当前最后一笔,就是线段的最后一笔
|
||||||
|
if not duan_bi_is_end(big_kline.cur_duan, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
# 当前的线段,已经具备底分型
|
||||||
|
if not check_duan_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
# 当前的笔,走完,具备底分型
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if not duan_bi_is_end(big_kline.cur_duan, Direction.LONG):
|
||||||
|
return False
|
||||||
|
if not check_duan_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
# 笔走完
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 中枢的进入笔、离开笔
|
||||||
|
# 中枢的首笔与线段不同向,则选择中枢之前的一笔和最后的一笔
|
||||||
|
if big_kline.cur_bi_zs.bi_list[0].direction != big_kline.cur_duan.direction:
|
||||||
|
entry_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end <= big_kline.cur_bi_zs.start]
|
||||||
|
exit_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end > big_kline.cur_bi_zs.end]
|
||||||
|
if not (len(entry_bi_list) >= 1 and len(exit_bi_list) == 1):
|
||||||
|
return False
|
||||||
|
entry_bi = entry_bi_list[-1]
|
||||||
|
exit_bi = exit_bi_list[0]
|
||||||
|
|
||||||
|
# 中枢首笔跟线段同向
|
||||||
|
else:
|
||||||
|
entry_bi = big_kline.cur_bi_zs.bi_list[0]
|
||||||
|
exit_bi = big_kline.cur_duan.bi_list[-1]
|
||||||
|
|
||||||
|
# 进入笔的高度,要高于离开笔,或者,进入笔的斜率,要大于离开笔
|
||||||
|
if entry_bi.height > exit_bi.height or entry_bi.atan > exit_bi.atan:
|
||||||
|
|
||||||
|
# 分析次级别K线,判断其是否也发生线段背驰
|
||||||
|
if small_kline:
|
||||||
|
if len(small_kline.cur_duan.bi_list) > 1:
|
||||||
|
if (small_kline.cur_duan.bi_list[0].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[0].atan > small_kline.cur_duan.bi_list[-1].atan) \
|
||||||
|
or (small_kline.cur_duan.bi_list[-3].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[-3].atan > small_kline.cur_duan.bi_list[-1].atan):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 判断是否macd背驰
|
||||||
|
if big_kline.is_macd_divergence(big_kline.cur_duan.direction, exit_bi.end, entry_bi.end):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_qsbc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||||
|
"""
|
||||||
|
判断趋势背驰1买/1卖信号
|
||||||
|
big_kline当前线段为趋势,与信号方向相反,线段具有2个中枢,
|
||||||
|
进入最后中枢与离开中枢的一笔力度对比(高度、斜率)
|
||||||
|
:param big_kline: 本级别K线
|
||||||
|
:param small_kline: 次级别K线(可选,可以是None)
|
||||||
|
:param signal_direction: 信号方向
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
direction = 1 if signal_direction == Direction.LONG else -1
|
||||||
|
# 排除
|
||||||
|
# 没有前线段、没有笔中枢
|
||||||
|
# 当前线段方向与判断方向一致
|
||||||
|
if not big_kline.pre_duan \
|
||||||
|
or not big_kline.cur_bi_zs \
|
||||||
|
or big_kline.cur_duan.direction == direction:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 如果有次级别K线时,也要判断方向
|
||||||
|
if small_kline and (not small_kline.pre_duan or small_kline.cur_duan.direction == direction):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 线段内,至少有2个或以上中枢
|
||||||
|
if len([zs for zs in big_kline.bi_zs_list[-4:] if zs.start > big_kline.cur_duan.start]) < 2:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段的高低点,与最高、最低分笔一致(不会出现区间套)
|
||||||
|
if signal_direction == Direction.LONG:
|
||||||
|
|
||||||
|
# 笔走完
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not check_duan_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 最后一笔
|
||||||
|
if not duan_bi_is_end(big_kline.cur_duan, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
|
||||||
|
else:
|
||||||
|
# 笔走完
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
if not check_duan_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
# 最后一笔
|
||||||
|
if not duan_bi_is_end(big_kline.cur_duan, Direction.LONG):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 中枢的进入笔、离开笔
|
||||||
|
entry_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end <= big_kline.cur_bi_zs.start]
|
||||||
|
exit_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end > big_kline.cur_bi_zs.end]
|
||||||
|
if not (len(entry_bi_list) >= 1 and len(exit_bi_list) == 1):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 离开中枢的一笔,其middle必须也不在中枢内
|
||||||
|
if signal_direction == Direction.LONG and exit_bi_list[0].middle > big_kline.cur_bi_zs.low:
|
||||||
|
return False
|
||||||
|
if signal_direction == Direction.SHORT and exit_bi_list[0].middle < big_kline.cur_bi_zs.high:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 进入中枢一笔,与离开中枢笔,方向必须相同
|
||||||
|
if entry_bi_list[-1].direction != exit_bi_list[-1].direction:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 进入笔的高度,要高于离开笔,或者,进入笔的斜率,要大于离开笔
|
||||||
|
if entry_bi_list[-1].height > exit_bi_list[0].height and entry_bi_list[-1].atan > exit_bi_list[0].atan:
|
||||||
|
|
||||||
|
# 分析次级别K线,判断其是否也发生线段背驰
|
||||||
|
if small_kline:
|
||||||
|
if len(small_kline.cur_duan.bi_list) > 1:
|
||||||
|
if (small_kline.cur_duan.bi_list[0].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[0].atan > small_kline.cur_duan.bi_list[-1].atan) \
|
||||||
|
or (small_kline.cur_duan.bi_list[-3].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[-3].atan > small_kline.cur_duan.bi_list[-1].atan):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_pz3bc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||||
|
"""
|
||||||
|
判断三卖后盘整背驰一买/三买后盘整背驰1卖信号
|
||||||
|
big_kline当前线段与信号方向相反,线段具有盘整一个中枢,离开中枢的一笔力度与三买/卖信号后的一笔对比(高度、斜率)
|
||||||
|
:param big_kline: 本级别K线
|
||||||
|
:param small_kline: 次级别K线(可选,可以是None)
|
||||||
|
:param signal_direction: 信号方向
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
direction = 1 if signal_direction == Direction.LONG else -1
|
||||||
|
|
||||||
|
# 排除
|
||||||
|
# 没有前线段、没有笔中枢
|
||||||
|
# 当前线段方向与判断方向一致、
|
||||||
|
if not big_kline.pre_duan \
|
||||||
|
or not big_kline.cur_bi_zs \
|
||||||
|
or big_kline.cur_duan.direction == direction:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 如果有次级别K线时,也要判断方向
|
||||||
|
if small_kline and (not small_kline.pre_duan or small_kline.cur_duan.direction == direction):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段必须有5笔
|
||||||
|
if len(big_kline.cur_duan.bi_list) < 5:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前笔中枢必须在当前线段之内
|
||||||
|
if big_kline.cur_bi_zs.start < big_kline.cur_duan.start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段的高低点,与最高、最低分笔一致(不会出现区间套)
|
||||||
|
if signal_direction == Direction.LONG:
|
||||||
|
# 下跌线段与下跌笔为最低点
|
||||||
|
if not duan_bi_is_end(big_kline.cur_duan, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
# 下跌线段具有底分
|
||||||
|
if not check_duan_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
# 下跌笔具有底分
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# 上涨线段与上涨笔为最高点
|
||||||
|
if not duan_bi_is_end(big_kline.cur_duan, Direction.LONG):
|
||||||
|
return False
|
||||||
|
# 上涨线段具有顶分
|
||||||
|
if not check_duan_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 上涨笔具有顶分
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 中枢的离开笔,有三笔
|
||||||
|
exit_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end > big_kline.cur_bi_zs.end]
|
||||||
|
if len(exit_bi_list) != 3:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 离开中枢首笔的高度,要高于末笔笔,或者,斜率要大于末笔
|
||||||
|
if exit_bi_list[0].height > exit_bi_list[-1].height and exit_bi_list[0].atan > exit_bi_list[-1].atan:
|
||||||
|
|
||||||
|
# 分析次级别K线,判断其是否也发生线段背驰
|
||||||
|
if small_kline:
|
||||||
|
if len(small_kline.cur_duan.bi_list) > 1:
|
||||||
|
if (small_kline.cur_duan.bi_list[0].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[0].atan > small_kline.cur_duan.bi_list[-1].atan) \
|
||||||
|
or (small_kline.cur_duan.bi_list[-3].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[-3].atan > small_kline.cur_duan.bi_list[-1].atan):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_qjt_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||||
|
"""
|
||||||
|
判断区间套一买/区间套1卖信号
|
||||||
|
big_kline当前线段与信号方向相反,线段具有盘整一个中枢,
|
||||||
|
[一买信号为例]
|
||||||
|
中枢前下跌一笔a,中枢后,存在两个下跌笔b、c,
|
||||||
|
b比a力度小,c比b力度小(高度、斜率)
|
||||||
|
:param big_kline: 本级别K线
|
||||||
|
:param small_kline: 次级别K线(可选,可以是None)
|
||||||
|
:param signal_direction: 信号方向
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
direction = 1 if signal_direction == Direction.LONG else -1
|
||||||
|
|
||||||
|
# 排除
|
||||||
|
# 没有前线段、没有笔中枢
|
||||||
|
# 当前线段方向与判断方向一致、
|
||||||
|
if not big_kline.pre_duan \
|
||||||
|
or not big_kline.cur_bi_zs \
|
||||||
|
or big_kline.cur_duan.direction == direction:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 如果有次级别K线时,也要判断方向
|
||||||
|
if small_kline and (not small_kline.pre_duan or small_kline.cur_duan.direction == direction):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前笔中枢必须在当前线段之内
|
||||||
|
if big_kline.cur_bi_zs.start < big_kline.cur_duan.start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段结束需要等于当前笔结束
|
||||||
|
if big_kline.cur_duan.end != big_kline.cur_bi.end:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 寻找做多信号时,要求当前下跌笔底分型成立
|
||||||
|
if signal_direction == Direction.LONG:
|
||||||
|
# 笔走完
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 寻找做空信号时,要求当前上涨笔顶分型成立
|
||||||
|
else:
|
||||||
|
# 笔走完
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 进入中枢前的一笔
|
||||||
|
entry_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end <= big_kline.cur_bi_zs.start]
|
||||||
|
|
||||||
|
# 中枢的离开笔,有三笔
|
||||||
|
exit_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end > big_kline.cur_bi_zs.end]
|
||||||
|
if len(entry_bi_list) < 1 or len(exit_bi_list) != 3:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# c笔的高度,要高于b笔,高于进入笔a, c笔斜率要大于b笔> 进入笔a
|
||||||
|
if exit_bi_list[0].height > exit_bi_list[-1].height > entry_bi_list[-1].height \
|
||||||
|
and exit_bi_list[0].atan > exit_bi_list[-1].atan > entry_bi_list[-1].atan:
|
||||||
|
|
||||||
|
# 分析次级别K线,判断其是否也发生线段背驰
|
||||||
|
if small_kline:
|
||||||
|
if len(small_kline.cur_duan.bi_list) > 1:
|
||||||
|
if (small_kline.cur_duan.bi_list[0].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[0].atan > small_kline.cur_duan.bi_list[-1].atan) \
|
||||||
|
or (small_kline.cur_duan.bi_list[-3].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
and small_kline.cur_duan.bi_list[-3].atan > small_kline.cur_duan.bi_list[-1].atan):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_qsbc_2nd(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||||
|
"""
|
||||||
|
判断趋势背驰1买/1卖后的二买、二卖信号
|
||||||
|
big_kline当前线段为趋势,与信号方向相反,线段具有2个中枢,
|
||||||
|
或者 big_kline的 tre_duan,pre_duan,cur_duan 为趋势,之间具有两个以上连续方向的中枢
|
||||||
|
cur_duan的末端一笔,形成趋势背驰,或者末端一笔超长时,其次级别形成具有背驰信号
|
||||||
|
big_kline当前段外具有两笔,最后一笔具有确认分型,斜率比cur_duan末笔的斜率小
|
||||||
|
:param big_kline: 本级别K线
|
||||||
|
:param small_kline: 次级别K线(可选,可以是None)
|
||||||
|
:param signal_direction: 信号方向
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
direction = 1 if signal_direction == Direction.LONG else -1
|
||||||
|
# 排除
|
||||||
|
# 没有前线段、没有笔中枢
|
||||||
|
# 当前线段方向与判断方向一致
|
||||||
|
if not big_kline.pre_duan \
|
||||||
|
or not big_kline.cur_bi_zs \
|
||||||
|
or big_kline.cur_duan.direction == direction:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 二买信号时,当前笔必须时下跌笔+底分型
|
||||||
|
if signal_direction == Direction.LONG:
|
||||||
|
# 若不是下跌笔,并且下跌笔没有底分型
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return False
|
||||||
|
# 二卖信号时,当前笔必须是上涨笔+顶分型
|
||||||
|
else:
|
||||||
|
# 若不是上涨笔,并且上涨笔没有顶分型
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.LONG):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段内,至少有2个或以上中枢
|
||||||
|
has_2_continue_zs = False
|
||||||
|
bi_zs_in_cur_duan = [zs for zs in big_kline.bi_zs_list[-4:] if zs.start > big_kline.cur_duan.start]
|
||||||
|
if len(bi_zs_in_cur_duan) >= 2:
|
||||||
|
# 两个连续下跌的中枢,可以进一步判断是否满足二买做多
|
||||||
|
if signal_direction == Direction.LONG and bi_zs_in_cur_duan[-2].low > bi_zs_in_cur_duan[-1].low:
|
||||||
|
has_2_continue_zs = True
|
||||||
|
# 两个连续上升的中枢,可以进一步判断是否满足二卖做空
|
||||||
|
if signal_direction == Direction.SHORT and bi_zs_in_cur_duan[-2].high < bi_zs_in_cur_duan[-1].high:
|
||||||
|
has_2_continue_zs = True
|
||||||
|
|
||||||
|
# 当前线段内,不足两个中枢,判断前三个线段内,是否具有两个或两个以上中枢
|
||||||
|
elif big_kline.tre_duan:
|
||||||
|
# 找出三个线段内的所有中枢
|
||||||
|
bi_zs_after_tre_duan = [zs for zs in big_kline.bi_zs_list[-4:] if zs.start > big_kline.tre_duan.start]
|
||||||
|
if len(bi_zs_after_tre_duan) >= 2:
|
||||||
|
if signal_direction == Direction.LONG \
|
||||||
|
and big_kline.tre_duan.high > big_kline.cur_duan.high \
|
||||||
|
and bi_zs_after_tre_duan[-2].low > bi_zs_after_tre_duan[-1].low:
|
||||||
|
has_2_continue_zs = True
|
||||||
|
if signal_direction == Direction.SHORT \
|
||||||
|
and big_kline.tre_duan.low < big_kline.cur_duan.low \
|
||||||
|
and bi_zs_after_tre_duan[-2].high < bi_zs_after_tre_duan[-1].high:
|
||||||
|
has_2_continue_zs = True
|
||||||
|
|
||||||
|
# 找不出两个连续同向的中枢,就不能进一步判断是否存在二买二卖
|
||||||
|
if not has_2_continue_zs:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段外的两笔
|
||||||
|
extra_bi_list = [bi for bi in big_kline.bi_list[-3:] if bi.start >= big_kline.cur_duan.end]
|
||||||
|
if len(extra_bi_list) != 2:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 线段外一笔的高度,不能超过线段最后一笔高度
|
||||||
|
if extra_bi_list[0].height > big_kline.cur_duan.bi_list[-1].height:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 最后一笔的高度,不能超过最后一段的高度的黄金分割38%
|
||||||
|
if extra_bi_list[-1].height > big_kline.cur_duan.height * 0.38:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 二买情况下
|
||||||
|
if direction == Direction.LONG:
|
||||||
|
# 当前线段的第二低点
|
||||||
|
if len(big_kline.cur_duan.bi_list) > 1:
|
||||||
|
second_low = min([bi.low for bi in big_kline.cur_duan.bi_list[:-1]])
|
||||||
|
else:
|
||||||
|
second_low = min([bi.low for bi in big_kline.bi_list[-5:-1]])
|
||||||
|
|
||||||
|
# 反抽上涨分笔,高度不能打破第二低点
|
||||||
|
if extra_bi_list[0].high > second_low:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# 当前线段的第二高点
|
||||||
|
if len(big_kline.cur_duan.bi_list) > 1:
|
||||||
|
second_high = max([bi.high for bi in big_kline.cur_duan.bi_list[:-1]])
|
||||||
|
else:
|
||||||
|
second_high = max([bi.high for bi in big_kline.bi_list[-5:-1]])
|
||||||
|
# 反抽下跌分笔,低点不能打破第二高点
|
||||||
|
if extra_bi_list[0].low < second_high:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_zs_3rd(big_kline: CtaLineBar,
|
||||||
|
small_kline: Union[CtaLineBar, None],
|
||||||
|
signal_direction: Direction,
|
||||||
|
first_zs: bool = True,
|
||||||
|
all_zs: bool = True):
|
||||||
|
"""
|
||||||
|
三买三卖信号
|
||||||
|
:param big_kline: 本级别K线
|
||||||
|
:param small_kline: 次级别K线
|
||||||
|
:param signal_direction: 信号方向。Direction.LONG: 三买信号, Direction.SHORT, 三卖信号
|
||||||
|
:param first_zs: 线段内得首个三买三卖(即第一个中枢后才有效)
|
||||||
|
:param all_zs: True 中枢的开始,在线段开始点之后, False: 中枢结束在线段的开始点之后
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
# Diection => 1/-1
|
||||||
|
direction = 1 if signal_direction == Direction.LONG else -1
|
||||||
|
|
||||||
|
if not big_kline.pre_duan or not big_kline.cur_bi_zs:
|
||||||
|
return
|
||||||
|
|
||||||
|
# 排除,须满足:当前段的方向 == 信号方向, 当前笔的方向 != 信号方向
|
||||||
|
if big_kline.cur_duan.direction != direction or big_kline.cur_bi.direction == direction:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前线段结束,与当前回调笔位置一致
|
||||||
|
if big_kline.cur_duan.end != big_kline.cur_bi.start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
zs_num = 0
|
||||||
|
|
||||||
|
# 中枢与当前线段交集的判断
|
||||||
|
if all_zs:
|
||||||
|
|
||||||
|
# 信号线段,必须至少含有5个分笔(如果含有1个分笔的,可能是强二买信号)
|
||||||
|
if len(big_kline.cur_duan.bi_list) < 3:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前中枢需要完全在当前线段内
|
||||||
|
if big_kline.cur_bi_zs.start < big_kline.cur_duan.start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前段之后的所有包含中枢
|
||||||
|
zs_list = [zs for zs in big_kline.bi_zs_list[-3:] if zs.start >= big_kline.cur_duan.start]
|
||||||
|
zs_num = len(zs_list)
|
||||||
|
# 是否现在线段得首个中枢后的三买三卖
|
||||||
|
if first_zs and zs_num> 1:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# 中枢需要与当前线段有交集[部分交集、或中枢完全在当前段内形成]
|
||||||
|
if big_kline.cur_bi_zs.end < big_kline.cur_duan.start:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 当前段之后的所有交集中枢
|
||||||
|
zs_list = [zs for zs in big_kline.bi_zs_list[-3:] if zs.end > big_kline.cur_duan.start]
|
||||||
|
zs_num = len(zs_list)
|
||||||
|
# 是否现在线段得首个中枢后的三买三卖
|
||||||
|
if first_zs and zs_num > 1:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not first_zs and zs_num > 1:
|
||||||
|
# 中枢的进入笔、离开笔
|
||||||
|
# 中枢的首笔与线段不同向,则选择中枢之前的一笔和最后的一笔
|
||||||
|
if big_kline.cur_bi_zs.bi_list[0].direction != big_kline.cur_duan.direction:
|
||||||
|
entry_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end <= big_kline.cur_bi_zs.start]
|
||||||
|
exit_bi_list = [bi for bi in big_kline.cur_duan.bi_list if bi.end > big_kline.cur_bi_zs.end]
|
||||||
|
if not (len(entry_bi_list) >= 1 and len(exit_bi_list) == 1):
|
||||||
|
return False
|
||||||
|
entry_bi = entry_bi_list[-1]
|
||||||
|
exit_bi = exit_bi_list[0]
|
||||||
|
|
||||||
|
# 中枢首笔跟线段同向
|
||||||
|
else:
|
||||||
|
entry_bi = big_kline.cur_bi_zs.bi_list[0]
|
||||||
|
exit_bi = big_kline.cur_duan.bi_list[-1]
|
||||||
|
#
|
||||||
|
# # 防止属于中枢盘整
|
||||||
|
if entry_bi.height > exit_bi.height and entry_bi.atan > exit_bi.atan:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 判断三买信号
|
||||||
|
if signal_direction == Direction.LONG:
|
||||||
|
|
||||||
|
# 本级别最后一笔,具有底分型
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.SHORT):
|
||||||
|
return
|
||||||
|
|
||||||
|
# 线段最后一笔,与中枢有交集,且笔的中心,不在中枢内
|
||||||
|
if big_kline.cur_duan.bi_list[-1].low > big_kline.cur_bi_zs.high \
|
||||||
|
or big_kline.cur_duan.bi_list[-1].middle <= big_kline.cur_bi_zs.high:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# # 线段的最后一笔,长度不能超过平均长度的两倍
|
||||||
|
# if big_kline.cur_duan.bi_list[-1].height > big_kline.bi_height_ma() * 2:
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# 下跌笔不落中枢,一般使用笔的底部必须在中枢上方。为了防止毛刺,这里用了分型的高位在中枢上方即可
|
||||||
|
if big_kline.cur_fenxing.high <= big_kline.cur_bi_zs.high:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 判断三卖信号
|
||||||
|
if signal_direction == Direction.SHORT:
|
||||||
|
|
||||||
|
# 本级别最后一笔,具有顶分型
|
||||||
|
if not check_bi_not_rt(big_kline, Direction.LONG):
|
||||||
|
return
|
||||||
|
|
||||||
|
# 线段最后一笔,与中枢有交集,且笔的中心,不在中枢内
|
||||||
|
if big_kline.cur_duan.bi_list[-1].high < big_kline.cur_bi_zs.low \
|
||||||
|
or big_kline.cur_duan.bi_list[-1].middle >= big_kline.cur_bi_zs.low:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# # 线段的最后一笔,长度不能超过平均长度的两倍
|
||||||
|
# if big_kline.cur_duan.bi_list[-1].height > big_kline.bi_height_ma() * 2:
|
||||||
|
# return False
|
||||||
|
|
||||||
|
# 上涨分笔不回中枢,一般使用笔的顶部必须在中枢下方。为了防止毛刺,这里用了分型的低位在中枢下方即可
|
||||||
|
if big_kline.cur_fenxing.low >= big_kline.cur_bi_zs.low:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 分析次级别K线,判断其是否也发生线段背驰
|
||||||
|
if small_kline:
|
||||||
|
if len(small_kline.cur_duan.bi_list) > 1:
|
||||||
|
if small_kline.cur_duan.bi_list[0].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
or small_kline.cur_duan.bi_list[0].atan > small_kline.cur_duan.bi_list[-1].atan \
|
||||||
|
or small_kline.cur_duan.bi_list[-3].height > small_kline.cur_duan.bi_list[-1].height \
|
||||||
|
or small_kline.cur_duan.bi_list[-3].atan > small_kline.cur_duan.bi_list[-1].atan:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
@ -564,37 +564,37 @@ class CtpGateway(BaseGateway):
|
|||||||
def close(self):
|
def close(self):
|
||||||
""""""
|
""""""
|
||||||
if self.md_api:
|
if self.md_api:
|
||||||
self.write_log('断开行情API')
|
self.write_log('断开行情API',on_log=True)
|
||||||
tmp1 = self.md_api
|
tmp1 = self.md_api
|
||||||
self.md_api = None
|
self.md_api = None
|
||||||
tmp1.close()
|
tmp1.close()
|
||||||
|
|
||||||
if self.l2_md_api:
|
if self.l2_md_api:
|
||||||
self.write_log('断开五档行情API')
|
self.write_log('断开五档行情API',on_log=True)
|
||||||
tmp1 = self.l2_md_api
|
tmp1 = self.l2_md_api
|
||||||
self.l2_md_api = None
|
self.l2_md_api = None
|
||||||
tmp1.close()
|
tmp1.close()
|
||||||
|
|
||||||
if self.td_api:
|
if self.td_api:
|
||||||
self.write_log('断开交易API')
|
self.write_log('断开交易API',on_log=True)
|
||||||
tmp2 = self.td_api
|
tmp2 = self.td_api
|
||||||
self.td_api = None
|
self.td_api = None
|
||||||
tmp2.close()
|
tmp2.close()
|
||||||
|
|
||||||
if self.tdx_api:
|
if self.tdx_api:
|
||||||
self.write_log(u'断开tdx指数行情API')
|
self.write_log(u'断开tdx指数行情API',on_log=True)
|
||||||
tmp3 = self.tdx_api
|
tmp3 = self.tdx_api
|
||||||
self.tdx_api = None
|
self.tdx_api = None
|
||||||
tmp3.close()
|
tmp3.close()
|
||||||
|
|
||||||
if self.rabbit_api:
|
if self.rabbit_api:
|
||||||
self.write_log(u'断开rabbit MQ tdx指数行情API')
|
self.write_log(u'断开rabbit MQ tdx指数行情API',on_log=True)
|
||||||
tmp4 = self.rabbit_api
|
tmp4 = self.rabbit_api
|
||||||
self.rabbit_api = None
|
self.rabbit_api = None
|
||||||
tmp4.close()
|
tmp4.close()
|
||||||
|
|
||||||
if self.tq_api:
|
if self.tq_api:
|
||||||
self.write_log(u'天勤行情API')
|
self.write_log(u'断开天勤行情API',on_log=True)
|
||||||
tmp5 = self.tq_api
|
tmp5 = self.tq_api
|
||||||
self.tq_api = None
|
self.tq_api = None
|
||||||
tmp5.close()
|
tmp5.close()
|
||||||
@ -659,7 +659,7 @@ class CtpMdApi(MdApi):
|
|||||||
"""
|
"""
|
||||||
Callback when front server is connected.
|
Callback when front server is connected.
|
||||||
"""
|
"""
|
||||||
self.gateway.write_log(f"{self.name}行情服务器连接成功")
|
self.gateway.write_log(f"{self.name}行情服务器连接成功",on_log=True)
|
||||||
self.connect_status = True
|
self.connect_status = True
|
||||||
self.login()
|
self.login()
|
||||||
self.gateway.status.update(
|
self.gateway.status.update(
|
||||||
@ -671,7 +671,7 @@ class CtpMdApi(MdApi):
|
|||||||
"""
|
"""
|
||||||
self.login_status = False
|
self.login_status = False
|
||||||
self.connect_status = False
|
self.connect_status = False
|
||||||
self.gateway.write_log(f"{self.name}行情服务器连接断开,原因{reason}")
|
self.gateway.write_log(f"{self.name}行情服务器连接断开,原因{reason}",on_log=True)
|
||||||
self.gateway.status.update(
|
self.gateway.status.update(
|
||||||
{f'{self.name}md_con': False, f'{self.name}md_dis_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
{f'{self.name}md_con': False, f'{self.name}md_dis_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
@ -681,7 +681,7 @@ class CtpMdApi(MdApi):
|
|||||||
"""
|
"""
|
||||||
if not error["ErrorID"]:
|
if not error["ErrorID"]:
|
||||||
self.login_status = True
|
self.login_status = True
|
||||||
self.gateway.write_log(f"{self.name}行情服务器登录成功")
|
self.gateway.write_log(f"{self.name}行情服务器登录成功",on_log=True)
|
||||||
|
|
||||||
for symbol in self.subscribed:
|
for symbol in self.subscribed:
|
||||||
self.subscribeMarketData(symbol)
|
self.subscribeMarketData(symbol)
|
||||||
@ -877,7 +877,7 @@ class CtpTdApi(TdApi):
|
|||||||
|
|
||||||
def onFrontConnected(self):
|
def onFrontConnected(self):
|
||||||
""""""
|
""""""
|
||||||
self.gateway.write_log("交易服务器连接成功")
|
self.gateway.write_log("交易服务器连接成功",on_log=True)
|
||||||
self.connect_status = True
|
self.connect_status = True
|
||||||
if self.auth_code:
|
if self.auth_code:
|
||||||
self.gateway.write_log("向交易服务器提交授权码验证")
|
self.gateway.write_log("向交易服务器提交授权码验证")
|
||||||
@ -889,7 +889,7 @@ class CtpTdApi(TdApi):
|
|||||||
def onFrontDisconnected(self, reason: int):
|
def onFrontDisconnected(self, reason: int):
|
||||||
""""""
|
""""""
|
||||||
self.login_status = False
|
self.login_status = False
|
||||||
self.gateway.write_log(f"交易服务器连接断开,原因{reason}")
|
self.gateway.write_log(f"交易服务器连接断开,原因{reason}",on_log=True)
|
||||||
self.gateway.status.update({'td_con': False, 'td_dis_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
self.gateway.status.update({'td_con': False, 'td_dis_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
|
|
||||||
def onRspAuthenticate(self, data: dict, error: dict, reqid: int, last: bool):
|
def onRspAuthenticate(self, data: dict, error: dict, reqid: int, last: bool):
|
||||||
@ -910,7 +910,7 @@ class CtpTdApi(TdApi):
|
|||||||
self.sessionid = data["SessionID"]
|
self.sessionid = data["SessionID"]
|
||||||
self.login_status = True
|
self.login_status = True
|
||||||
self.gateway.status.update({'td_con': True, 'td_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
self.gateway.status.update({'td_con': True, 'td_con_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')})
|
||||||
self.gateway.write_log("交易帐号登录完成")
|
self.gateway.write_log("交易帐号登录完成",on_log=True)
|
||||||
|
|
||||||
# Confirm settlement
|
# Confirm settlement
|
||||||
req = {
|
req = {
|
||||||
@ -971,7 +971,7 @@ class CtpTdApi(TdApi):
|
|||||||
"""
|
"""
|
||||||
Callback of settlment info confimation.
|
Callback of settlment info confimation.
|
||||||
"""
|
"""
|
||||||
self.gateway.write_log("结算信息确认成功")
|
self.gateway.write_log("结算信息确认成功",on_log=True)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
self.reqid += 1
|
self.reqid += 1
|
||||||
@ -1594,7 +1594,7 @@ class TdxMdApi():
|
|||||||
# 创建api连接对象实例
|
# 创建api连接对象实例
|
||||||
try:
|
try:
|
||||||
if self.api is None or not self.connection_status:
|
if self.api is None or not self.connection_status:
|
||||||
self.gateway.write_log(u'开始连接通达信行情服务器')
|
self.gateway.write_log(u'开始连接通达信行情服务器',on_log=True)
|
||||||
self.api = TdxExHq_API(heartbeat=True, auto_retry=True, raise_exception=True)
|
self.api = TdxExHq_API(heartbeat=True, auto_retry=True, raise_exception=True)
|
||||||
|
|
||||||
# 选取最佳服务器
|
# 选取最佳服务器
|
||||||
@ -1619,12 +1619,12 @@ class TdxMdApi():
|
|||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.gateway.write_log(u'连接服务器tdx异常:{},{}'.format(str(ex), traceback.format_exc()))
|
self.gateway.write_log(u'连接服务器tdx异常:{},{}'.format(str(ex), traceback.format_exc()),on_log=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""退出API"""
|
"""退出API"""
|
||||||
self.gateway.write_log(u'退出tdx API')
|
self.gateway.write_log(u'退出tdx API',on_log=True)
|
||||||
self.connection_status = False
|
self.connection_status = False
|
||||||
|
|
||||||
if self.thread:
|
if self.thread:
|
||||||
@ -2110,7 +2110,7 @@ class TqMdApi():
|
|||||||
from tqsdk import TqApi
|
from tqsdk import TqApi
|
||||||
self.api = TqApi(url="wss://u.shinnytech.com/t/md/front/mobile")
|
self.api = TqApi(url="wss://u.shinnytech.com/t/md/front/mobile")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.gateway.write_log(f'天勤行情API接入异常'.format(str(e)))
|
self.gateway.write_log(f'天勤行情API接入异常'.format(str(e)),on_log=True)
|
||||||
if self.api:
|
if self.api:
|
||||||
self.is_connected = True
|
self.is_connected = True
|
||||||
self.gateway.write_log(f'天勤行情API已连接')
|
self.gateway.write_log(f'天勤行情API已连接')
|
||||||
@ -2216,7 +2216,7 @@ class TqMdApi():
|
|||||||
self.quote_objs.append((req.vt_symbol, quote))
|
self.quote_objs.append((req.vt_symbol, quote))
|
||||||
self.subscribe_array.append(req.vt_symbol)
|
self.subscribe_array.append(req.vt_symbol)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.gateway.write_log('订阅天勤行情异常:{}'.format(str(ex)))
|
self.gateway.write_log('订阅天勤行情异常:{}'.format(str(ex)),on_log=True)
|
||||||
|
|
||||||
def query_contracts(self) -> None:
|
def query_contracts(self) -> None:
|
||||||
""""""
|
""""""
|
||||||
@ -2317,4 +2317,4 @@ class TqMdApi():
|
|||||||
if self.update_thread:
|
if self.update_thread:
|
||||||
self.update_thread.join()
|
self.update_thread.join()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.gateway.write_log('退出天勤行情api异常:{}'.format(str(e)))
|
self.gateway.write_log('退出天勤行情api异常:{}'.format(str(e)),on_log=True)
|
||||||
|
@ -173,6 +173,7 @@ class ThsGateway(BaseGateway):
|
|||||||
|
|
||||||
def connect(self, setting: dict) -> None:
|
def connect(self, setting: dict) -> None:
|
||||||
"""连接"""
|
"""连接"""
|
||||||
|
try:
|
||||||
userid = setting["资金账号"]
|
userid = setting["资金账号"]
|
||||||
password = setting["登录密码"]
|
password = setting["登录密码"]
|
||||||
|
|
||||||
@ -191,6 +192,10 @@ class ThsGateway(BaseGateway):
|
|||||||
# self.tq_api.connect()
|
# self.tq_api.connect()
|
||||||
self.init_query()
|
self.init_query()
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
msg = f'{self.gateway_name}连接行情和交易接口异常:{str(ex)}'
|
||||||
|
self.write_error(msg)
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
""""""
|
""""""
|
||||||
self.md_api.close()
|
self.md_api.close()
|
||||||
@ -248,6 +253,8 @@ class ThsGateway(BaseGateway):
|
|||||||
self.count = 0
|
self.count = 0
|
||||||
self.query_functions = [self.query_orders, self.query_trades, self.query_account, self.query_position]
|
self.query_functions = [self.query_orders, self.query_trades, self.query_account, self.query_position]
|
||||||
|
|
||||||
|
def check_status(self):
|
||||||
|
self.write_log(self.status)
|
||||||
|
|
||||||
class TdxMdApi(object):
|
class TdxMdApi(object):
|
||||||
"""通达信行情和基础数据"""
|
"""通达信行情和基础数据"""
|
||||||
@ -403,7 +410,7 @@ class TdxMdApi(object):
|
|||||||
self.pool.map_async(self.run, range(n))
|
self.pool.map_async(self.run, range(n))
|
||||||
|
|
||||||
# 设置上层的连接状态
|
# 设置上层的连接状态
|
||||||
self.gateway.tdxConnected = True
|
self.gateway.tdx_connected = True
|
||||||
|
|
||||||
def reconnect(self, i):
|
def reconnect(self, i):
|
||||||
"""
|
"""
|
||||||
@ -884,7 +891,8 @@ class ThsTdApi(object):
|
|||||||
self.password = user_pwd
|
self.password = user_pwd
|
||||||
self.rpc_host = host
|
self.rpc_host = host
|
||||||
self.rpc_port = port
|
self.rpc_port = port
|
||||||
|
self.gateway.write_log(f'{self.gateway_name}开始连接{host}:{port}')
|
||||||
|
try:
|
||||||
# 创建 easy客户端
|
# 创建 easy客户端
|
||||||
self.api = easytrader_use(broker='pingan_ths', host=self.rpc_host, port=self.rpc_port)
|
self.api = easytrader_use(broker='pingan_ths', host=self.rpc_host, port=self.rpc_port)
|
||||||
|
|
||||||
@ -893,6 +901,12 @@ class ThsTdApi(object):
|
|||||||
|
|
||||||
self.login_status = True
|
self.login_status = True
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
msg = f'{self.gateway_name}连接{host}:{port}异常:{str(ex)}'
|
||||||
|
self.gateway.write_error(msg)
|
||||||
|
from vnpy.trader.util_wechat import send_wx_msg
|
||||||
|
send_wx_msg(msg)
|
||||||
|
|
||||||
def reconnect(self):
|
def reconnect(self):
|
||||||
"""连接"""
|
"""连接"""
|
||||||
self.gateway.write_log(f'重新连接')
|
self.gateway.write_log(f'重新连接')
|
||||||
|
Loading…
Reference in New Issue
Block a user