[update] 基础组件更新
This commit is contained in:
parent
344f877bda
commit
98ab549e0d
@ -3,6 +3,7 @@
|
||||
下载通达信股票合约1分钟&日线bar => vnpy项目目录/bar_data/
|
||||
上海股票 => SSE子目录
|
||||
深圳股票 => SZSE子目录
|
||||
修改为多进程模式
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
@ -10,6 +11,10 @@ import csv
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
import pandas as pd
|
||||
from multiprocessing import Pool
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from copy import copy
|
||||
|
||||
vnpy_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
if vnpy_root not in sys.path:
|
||||
@ -35,15 +40,21 @@ api_01 = TdxStockData()
|
||||
# 额外需要数据下载的基金列表
|
||||
stock_list = load_json('stock_list.json')
|
||||
|
||||
# 强制更新缓存
|
||||
api_01.cache_config()
|
||||
symbol_dict = api_01.symbol_dict
|
||||
#
|
||||
# thread_executor = ThreadPoolExecutor(max_workers=1)
|
||||
# thread_tasks = []
|
||||
|
||||
# 下载所有的股票数据
|
||||
num_stocks = 0
|
||||
for period in ['1min', '1day']:
|
||||
for symbol in symbol_dict.keys():
|
||||
symbol_info = symbol_dict[symbol]
|
||||
|
||||
def refill(symbol_info):
|
||||
period = symbol_info['period']
|
||||
progress = symbol_info['progress']
|
||||
# print("{}_{}".format(period, symbol_info['code']))
|
||||
# return
|
||||
stock_code = symbol_info['code']
|
||||
if ('stock_type' in symbol_info.keys() and symbol_info['stock_type'] in ['stock_cn', 'cb_cn']) or stock_code in stock_list:
|
||||
|
||||
# if stock_code in stock_list:
|
||||
# print(symbol_info['code'])
|
||||
if symbol_info['exchange'] == 'SZSE':
|
||||
@ -52,9 +63,8 @@ for period in ['1min', '1day']:
|
||||
else:
|
||||
exchange_name = '上交所'
|
||||
exchange = Exchange.SSE
|
||||
else:
|
||||
continue
|
||||
num_stocks += 1
|
||||
|
||||
# num_stocks += 1
|
||||
|
||||
stock_name = symbol_info.get('name')
|
||||
print(f'开始更新:{exchange_name}/{stock_name}, 代码:{stock_code}')
|
||||
@ -62,7 +72,8 @@ for period in ['1min', '1day']:
|
||||
if not os.path.exists(bar_file_folder):
|
||||
os.makedirs(bar_file_folder)
|
||||
# csv数据文件名
|
||||
bar_file_path = os.path.abspath(os.path.join(bar_file_folder, f'{stock_code}_{period[0:2]}.csv'))
|
||||
p_name = period.replace('min', 'm').replace('day', 'd').replace('hour', 'h')
|
||||
bar_file_path = os.path.abspath(os.path.join(bar_file_folder, f'{stock_code}_{p_name}.csv'))
|
||||
|
||||
# 如果文件存在,
|
||||
if os.path.exists(bar_file_path):
|
||||
@ -73,11 +84,12 @@ for period in ['1min', '1day']:
|
||||
|
||||
if last_dt:
|
||||
start_dt = last_dt - timedelta(days=1)
|
||||
print(f'文件{bar_file_path}存在,最后时间:{start_date}')
|
||||
print(f'文件{bar_file_path}存在,最后时间:{start_dt}')
|
||||
else:
|
||||
start_dt = datetime.strptime(start_date, '%Y%m%d')
|
||||
print(f'文件{bar_file_path}不存在,或读取最后记录错误,开始时间:{start_date}')
|
||||
|
||||
d1 = datetime.now()
|
||||
result, bars = api_01.get_bars(symbol=stock_code,
|
||||
period=period,
|
||||
callback=None,
|
||||
@ -85,8 +97,9 @@ for period in ['1min', '1day']:
|
||||
return_bar=False)
|
||||
# [dict] => dataframe
|
||||
if not result or len(bars) == 0:
|
||||
continue
|
||||
return
|
||||
|
||||
need_resample = False
|
||||
# 全新数据
|
||||
if last_dt is None:
|
||||
data_df = pd.DataFrame(bars)
|
||||
@ -95,7 +108,10 @@ for period in ['1min', '1day']:
|
||||
# print(data_df.head())
|
||||
print(data_df.tail())
|
||||
data_df.to_csv(bar_file_path, index=True)
|
||||
print(f'首次更新{stock_code} {stock_name}数据 => 文件{bar_file_path}')
|
||||
d2 = datetime.now()
|
||||
microseconds = (d1 - d1).microseconds
|
||||
print(f'{progress}% 首次更新{stock_code} {stock_name}数据 {microseconds} 毫秒=> 文件{bar_file_path}')
|
||||
need_resample = True
|
||||
|
||||
# 增量更新
|
||||
else:
|
||||
@ -119,13 +135,68 @@ for period in ['1min', '1day']:
|
||||
continue
|
||||
bar_count += 1
|
||||
writer.writerow(bar)
|
||||
if not need_resample:
|
||||
need_resample = True
|
||||
d2 = datetime.now()
|
||||
microseconds = round((d2 - d1).microseconds / 100, 0)
|
||||
print(f'{progress}%,更新{stock_code} {stock_name} 数据 {microseconds}毫秒 => 文件{bar_file_path}, 最后记录:{bars[-1]}')
|
||||
|
||||
print(f'更新{stock_code} {stock_name} 数据 => 文件{bar_file_path}, 最后记录:{bars[-1]}')
|
||||
# 采用多线程方式输出 5、15、30分钟的数据
|
||||
# if period == '1min' and need_resample:
|
||||
# task = thread_executor.submit(resample, stock_code, exchange, [5, 15, 30])
|
||||
# thread_tasks.append(task)
|
||||
|
||||
# 输出 5、15、30分钟的数据
|
||||
if period == '1min':
|
||||
out_files, err_msg = resample_bars_file(vnpy_root=vnpy_root, symbol=stock_code, exchange=exchange, x_mins=[5,15,30])
|
||||
|
||||
msg = 'tdx股票数据补充完毕: num_stocks={}'.format(num_stocks)
|
||||
send_wx_msg(content=msg)
|
||||
os._exit(0)
|
||||
def resample(symbol, exchange, x_mins=[5, 15, 30]):
|
||||
"""
|
||||
更新多周期文件
|
||||
:param symbol:
|
||||
:param exchange:
|
||||
:param x_mins:
|
||||
:return:
|
||||
"""
|
||||
d1 = datetime.now()
|
||||
out_files, err_msg = resample_bars_file(vnpy_root=vnpy_root,
|
||||
symbol=symbol,
|
||||
exchange=exchange,
|
||||
x_mins=x_mins)
|
||||
d2 = datetime.now()
|
||||
microseconds = round((d2 - d1).microseconds / 100, 0)
|
||||
if len(err_msg) > 0:
|
||||
print(err_msg, file=sys.stderr)
|
||||
|
||||
if out_files:
|
||||
print(f'{microseconds}毫秒,生成 =>{out_files}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# 下载所有的股票数据
|
||||
num_progress = 0
|
||||
total_tasks = len(symbol_dict.keys()) * 2
|
||||
tasks = []
|
||||
for period in ['1min', '5min', '15min', '30min', '1hour', '1day']:
|
||||
for symbol in symbol_dict.keys():
|
||||
info = copy(symbol_dict[symbol])
|
||||
stock_code = info['code']
|
||||
if ('stock_type' in info.keys() and info['stock_type'] in ['stock_cn',
|
||||
'cb_cn']) or stock_code in stock_list:
|
||||
info['period'] = period
|
||||
tasks.append(info)
|
||||
# if len(tasks) > 12:
|
||||
# break
|
||||
|
||||
total_tasks = len(tasks)
|
||||
for task in tasks:
|
||||
num_progress += 1
|
||||
task['progress'] = round(100 * num_progress / total_tasks, 2)
|
||||
|
||||
p = Pool(12)
|
||||
p.map(refill, tasks)
|
||||
p.close()
|
||||
p.join()
|
||||
|
||||
#
|
||||
msg = 'tdx股票数据补充完毕: num_stocks={}'.format(total_tasks)
|
||||
send_wx_msg(content=msg)
|
||||
os._exit(0)
|
||||
|
@ -1921,7 +1921,7 @@ class BackTestingEngine(object):
|
||||
# 返回回测结果
|
||||
d = {}
|
||||
d['init_capital'] = self.init_capital
|
||||
d['profit'] = self.cur_capital - self.init_capital
|
||||
d['profit'] = self.net_capital - self.init_capital
|
||||
d['net_capital'] = self.net_capital
|
||||
d['max_capital'] = self.max_net_capital # 取消原 maxCapital
|
||||
|
||||
@ -2006,8 +2006,8 @@ class BackTestingEngine(object):
|
||||
result_info.update({u'期末资金': d['net_capital']})
|
||||
self.output(u'期末资金:\t%s' % format_number(d['net_capital']))
|
||||
|
||||
result_info.update({u'平仓盈亏': d['profit']})
|
||||
self.output(u'平仓盈亏:\t%s' % format_number(d['profit']))
|
||||
result_info.update({u'总盈亏': d['profit']})
|
||||
self.output(u'总盈亏:\t%s' % format_number(d['profit']))
|
||||
|
||||
result_info.update({u'资金最高净值': d['max_capital']})
|
||||
self.output(u'资金最高净值:\t%s' % format_number(d['max_capital']))
|
||||
|
@ -1316,7 +1316,7 @@ class CtaFutureTemplate(CtaTemplate):
|
||||
|
||||
up_grids_info = ""
|
||||
for grid in list(self.gt.up_grids):
|
||||
if not grid.open_status and grid.order_status:
|
||||
if grid.open_status and grid.order_status:
|
||||
up_grids_info += f'平空中: [已平:{grid.traded_volume} => 目标:{grid.volume}, 委托时间:{grid.order_time}]\n'
|
||||
if len(grid.order_ids) > 0:
|
||||
up_grids_info += f'委托单号:{grid.order_ids}'
|
||||
@ -1333,7 +1333,7 @@ class CtaFutureTemplate(CtaTemplate):
|
||||
|
||||
dn_grids_info = ""
|
||||
for grid in list(self.gt.dn_grids):
|
||||
if not grid.open_status and grid.order_status:
|
||||
if grid.open_status and grid.order_status:
|
||||
dn_grids_info += f'平多中: [已平:{grid.traded_volume} => 目标:{grid.volume}, 委托时间:{grid.order_time}]\n'
|
||||
if len(grid.order_ids) > 0:
|
||||
dn_grids_info += f'委托单号:{grid.order_ids}'
|
||||
|
@ -450,6 +450,13 @@ class PortfolioTestingEngine(BackTestingEngine):
|
||||
'{}_{}.csv'.format(symbol, tick_date.strftime('%Y%m%d'))))
|
||||
|
||||
ticks = []
|
||||
if not os.path.isfile(file_path):
|
||||
self.write_log(u'{}文件不存在'.format(file_path))
|
||||
file_path = os.path.abspath(
|
||||
os.path.join(
|
||||
tick_folder,
|
||||
tick_date.strftime('%Y%m'),
|
||||
'{}_{}.csv'.format(symbol.lower(), tick_date.strftime('%Y%m%d'))))
|
||||
if not os.path.isfile(file_path):
|
||||
self.write_log(u'{}文件不存在'.format(file_path))
|
||||
return None
|
||||
@ -589,8 +596,32 @@ class PortfolioTestingEngine(BackTestingEngine):
|
||||
time=dt.strftime('%H:%M:%S.%f'),
|
||||
trading_day=test_day.strftime('%Y-%m-%d'),
|
||||
last_price=last_price,
|
||||
volume=tick_data['volume']
|
||||
volume=tick_data['volume'],
|
||||
ask_price_1=float(tick_data.get('ask_price_1',0)),
|
||||
ask_volume_1=int(tick_data.get('ask_volume_1',0)),
|
||||
bid_price_1=float(tick_data.get('bid_price_1',0)),
|
||||
bid_volume_1=int(tick_data.get('bid_volume_1',0))
|
||||
)
|
||||
if tick_data.get('ask_price_5',0) > 0:
|
||||
tick.ask_price_2 = float(tick_data.get('ask_price_2',0))
|
||||
tick.ask_volume_2 = int(tick_data.get('ask_volume_2', 0))
|
||||
tick.bid_price_2 = float(tick_data.get('bid_price_2', 0))
|
||||
tick.bid_volume_2 = int(tick_data.get('bid_volume_2', 0))
|
||||
|
||||
tick.ask_price_3 = float(tick_data.get('ask_price_3', 0))
|
||||
tick.ask_volume_3 = int(tick_data.get('ask_volume_3', 0)),
|
||||
tick.bid_price_3 = float(tick_data.get('bid_price_3', 0)),
|
||||
tick.bid_volume_3 = int(tick_data.get('bid_volume_3', 0))
|
||||
|
||||
tick.ask_price_4 = float(tick_data.get('ask_price_4', 0))
|
||||
tick.ask_volume_4 = int(tick_data.get('ask_volume_4', 0)),
|
||||
tick.bid_price_4 = float(tick_data.get('bid_price_4', 0)),
|
||||
tick.bid_volume_4 = int(tick_data.get('bid_volume_4', 0))
|
||||
|
||||
tick.ask_price_5 = float(tick_data.get('ask_price_5', 0))
|
||||
tick.ask_volume_5 = int(tick_data.get('ask_volume_5', 0)),
|
||||
tick.bid_price_5 = float(tick_data.get('bid_price_5', 0)),
|
||||
tick.bid_volume_5 = int(tick_data.get('bid_volume_5', 0))
|
||||
|
||||
self.new_tick(tick)
|
||||
|
||||
|
@ -5,6 +5,9 @@ import sys
|
||||
from abc import ABC
|
||||
from enum import Enum
|
||||
from logging import INFO, ERROR
|
||||
import json
|
||||
import numpy as np
|
||||
import datetime
|
||||
from vnpy.trader.constant import Direction # noqa
|
||||
|
||||
|
||||
@ -71,3 +74,20 @@ class CtaComponent(ABC):
|
||||
self.strategy.write_log(msg=content, level=level)
|
||||
else:
|
||||
print(content, file=sys.stderr)
|
||||
|
||||
|
||||
class MyEncoder(json.JSONEncoder):
|
||||
"""
|
||||
自定义转换器,处理np,datetime等不能被json转换得问题
|
||||
"""
|
||||
def default(self, obj):
|
||||
if isinstance(obj, np.integer):
|
||||
return int(obj)
|
||||
elif isinstance(obj, np.floating):
|
||||
return float(obj)
|
||||
elif isinstance(obj, np.ndarray):
|
||||
return obj.tolist()
|
||||
elif isinstance(obj, datetime):
|
||||
return obj.strftime('%Y-%m-%d %H:%M:%S')
|
||||
else:
|
||||
return super(MyEncoder, self).default(obj)
|
||||
|
@ -10,7 +10,7 @@ import traceback
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from vnpy.trader.utility import get_folder_path
|
||||
from vnpy.component.base import Direction, CtaComponent
|
||||
from vnpy.component.base import Direction, CtaComponent,MyEncoder
|
||||
|
||||
"""
|
||||
网格交易,用于套利单
|
||||
@ -894,7 +894,7 @@ class CtaGridTrade(CtaComponent):
|
||||
data = self.to_json()
|
||||
|
||||
with open(grid_json_file, 'w', encoding='utf8') as f:
|
||||
json_data = json.dumps(data, indent=4, ensure_ascii=False)
|
||||
json_data = json.dumps(data, indent=4, ensure_ascii=False, cls=MyEncoder)
|
||||
f.write(json_data)
|
||||
|
||||
self.write_log(u'GrideTrade保存文件{}完成'.format(grid_json_file))
|
||||
|
@ -28,8 +28,9 @@ from vnpy.component.base import (
|
||||
MARKET_ZJ)
|
||||
from vnpy.component.cta_period import CtaPeriod, Period
|
||||
from vnpy.trader.object import BarData, TickData
|
||||
from vnpy.trader.constant import Interval, Color
|
||||
from vnpy.trader.constant import Interval, Color, ChanSignals
|
||||
from vnpy.trader.utility import round_to, get_trading_date, get_underlying_symbol
|
||||
from vnpy.component.cta_utility import check_chan_xt,check_chan_xt_three_bi, check_qsbc_2nd
|
||||
|
||||
try:
|
||||
from vnpy.component.chanlun import ChanGraph, ChanLibrary
|
||||
@ -206,6 +207,8 @@ class CtaLineBar(object):
|
||||
self.export_bi_filename = None # 通过缠论笔csv文件
|
||||
self.export_zs_filename = None # 通过缠论的笔中枢csv文件
|
||||
self.export_duan_filename = None # 通过缠论的线段csv文件
|
||||
self.export_xt_filename = None # 缠论笔的形态csv文件, 满足 strategy_name_xt_n_signals.csv
|
||||
# n 会转换为 3,5,7,9,11,13
|
||||
|
||||
self.pre_bi_start = None # 前一个笔的时间
|
||||
self.pre_zs_start = None # 前一个中枢的时间
|
||||
@ -295,6 +298,8 @@ class CtaLineBar(object):
|
||||
self.param_list.append('para_ema1_len') # 三条EMA均线
|
||||
self.param_list.append('para_ema2_len')
|
||||
self.param_list.append('para_ema3_len')
|
||||
self.param_list.append('para_ema4_len')
|
||||
self.param_list.append('para_ema5_len')
|
||||
|
||||
self.param_list.append('para_dmi_len')
|
||||
self.param_list.append('para_dmi_max')
|
||||
@ -365,6 +370,7 @@ class CtaLineBar(object):
|
||||
self.param_list.append('para_bd_len')
|
||||
|
||||
self.param_list.append('para_active_chanlun') # 激活缠论
|
||||
self.param_list.append('para_active_chan_xt') # 激活缠论的形态分析
|
||||
|
||||
def init_properties(self):
|
||||
"""
|
||||
@ -417,6 +423,8 @@ class CtaLineBar(object):
|
||||
self.para_ema1_len = 0 # 13 # 第一根EMA均线的周期长度
|
||||
self.para_ema2_len = 0 # 21 # 第二根EMA均线的周期长度
|
||||
self.para_ema3_len = 0 # 120 # 第三根EMA均线的周期长度
|
||||
self.para_ema4_len = 0 # 120 # 第四根EMA均线的周期长度
|
||||
self.para_ema5_len = 0 # 120 # 第五根EMA均线的周期长度
|
||||
|
||||
self.para_dmi_len = 0 # 14 # DMI的计算周期
|
||||
self.para_dmi_max = 0 # 30 # Dpi和Mdi的突破阈值
|
||||
@ -538,10 +546,14 @@ class CtaLineBar(object):
|
||||
self.line_ema1 = [] # K线的EMA1均线,周期是para_ema1_len1,不包含当前bar
|
||||
self.line_ema2 = [] # K线的EMA2均线,周期是para_ema1_len2,不包含当前bar
|
||||
self.line_ema3 = [] # K线的EMA3均线,周期是para_ema1_len3,不包含当前bar
|
||||
self.line_ema4 = [] # K线的EMA4均线,周期是para_ema1_len4,不包含当前bar
|
||||
self.line_ema5 = [] # K线的EMA5均线,周期是para_ema1_len5,不包含当前bar
|
||||
|
||||
self._rt_ema1 = None # K线的实时EMA(para_ema1_len)
|
||||
self._rt_ema2 = None # K线的实时EMA(para_ema2_len)
|
||||
self._rt_ema3 = None # K线的实时EMA(para_ema3_len)
|
||||
self._rt_ema4 = None # K线的实时EMA(para_ema4_len)
|
||||
self._rt_ema5 = None # K线的实时EMA(para_ema5_len)
|
||||
|
||||
# K线的DMI( Pdi,Mdi,ADX,Adxr) 计算数据
|
||||
self.cur_pdi = 0 # bar内的升动向指标,即做多的比率
|
||||
@ -793,6 +805,14 @@ class CtaLineBar(object):
|
||||
self._bi_zs_list = [] # 笔中枢列表
|
||||
self._duan_list = [] # 段列表
|
||||
self._duan_zs_list = [] # 段中枢列表
|
||||
self.para_active_chan_xt = False # 是否激活czsc缠论形态识别
|
||||
self.xt_3_signals = [] # czsc 三笔信号列表 {'bi_start'最后一笔开始,'bi_end'最后一笔结束,'signal'}
|
||||
self.xt_5_signals = [] # czsc 五笔信号列表 {'bi_start'最后一笔开始,'bi_end'最后一笔结束,'signal'}
|
||||
self.xt_7_signals = [] # czsc 七笔信号列表 {'bi_start'最后一笔开始,'bi_end'最后一笔结束,'signal'}
|
||||
self.xt_9_signals = [] # czsc 九笔信号列表 {'bi_start'最后一笔开始,'bi_end'最后一笔结束,'signal'}
|
||||
self.xt_11_signals = [] # czsc 11笔信号列表 {'bi_start'最后一笔开始,'bi_end'最后一笔结束,'signal'}
|
||||
self.xt_13_signals = [] # czsc 13笔信号列表 {'bi_start'最后一笔开始,'bi_end'最后一笔结束,'signal'}
|
||||
self.xt_2nd_signals = [] # 趋势背驰2买或趋势背驰2卖信号
|
||||
|
||||
def set_params(self, setting: dict = {}):
|
||||
"""设置参数"""
|
||||
@ -828,7 +848,7 @@ class CtaLineBar(object):
|
||||
return
|
||||
|
||||
self.cur_datetime = tick.datetime
|
||||
self.cur_tick = copy.copy(tick)
|
||||
self.cur_tick = tick #copy.copy(tick)
|
||||
|
||||
# 兼容 标准套利合约,它没有last_price
|
||||
if self.cur_tick.last_price is None or self.cur_tick.last_price == 0:
|
||||
@ -842,7 +862,7 @@ class CtaLineBar(object):
|
||||
self.cur_price = self.cur_tick.last_price
|
||||
|
||||
# 3.生成x K线,若形成新Bar,则触发OnBar事件
|
||||
self.generate_bar(copy.copy(self.cur_tick))
|
||||
self.generate_bar(self.cur_tick) # copy.copy(self.cur_tick)
|
||||
|
||||
# 更新curPeriod的High,low
|
||||
if self.cur_period is not None:
|
||||
@ -864,8 +884,8 @@ class CtaLineBar(object):
|
||||
self.cur_datetime = bar.datetime + timedelta(minutes=bar_freq)
|
||||
|
||||
if self.bar_len == 0:
|
||||
new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(new_bar)
|
||||
#new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(bar)
|
||||
self.cur_trading_day = bar.trading_day
|
||||
self.on_bar(bar)
|
||||
return
|
||||
@ -910,8 +930,8 @@ class CtaLineBar(object):
|
||||
|
||||
if is_new_bar:
|
||||
# 添加新的bar
|
||||
new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(new_bar)
|
||||
#new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(bar) # new_bar
|
||||
# 将上一个Bar推送至OnBar事件
|
||||
self.on_bar(lastBar)
|
||||
|
||||
@ -1008,6 +1028,9 @@ class CtaLineBar(object):
|
||||
# 输出缠论=》csv文件
|
||||
self.export_chan()
|
||||
|
||||
# 识别缠论分笔形态
|
||||
self.update_chan_xt()
|
||||
|
||||
# 回调上层调用者,将合成的 x分钟bar,回调给策略 def on_bar_x(self, bar: BarData):函数
|
||||
if self.cb_on_bar:
|
||||
self.cb_on_bar(bar=bar)
|
||||
@ -1121,6 +1144,12 @@ class CtaLineBar(object):
|
||||
if self.para_ema3_len > 0 and len(self.line_ema3) > 0:
|
||||
msg = msg + u',EMA({0}):{1}'.format(self.para_ema3_len, self.line_ema3[-1])
|
||||
|
||||
if self.para_ema4_len > 0 and len(self.line_ema4) > 0:
|
||||
msg = msg + u',EMA({0}):{1}'.format(self.para_ema4_len, self.line_ema4[-1])
|
||||
|
||||
if self.para_ema5_len > 0 and len(self.line_ema5) > 0:
|
||||
msg = msg + u',EMA({0}):{1}'.format(self.para_ema5_len, self.line_ema5[-1])
|
||||
|
||||
if self.para_dmi_len > 0 and len(self.line_pdi) > 0:
|
||||
msg = msg + u',Pdi:{1};Mdi:{1};Adx:{2}'.format(self.line_pdi[-1], self.line_mdi[-1], self.line_adx[-1])
|
||||
|
||||
@ -2506,13 +2535,16 @@ class CtaLineBar(object):
|
||||
def __count_ema(self):
|
||||
"""计算K线的EMA1 和EMA2"""
|
||||
|
||||
if not (self.para_ema1_len > 0 or self.para_ema2_len > 0 or self.para_ema3_len > 0): # 不计算
|
||||
if not (self.para_ema1_len > 0 or self.para_ema2_len > 0 or self.para_ema3_len > 0
|
||||
or self.para_ema4_len > 0 or self.para_ema5_len > 0): # 不计算
|
||||
return
|
||||
|
||||
ema1_data_len = min(self.para_ema1_len * 4, self.para_ema1_len + 40) if self.para_ema1_len > 0 else 0
|
||||
ema2_data_len = min(self.para_ema2_len * 4, self.para_ema2_len + 40) if self.para_ema2_len > 0 else 0
|
||||
ema3_data_len = min(self.para_ema3_len * 4, self.para_ema3_len + 40) if self.para_ema3_len > 0 else 0
|
||||
max_data_len = max(ema1_data_len, ema2_data_len, ema3_data_len)
|
||||
ema4_data_len = min(self.para_ema4_len * 4, self.para_ema4_len + 40) if self.para_ema4_len > 0 else 0
|
||||
ema5_data_len = min(self.para_ema5_len * 4, self.para_ema5_len + 40) if self.para_ema5_len > 0 else 0
|
||||
max_data_len = max(ema1_data_len, ema2_data_len, ema3_data_len, ema4_data_len, ema5_data_len)
|
||||
# 1、lineBar满足长度才执行计算
|
||||
if self.bar_len < max_data_len:
|
||||
self.write_log(u'数据未充分,当前Bar数据数量:{0},计算EMA需要:{1}'.
|
||||
@ -2524,7 +2556,7 @@ class CtaLineBar(object):
|
||||
count_len = min(self.para_ema1_len, self.bar_len - 1)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的K线
|
||||
barEma1 = ta.EMA(self.close_array[-ema1_data_len:], count_len)[-1]
|
||||
barEma1 = ta.EMA(self.close_array[-self.para_ema1_len * 4:], count_len)[-1]
|
||||
if np.isnan(barEma1):
|
||||
return
|
||||
barEma1 = round(float(barEma1), self.round_n)
|
||||
@ -2539,7 +2571,7 @@ class CtaLineBar(object):
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
|
||||
barEma2 = ta.EMA(self.close_array[-ema2_data_len:], count_len)[-1]
|
||||
barEma2 = ta.EMA(self.close_array[-self.para_ema2_len * 4:], count_len)[-1]
|
||||
if np.isnan(barEma2):
|
||||
return
|
||||
barEma2 = round(float(barEma2), self.round_n)
|
||||
@ -2553,7 +2585,7 @@ class CtaLineBar(object):
|
||||
count_len = min(self.bar_len - 1, self.para_ema3_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
barEma3 = ta.EMA(self.close_array[-ema3_data_len:], count_len)[-1]
|
||||
barEma3 = ta.EMA(self.close_array[-self.para_ema3_len * 4:], count_len)[-1]
|
||||
if np.isnan(barEma3):
|
||||
return
|
||||
barEma3 = round(float(barEma3), self.round_n)
|
||||
@ -2562,16 +2594,47 @@ class CtaLineBar(object):
|
||||
del self.line_ema3[0]
|
||||
self.line_ema3.append(barEma3)
|
||||
|
||||
# 计算第四条EMA均线
|
||||
if self.para_ema4_len > 0:
|
||||
count_len = min(self.bar_len - 1, self.para_ema4_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
barEma4 = ta.EMA(self.close_array[-self.para_ema4_len * 4:], count_len)[-1]
|
||||
if np.isnan(barEma4):
|
||||
return
|
||||
barEma4 = round(float(barEma4), self.round_n)
|
||||
|
||||
if len(self.line_ema4) > self.max_hold_bars:
|
||||
del self.line_ema4[0]
|
||||
self.line_ema4.append(barEma4)
|
||||
|
||||
# 计算第五条EMA均线
|
||||
if self.para_ema5_len > 0:
|
||||
count_len = min(self.bar_len - 1, self.para_ema5_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
barEma5 = ta.EMA(self.close_array[-self.para_ema5_len * 4:], count_len)[-1]
|
||||
if np.isnan(barEma5):
|
||||
return
|
||||
barEma5 = round(float(barEma5), self.round_n)
|
||||
|
||||
if len(self.line_ema5) > self.max_hold_bars:
|
||||
del self.line_ema5[0]
|
||||
self.line_ema5.append(barEma5)
|
||||
|
||||
def rt_count_ema(self):
|
||||
"""计算K线的EMA1 和EMA2"""
|
||||
|
||||
if not (self.para_ema1_len > 0 or self.para_ema2_len > 0 or self.para_ema3_len > 0): # 不计算
|
||||
if not (self.para_ema1_len > 0 or self.para_ema2_len > 0 or self.para_ema3_len > 0
|
||||
or self.para_ema4_len > 0 or self.para_ema5_len > 0): # 不计算
|
||||
return
|
||||
|
||||
ema1_data_len = min(self.para_ema1_len * 4, self.para_ema1_len + 40) if self.para_ema1_len > 0 else 0
|
||||
ema2_data_len = min(self.para_ema2_len * 4, self.para_ema2_len + 40) if self.para_ema2_len > 0 else 0
|
||||
ema3_data_len = min(self.para_ema3_len * 4, self.para_ema3_len + 40) if self.para_ema3_len > 0 else 0
|
||||
max_data_len = max(ema1_data_len, ema2_data_len, ema3_data_len)
|
||||
ema4_data_len = min(self.para_ema4_len * 4, self.para_ema4_len + 40) if self.para_ema4_len > 0 else 0
|
||||
ema5_data_len = min(self.para_ema5_len * 4, self.para_ema5_len + 40) if self.para_ema5_len > 0 else 0
|
||||
max_data_len = max(ema1_data_len, ema2_data_len, ema3_data_len, ema4_data_len, ema5_data_len)
|
||||
# 1、lineBar满足长度才执行计算
|
||||
if self.bar_len < max_data_len:
|
||||
return
|
||||
@ -2581,7 +2644,7 @@ class CtaLineBar(object):
|
||||
count_len = min(self.para_ema1_len, self.bar_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的K线
|
||||
barEma1 = ta.EMA(np.append(self.close_array[-ema1_data_len:], [self.cur_price]), count_len)[-1]
|
||||
barEma1 = ta.EMA(np.append(self.close_array[-self.para_ema1_len * 4:], [self.cur_price]), count_len)[-1]
|
||||
if np.isnan(barEma1):
|
||||
return
|
||||
self._rt_ema1 = round(float(barEma1), self.round_n)
|
||||
@ -2592,7 +2655,7 @@ class CtaLineBar(object):
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
|
||||
barEma2 = ta.EMA(np.append(self.close_array[-ema2_data_len:], [self.cur_price]), count_len)[-1]
|
||||
barEma2 = ta.EMA(np.append(self.close_array[-self.para_ema2_len * 4:], [self.cur_price]), count_len)[-1]
|
||||
if np.isnan(barEma2):
|
||||
return
|
||||
self._rt_ema2 = round(float(barEma2), self.round_n)
|
||||
@ -2602,11 +2665,31 @@ class CtaLineBar(object):
|
||||
count_len = min(self.bar_len, self.para_ema3_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
barEma3 = ta.EMA(np.append(self.close_array[-ema3_data_len:], [self.cur_price]), count_len)[-1]
|
||||
barEma3 = ta.EMA(np.append(self.close_array[-self.para_ema3_len * 4:], [self.cur_price]), count_len)[-1]
|
||||
if np.isnan(barEma3):
|
||||
return
|
||||
self._rt_ema3 = round(float(barEma3), self.round_n)
|
||||
|
||||
# 计算第四条EMA均线
|
||||
if self.para_ema4_len > 0:
|
||||
count_len = min(self.bar_len, self.para_ema4_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
barEma4 = ta.EMA(np.append(self.close_array[-self.para_ema4_len * 4:], [self.cur_price]), count_len)[-1]
|
||||
if np.isnan(barEma4):
|
||||
return
|
||||
self._rt_ema4 = round(float(barEma4), self.round_n)
|
||||
|
||||
# 计算第五条EMA均线
|
||||
if self.para_ema5_len > 0:
|
||||
count_len = min(self.bar_len, self.para_ema5_len)
|
||||
|
||||
# 3、获取前InputN周期(不包含当前周期)的自适应均线
|
||||
barEma5 = ta.EMA(np.append(self.close_array[-self.para_ema5_len * 4:], [self.cur_price]), count_len)[-1]
|
||||
if np.isnan(barEma5):
|
||||
return
|
||||
self._rt_ema5 = round(float(barEma5), self.round_n)
|
||||
|
||||
@property
|
||||
def rt_ema1(self):
|
||||
self.check_rt_funcs(self.rt_count_ema)
|
||||
@ -2628,6 +2711,20 @@ class CtaLineBar(object):
|
||||
return self.line_ema3[-1]
|
||||
return self._rt_ema3
|
||||
|
||||
@property
|
||||
def rt_ema4(self):
|
||||
self.check_rt_funcs(self.rt_count_ema)
|
||||
if self._rt_ema4 is None and len(self.line_ema4) > 0:
|
||||
return self.line_ema4[-1]
|
||||
return self._rt_ema4
|
||||
|
||||
@property
|
||||
def rt_ema5(self):
|
||||
self.check_rt_funcs(self.rt_count_ema)
|
||||
if self._rt_ema5 is None and len(self.line_ema5) > 0:
|
||||
return self.line_ema5[-1]
|
||||
return self._rt_ema5
|
||||
|
||||
def __count_dmi(self):
|
||||
"""计算K线的DMI数据和条件"""
|
||||
|
||||
@ -5806,7 +5903,7 @@ class CtaLineBar(object):
|
||||
return False
|
||||
|
||||
# 当前段包含的分笔,必须大于3
|
||||
if len(cur_duan.bi_list) < 3:
|
||||
if len(cur_duan.bi_list) <= 3:
|
||||
return False
|
||||
|
||||
# 获取倒数第二根同向分笔的结束dif值或macd值
|
||||
@ -6132,6 +6229,79 @@ class CtaLineBar(object):
|
||||
|
||||
return False
|
||||
|
||||
def update_chan_xt(self):
|
||||
"""更新缠论形态"""
|
||||
if not self.para_active_chan_xt:
|
||||
return
|
||||
bi_len = len(self.bi_list)
|
||||
if bi_len < 3:
|
||||
return
|
||||
|
||||
if self.cur_fenxing.is_rt:
|
||||
return
|
||||
|
||||
bi_n = min(15, bi_len)
|
||||
|
||||
price = self.cur_bi.low if self.cur_bi.direction == -1 else self.cur_bi.high
|
||||
|
||||
for n in range(3, bi_n, 2):
|
||||
# => 信号
|
||||
if n == 3:
|
||||
signal = check_chan_xt_three_bi(self, self.bi_list[-n:])
|
||||
else:
|
||||
signal = check_chan_xt(self, self.bi_list[-n:])
|
||||
# => 信号列表
|
||||
xt_signals = getattr(self, f'xt_{n}_signals')
|
||||
if xt_signals is None:
|
||||
continue
|
||||
# => 上一信号
|
||||
cur_signal = xt_signals[-1] if len(xt_signals) > 0 else None
|
||||
# 不同笔开始时间
|
||||
if cur_signal is None or cur_signal.get("start", "") != self.cur_bi.start:
|
||||
# 新增
|
||||
xt_signals.append({'start': self.cur_bi.start,
|
||||
'end': self.cur_bi.end,
|
||||
'price': price,
|
||||
'signal': signal})
|
||||
if len(xt_signals) > 200:
|
||||
del xt_signals[0]
|
||||
if cur_signal is not None and self.export_xt_filename :
|
||||
self.append_data(
|
||||
file_name=self.export_xt_filename.replace('_n_',f'_{n}_'),
|
||||
dict_data=cur_signal,
|
||||
field_names=["start", "end", "price", "signal"]
|
||||
)
|
||||
# 直接更新
|
||||
else:
|
||||
xt_signals[-1].update({'end': self.cur_bi.end, 'price': price,'signal': signal})
|
||||
|
||||
# 是否趋势二买
|
||||
qsbc_2nd = ChanSignals.Other.value
|
||||
if self.cur_bi.direction == -1:
|
||||
if check_qsbc_2nd(big_kline=self, small_kline=None, signal_direction=Direction.LONG):
|
||||
qsbc_2nd = ChanSignals.Q2L0.value
|
||||
else:
|
||||
if check_qsbc_2nd(big_kline=self, small_kline=None,signal_direction=Direction.SHORT):
|
||||
qsbc_2nd = ChanSignals.Q2S0.value
|
||||
cur_signal = self.xt_2nd_signals[-1] if len(self.xt_2nd_signals) > 0 else None
|
||||
# 不同笔开始时间
|
||||
if cur_signal is None or cur_signal.get("start", "") != self.cur_bi.start:
|
||||
# 新增
|
||||
self.xt_2nd_signals.append({'start': self.cur_bi.start,
|
||||
'end': self.cur_bi.end,
|
||||
'price': price,
|
||||
'signal': qsbc_2nd})
|
||||
if cur_signal and self.export_xt_filename:
|
||||
self.append_data(
|
||||
file_name=self.export_xt_filename.replace('_n_', f'_2nd_'),
|
||||
dict_data=cur_signal,
|
||||
field_names=["start", "end", "price", "signal"]
|
||||
)
|
||||
# 直接更新
|
||||
else:
|
||||
self.xt_2nd_signals[-1].update({'end': self.cur_bi.end, 'price': price, 'signal': qsbc_2nd})
|
||||
|
||||
|
||||
|
||||
def write_log(self, content):
|
||||
"""记录CTA日志"""
|
||||
@ -6338,6 +6508,22 @@ class CtaLineBar(object):
|
||||
'type': 'line'
|
||||
}
|
||||
indicators.update({indicator.get('name'): copy.copy(indicator)})
|
||||
if isinstance(self.para_ema4_len, int) and self.para_ema4_len > 0:
|
||||
indicator = {
|
||||
'name': 'EMA{}'.format(self.para_ema4_len),
|
||||
'attr_name': 'line_ema4',
|
||||
'is_main': True,
|
||||
'type': 'line'
|
||||
}
|
||||
indicators.update({indicator.get('name'): copy.copy(indicator)})
|
||||
if isinstance(self.para_ema5_len, int) and self.para_ema5_len > 0:
|
||||
indicator = {
|
||||
'name': 'EMA{}'.format(self.para_ema5_len),
|
||||
'attr_name': 'line_ema5',
|
||||
'is_main': True,
|
||||
'type': 'line'
|
||||
}
|
||||
indicators.update({indicator.get('name'): copy.copy(indicator)})
|
||||
|
||||
# MA 均线 (主图)
|
||||
if isinstance(self.para_ma1_len, int) and self.para_ma1_len > 0:
|
||||
@ -6820,9 +7006,9 @@ class CtaMinuteBar(CtaLineBar):
|
||||
is_new_bar = True
|
||||
|
||||
if is_new_bar:
|
||||
new_bar = copy.deepcopy(bar)
|
||||
#new_bar = copy.deepcopy(bar)
|
||||
# 添加新的bar
|
||||
self.line_bar.append(new_bar)
|
||||
self.line_bar.append(bar) # new_bar
|
||||
# 将上一个Bar推送至OnBar事件
|
||||
self.on_bar(lastBar)
|
||||
else:
|
||||
@ -7261,8 +7447,8 @@ class CtaDayBar(CtaLineBar):
|
||||
bar_len = len(self.line_bar)
|
||||
|
||||
if bar_len == 0:
|
||||
new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(new_bar)
|
||||
#new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(bar) # new_bar
|
||||
self.cur_trading_day = bar.trading_day if bar.trading_day is not None else get_trading_date(bar.datetime)
|
||||
if bar_is_completed:
|
||||
self.on_bar(bar)
|
||||
@ -7288,8 +7474,8 @@ class CtaDayBar(CtaLineBar):
|
||||
|
||||
if is_new_bar:
|
||||
# 添加新的bar
|
||||
new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(new_bar)
|
||||
#new_bar = copy.deepcopy(bar)
|
||||
self.line_bar.append(bar) # new_bar
|
||||
# 将上一个Bar推送至OnBar事件
|
||||
self.on_bar(lastBar)
|
||||
else:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# 周期类,定义CTA的五种周期,及其周期变换矩阵
|
||||
# 周期状态类,定义CTA的多种周期状态,及其状态变换矩阵
|
||||
from enum import Enum
|
||||
from datetime import datetime
|
||||
|
||||
@ -9,8 +9,12 @@ from datetime import datetime
|
||||
class Period(Enum):
|
||||
INIT = u'初始状态'
|
||||
LONG = u'多'
|
||||
LONG_STOP = u'止涨'
|
||||
SHORT = u'空'
|
||||
SHORT_STOP = u'止跌'
|
||||
SHOCK = u'震荡'
|
||||
SHOCK_LONG = u'震荡偏多'
|
||||
SHOCK_SHORT = u'震荡偏空'
|
||||
LONG_EXTREME = u'极端多'
|
||||
SHORT_EXTREME = u'极端空'
|
||||
|
||||
|
@ -4,7 +4,7 @@ import os
|
||||
import json
|
||||
from datetime import datetime
|
||||
from collections import OrderedDict
|
||||
from vnpy.component.base import CtaComponent
|
||||
from vnpy.component.base import CtaComponent, MyEncoder
|
||||
from vnpy.trader.utility import get_folder_path
|
||||
|
||||
TNS_STATUS_OBSERVATE = 'observate'
|
||||
@ -15,24 +15,6 @@ TNS_STATUS_CLOSED = 'closed'
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
class MyEncoder(json.JSONEncoder):
|
||||
"""
|
||||
自定义转换器,处理np,datetime等不能被json转换得问题
|
||||
"""
|
||||
def default(self, obj):
|
||||
if isinstance(obj, np.integer):
|
||||
return int(obj)
|
||||
elif isinstance(obj, np.floating):
|
||||
return float(obj)
|
||||
elif isinstance(obj, np.ndarray):
|
||||
return obj.tolist()
|
||||
elif isinstance(obj, datetime):
|
||||
return obj.strftime('%Y-%m-%d %H:%M:%S')
|
||||
else:
|
||||
return super(MyEncoder, self).default(obj)
|
||||
|
||||
|
||||
class CtaPolicy(CtaComponent):
|
||||
"""
|
||||
策略的持久化Policy组件
|
||||
|
@ -4,15 +4,16 @@
|
||||
|
||||
from vnpy.trader.constant import ChanSignals, Direction
|
||||
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, Union
|
||||
|
||||
# 所有底背驰信号集合
|
||||
DI_BEICHI_SIGNALS = [ChanSignals.LA0.value, ChanSignals.LA1.value, ChanSignals.LA2.value, ChanSignals.LA3.value,
|
||||
ChanSignals.LB0.value, ChanSignals.LB1.value, ChanSignals.LB2.value, ChanSignals.LB3.value]
|
||||
DI_BEICHI_SIGNALS = [ChanSignals.LA0.value,
|
||||
ChanSignals.LB0.value]
|
||||
|
||||
# 所有顶背驰信号集合
|
||||
DING_BEICHI_SIGNALS = [ChanSignals.SA0.value, ChanSignals.SA1.value, ChanSignals.SA2.value, ChanSignals.SA3.value,
|
||||
ChanSignals.SB0.value, ChanSignals.SB1.value, ChanSignals.SB2.value, ChanSignals.SB3.value]
|
||||
DING_BEICHI_SIGNALS = [ChanSignals.SA0.value,
|
||||
ChanSignals.SB0.value]
|
||||
|
||||
|
||||
def duan_bi_is_end(duan: ChanDuan, direction: Direction) -> bool:
|
||||
@ -37,7 +38,7 @@ def duan_bi_is_end(duan: ChanDuan, direction: Direction) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def check_duan_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
||||
def check_duan_not_rt(kline, direction: Direction) -> bool:
|
||||
"""
|
||||
检查某一个K线当前线段是否非实时
|
||||
:param kline:
|
||||
@ -58,7 +59,7 @@ def check_duan_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def check_bi_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
||||
def check_bi_not_rt(kline, direction: Direction) -> bool:
|
||||
"""
|
||||
检查某一个K线当前分笔是否非实时并符合判断方向
|
||||
:param kline:
|
||||
@ -84,7 +85,7 @@ def check_bi_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
||||
# 判断还没走完的bar,是否满足顶分型
|
||||
if float(kline.cur_fenxing.high) == float(kline.high_array[-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].high_price < float(kline.cur_fenxing.high) \
|
||||
and kline.line_bar[-1].low_price < kline.line_bar[-2].low_price:
|
||||
return True
|
||||
@ -103,7 +104,7 @@ def check_bi_not_rt(kline: CtaLineBar, direction: Direction) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def check_fx_power(kline: CtaLineBar, direction: Direction) -> str:
|
||||
def check_fx_power(kline, direction: Direction) -> str:
|
||||
"""
|
||||
获取分型强弱
|
||||
:param kline: 本级别K线
|
||||
@ -165,7 +166,7 @@ def check_fx_power(kline: CtaLineBar, direction: Direction) -> str:
|
||||
return ret
|
||||
|
||||
|
||||
def check_chan_xt(kline: CtaLineBar, bi_list: List[ChanObject]) -> str:
|
||||
def check_chan_xt(kline, bi_list: List[ChanObject]) -> str:
|
||||
"""
|
||||
获取缠论得形态
|
||||
如果提供得是段内得bi_list,一般可以算出该线段是否有背驰,
|
||||
@ -189,12 +190,12 @@ def check_chan_xt(kline: CtaLineBar, bi_list: List[ChanObject]) -> str:
|
||||
return v
|
||||
|
||||
|
||||
def check_chan_xt_three_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
def check_chan_xt_three_bi(kline, bi_list: List[ChanObject]):
|
||||
"""
|
||||
获取指定3分笔得形态
|
||||
(含有三笔)
|
||||
:param kline:
|
||||
:param bi_list:
|
||||
:param kline: ctaLineBar对象
|
||||
:param bi_list: 笔列表
|
||||
:return:
|
||||
"""
|
||||
v = ChanSignals.Other.value
|
||||
@ -207,62 +208,146 @@ def check_chan_xt_three_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
# 最后一笔是下跌
|
||||
if bi_3.direction == -1:
|
||||
# X3LA0~向下不重合
|
||||
# ^
|
||||
# / \
|
||||
# / \
|
||||
# /
|
||||
# \ /
|
||||
# \ /
|
||||
# v
|
||||
if bi_3.low > bi_1.high:
|
||||
v = ChanSignals.X3LA0.value
|
||||
|
||||
# X3LB0~向下奔走型中枢
|
||||
# X3LB0~向下奔走型
|
||||
# ^
|
||||
# / \
|
||||
# / \
|
||||
# \ / \
|
||||
# \ /
|
||||
# \ /
|
||||
# v
|
||||
if bi_2.low < bi_3.low < bi_1.high < bi_2.high:
|
||||
v = ChanSignals.X3LB0.value
|
||||
|
||||
# X3LC0~向下三角收敛中枢
|
||||
# X3LC0~向下收敛
|
||||
# \
|
||||
# \ ^
|
||||
# \ / \
|
||||
# \ / \
|
||||
# \ /
|
||||
# \ /
|
||||
# v
|
||||
if bi_1.high > bi_3.high and bi_1.low < bi_3.low:
|
||||
v = ChanSignals.X3LC0.value
|
||||
|
||||
# 向下三角扩张中枢
|
||||
# X3LD0~向下扩张
|
||||
# ^
|
||||
# / \
|
||||
# \ / \
|
||||
# \ / \
|
||||
# v \
|
||||
# \
|
||||
if bi_1.high < bi_3.high and bi_1.low > bi_3.low:
|
||||
v = ChanSignals.X3LD0.value
|
||||
|
||||
# X3LE0~向下盘背中枢, X3LF0~向下无背中枢
|
||||
# X3LE0~向下盘背, X3LF0~向下无背
|
||||
if bi_3.low < bi_1.low and bi_3.high < bi_1.high:
|
||||
if bi_3.height < bi_1.height:
|
||||
# X3LE0~向下盘背中枢
|
||||
# X3LE0~向下盘背
|
||||
# \
|
||||
# \
|
||||
# \ ^
|
||||
# \ / \
|
||||
# \ / \
|
||||
# v \
|
||||
# \
|
||||
v = ChanSignals.X3LE0.value
|
||||
else:
|
||||
# X3LF0~向下无背中枢
|
||||
# \
|
||||
# \ ^
|
||||
# \ / \
|
||||
# \ / \
|
||||
# v \
|
||||
# \
|
||||
# \
|
||||
v = ChanSignals.X3LF0.value
|
||||
|
||||
# 上涨线段
|
||||
elif bi_3.direction == 1:
|
||||
# X3SA0~向上不重合
|
||||
if bi_3.high > bi_1.low:
|
||||
# ^
|
||||
# / \
|
||||
# / \
|
||||
# \
|
||||
# \ /
|
||||
# \ /
|
||||
# v
|
||||
if bi_3.high < bi_1.low:
|
||||
v = ChanSignals.X3SA0.value
|
||||
|
||||
# X3SB0~向上奔走型中枢
|
||||
# X3SB0~向上奔走型
|
||||
# ^
|
||||
# / \
|
||||
# / \ /
|
||||
# / \ /
|
||||
# \ /
|
||||
# v
|
||||
if bi_2.low < bi_1.low < bi_3.high < bi_2.high:
|
||||
v = ChanSignals.X3SB0.value
|
||||
|
||||
# X3SC0~向上三角收敛中枢
|
||||
# X3SC0~向上收敛
|
||||
# ^
|
||||
# / \
|
||||
# / \ /
|
||||
# / \ /
|
||||
# / v
|
||||
# /
|
||||
if bi_1.high > bi_3.high and bi_1.low < bi_3.low:
|
||||
v = ChanSignals.X3SC0.value
|
||||
|
||||
# X3SD0~向上三角扩张中枢
|
||||
# X3SD0~向上扩张
|
||||
# /
|
||||
# ^ /
|
||||
# / \ /
|
||||
# / \ /
|
||||
# / \ /
|
||||
# v
|
||||
if bi_1.high < bi_3.high and bi_1.low > bi_3.low:
|
||||
v = ChanSignals.X3SD0.value
|
||||
# X3SE0~向上盘背中枢,X3SF0~向上无背中枢
|
||||
|
||||
# X3SE0~向上盘背,X3SF0~向上无背
|
||||
if bi_3.low > bi_1.low and bi_3.high > bi_1.high:
|
||||
if bi_3.height < bi_1.height:
|
||||
# X3SE0~向上盘背中枢
|
||||
# X3SE0~向上盘背
|
||||
# /
|
||||
# ^ /
|
||||
# / \ /
|
||||
# / \ /
|
||||
# / \ /
|
||||
# / v
|
||||
# /
|
||||
# /
|
||||
v = ChanSignals.X3SE0.value
|
||||
else:
|
||||
# X3SF0~向上无背中枢
|
||||
# X3SF0~向上无背
|
||||
# /
|
||||
# /
|
||||
# ^ /
|
||||
# / \ /
|
||||
# / \ /
|
||||
# / \ /
|
||||
# / v
|
||||
# /
|
||||
v = ChanSignals.X3SF0.value
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def check_chan_xt_five_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
def check_chan_xt_five_bi(kline, bi_list: List[ChanObject]):
|
||||
"""识别当前5笔形态
|
||||
:param cur_duan: 当前线段
|
||||
:param kline: ctaLineBar对象
|
||||
:param bi_list: 笔列表
|
||||
:return: str
|
||||
"""
|
||||
v = ChanSignals.Other.value
|
||||
@ -282,77 +367,77 @@ def check_chan_xt_five_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
# aAb式底背驰
|
||||
if min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) and max_high == bi_1.high and bi_5.height < bi_1.height:
|
||||
if (min_low == bi_3.low and bi_5.low < bi_1.low) or (min_low == bi_5.low):
|
||||
v = ChanSignals.LA0.value
|
||||
return ChanSignals.LA0.value # "底背驰”五笔aAb式
|
||||
|
||||
# 类趋势底背驰( 笔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, bi_1.height) \
|
||||
and bi_5.atan < max(bi_3.atan, bi_1.atan):
|
||||
v = ChanSignals.LA0.value
|
||||
return ChanSignals.LA0.value # "底背驰" 五笔类趋势
|
||||
|
||||
# 上颈线突破
|
||||
if (min_low == bi_1.low and bi_5.high > min(bi_1.high, bi_2.high) > bi_5.low > bi_1.low) \
|
||||
or (min_low == bi_3.low and bi_5.high > bi_3.high > bi_5.low > bi_3.low):
|
||||
v = ChanSignals.LG0.value
|
||||
return ChanSignals.LG0.value # 上颈线突破 五笔
|
||||
|
||||
# 五笔三买,要求bi_5.high是最高点, 或者bi_4.height,超过笔2、笔3两倍
|
||||
if 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:
|
||||
v = ChanSignals.LI0.value
|
||||
elif bi_4.low == min_low and bi_1.high == max_high \
|
||||
v = ChanSignals.LI0.value # 类三买, 五笔
|
||||
elif bi_3.low == min_low and bi_1.high == max_high \
|
||||
and bi_4.height > max(bi_1.height, bi_2.height, bi_3.height) \
|
||||
and bi_4.height > 2 * max(bi_2.height, bi_3.height):
|
||||
v = ChanSignals.LI0.value
|
||||
v = ChanSignals.LI0.value # 类三买, 五笔
|
||||
|
||||
# 向上三角扩张中枢
|
||||
if bi_1.high < bi_3.high < bi_5.high and bi_1.low > bi_3.low > bi_5.low:
|
||||
v = ChanSignals.LJ0.value
|
||||
|
||||
# 向上三角收敛中枢
|
||||
if bi_1.high > bi_3.high > bi_5.high and bi_1.low < bi_3.low < bi_5.low:
|
||||
v = ChanSignals.LK0.value
|
||||
# # 向上三角扩张中枢
|
||||
# if bi_1.high < bi_3.high < bi_5.high and bi_1.low > bi_3.low > bi_5.low:
|
||||
# v = ChanSignals.LJ0.value
|
||||
#
|
||||
# # 向上三角收敛中枢
|
||||
# if bi_1.high > bi_3.high > bi_5.high and bi_1.low < bi_3.low < bi_5.low:
|
||||
# v = ChanSignals.LK0.value
|
||||
|
||||
# 上涨线段,寻找顶背驰
|
||||
elif direction == 1:
|
||||
# aAb式顶背驰
|
||||
# aAb式顶背驰,类一卖
|
||||
if min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) and min_low == bi_1.low and bi_5.height < bi_1.height:
|
||||
if (max_high == bi_3.high and bi_5.high > bi_1.high) or (max_high == bi_5.high):
|
||||
v = ChanSignals.SA0.value
|
||||
return ChanSignals.SA0.value # k3='基础形态', v1='顶背驰', v2='五笔aAb式'
|
||||
|
||||
# 类趋势顶背驰
|
||||
# 类趋势顶背驰,类一卖
|
||||
if min_low == bi_1.low and max_high == bi_5.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
|
||||
return ChanSignals.SA0.value # k3='基础形态', v1='顶背驰', v2='五笔类趋势')
|
||||
|
||||
# 下颈线突破
|
||||
if (max_high == bi_1.high and bi_5.low < max(bi_1.low, bi_2.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
|
||||
return ChanSignals.SG0.value # k3='基础形态', v1='下颈线突破', v2='五笔')
|
||||
|
||||
# 五笔三卖,要求bi_5.low是最低点,中枢可能是1~3
|
||||
if min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) > bi_5.high:
|
||||
if bi_5.low == min_low:
|
||||
v = ChanSignals.SI0.value
|
||||
elif bi_4.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 > 2 * max(bi_2.height,bi_3.height):
|
||||
v = ChanSignals.SI0.value
|
||||
return ChanSignals.SI0.value
|
||||
elif bi_3.high == max_high and bi_1.low == min_low \
|
||||
and bi_4.height > max(bi_1.height, bi_2.height, bi_3.height) \
|
||||
and bi_4.height > 2 * max(bi_2.height, bi_3.height):
|
||||
return ChanSignals.SI0.value # k3='基础形态', v1='类三卖', v2='五笔')
|
||||
# elif bi_1.high == max_high and bi_1.low == min_low:
|
||||
|
||||
# 向下三角扩张中枢
|
||||
if bi_1.high < bi_3.high < bi_5.high and bi_1.low > bi_3.low > bi_5.low:
|
||||
v = ChanSignals.SJ0.value
|
||||
|
||||
# 向下三角收敛中枢
|
||||
if bi_1.high > bi_3.high > bi_5.high and bi_1.low < bi_3.low < bi_5.low:
|
||||
v = ChanSignals.SK0.value
|
||||
# # 向下三角扩张中枢
|
||||
# if bi_1.high < bi_3.high < bi_5.high and bi_1.low > bi_3.low > bi_5.low:
|
||||
# v = ChanSignals.SJ0.value
|
||||
#
|
||||
# # 向下三角收敛中枢
|
||||
# if bi_1.high > bi_3.high > bi_5.high and bi_1.low < bi_3.low < bi_5.low:
|
||||
# v = ChanSignals.SK0.value
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def check_chan_xt_seven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
def check_chan_xt_seven_bi(kline, bi_list: List[ChanObject]):
|
||||
"""
|
||||
识别当前7笔的形态
|
||||
:param cur_duan:
|
||||
@ -371,80 +456,80 @@ def check_chan_xt_seven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
# 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 and bi_7.atan <= bi_5.atan:
|
||||
v = ChanSignals.LA0.value
|
||||
v = ChanSignals.LA0.value # k3='基础形态', v1='底背驰', v2='七笔aAbcd式')
|
||||
|
||||
# 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) \
|
||||
and bi_7.atan < (bi_1.atan + bi_3.atan) / 2:
|
||||
v = ChanSignals.LA0.value
|
||||
v = ChanSignals.LA0.value # k3='基础形态', v1='底背驰', v2='七笔abcAd式')
|
||||
|
||||
# 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 and bi_7.atan <= bi_1.atan:
|
||||
v = ChanSignals.LA0.value
|
||||
v = ChanSignals.LA0.value # k3='基础形态', v1='底背驰', v2='七笔aAb式'
|
||||
|
||||
# 类趋势底背驰
|
||||
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, 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 # k3='基础形态', v1='底背驰', v2='七笔类趋势'
|
||||
|
||||
# 向上中枢完成
|
||||
if bi_4.low == min_low and min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) \
|
||||
and min(bi_5.high, bi_7.high) > max(bi_5.low, bi_7.low) \
|
||||
and max(bi_4.high, bi_6.high) > min(bi_3.high, bi_4.high):
|
||||
if max(bi_1.low, bi_3.low) < max(bi_5.high, bi_7.high):
|
||||
v = ChanSignals.LH0.value
|
||||
v = ChanSignals.LH0.value # k3='基础形态', v1='向上中枢完成', v2='七笔')
|
||||
|
||||
# 七笔三买,567回调
|
||||
# 七笔三买,567回调 :1~3构成中枢,最低点在1~3,最高点在5~7,5~7的最低点大于1~3的最高点
|
||||
if bi_5.high == max_high and bi_5.high > bi_7.high \
|
||||
and bi_5.low > bi_7.low > min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low):
|
||||
v = ChanSignals.LI0.value
|
||||
#
|
||||
v = ChanSignals.LI0.value # k3='基础形态', v1='类三买', v2='七笔'
|
||||
|
||||
elif bi_7.direction == 1:
|
||||
# 顶背驰
|
||||
if bi_1.low == min_low and bi_7.high == max_high:
|
||||
# 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 and bi_7.atan <= bi_5.atan:
|
||||
v = ChanSignals.SA0.value
|
||||
v = ChanSignals.SA0.value # k3='基础形态', v1='顶背驰', v2='七笔aAbcd式'
|
||||
|
||||
# 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) \
|
||||
and bi_7.atan < (bi_1.atan + bi_3.atan) / 2:
|
||||
v = ChanSignals.SA0.value
|
||||
v = ChanSignals.SA0.value # k3='基础形态', v1='顶背驰', v2='七笔abcAd式'
|
||||
|
||||
# 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 and bi_7.atan <= bi_1.atan:
|
||||
v = ChanSignals.SA0.value
|
||||
v = ChanSignals.SA0.value # k3='基础形态', v1='顶背驰', v2='七笔aAb式'
|
||||
|
||||
# 类趋势顶背驰
|
||||
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, 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 # k3='基础形态', v1='顶背驰', v2='七笔类趋势'
|
||||
|
||||
# 向下中枢完成
|
||||
if bi_4.high == max_high and min(bi_1.high, bi_3.high) > max(bi_1.low, bi_3.low) \
|
||||
and min(bi_5.high, bi_7.high) > max(bi_5.low, bi_7.low) \
|
||||
and min(bi_4.low, bi_6.low) < max(bi_3.low, bi_4.low):
|
||||
if min(bi_1.high, bi_3.high) > min(bi_5.low, bi_7.low):
|
||||
v = ChanSignals.SH0.value
|
||||
v = ChanSignals.SH0.value # k3='基础形态', v1='向下中枢完成', v2='七笔'
|
||||
|
||||
# 七笔三卖,567回调,中枢可能在1~3
|
||||
# 七笔三卖,567回调 1~3构成中枢,最高点在1~3,最低点在5~7,5~7的最高点小于1~3的最低点
|
||||
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:
|
||||
v = ChanSignals.SI0.value
|
||||
v = ChanSignals.SI0.value # k3='基础形态', v1='类三卖', v2='七笔'
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def check_chan_xt_nine_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
def check_chan_xt_nine_bi(kline, bi_list: List[ChanObject]):
|
||||
"""
|
||||
获取线段得形态(9分笔)
|
||||
获取线段得买卖点(9分笔)
|
||||
:param cur_duan:
|
||||
:return:
|
||||
"""
|
||||
@ -460,72 +545,126 @@ def check_chan_xt_nine_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
# 依据最后一笔得方向进行判断
|
||||
if direction == -1:
|
||||
if min_low == bi_9.low and max_high == bi_1.high:
|
||||
# aAbBc式底背驰
|
||||
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_2.low, bi_4.low) > max(bi_6.high, bi_8.high) \
|
||||
and bi_9.height < bi_5.height and bi_7.atan <= bi_5.atan:
|
||||
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) \
|
||||
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
|
||||
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔aAb式'
|
||||
|
||||
# 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 \
|
||||
and bi_9.height < bi_7.height and bi_9.atan <= bi_7.atan:
|
||||
v = ChanSignals.LA0.value
|
||||
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔aAbcd式'
|
||||
|
||||
# ABC式底背驰
|
||||
# ABC式类一买
|
||||
if bi_3.low < bi_1.low and bi_7.high > bi_9.high \
|
||||
and min(bi_4.high, bi_6.high) > max(bi_4.low, bi_6.low) \
|
||||
and (bi_1.high - bi_3.low) > (bi_7.high - bi_9.low):
|
||||
v = ChanSignals.LA0.value
|
||||
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔ABC式'
|
||||
|
||||
# 九笔三买(789回调)中枢可能在3~7内
|
||||
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]]):
|
||||
v = ChanSignals.LI0.value
|
||||
# 类趋势一买
|
||||
if bi_8.high < bi_6.low < bi_6.high < bi_4.high < bi_2.low \
|
||||
and bi_9.atan < max([bi_1.atan, bi_3.atan, bi_5.atan, bi_7.atan]):
|
||||
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔类趋势'
|
||||
|
||||
# 9笔 aAbBc式类一买(2~4构成中枢A,6~8构成中枢B,9背驰)
|
||||
if max_high == max(bi_1.high, bi_3.high) and min_low == bi_9.low \
|
||||
and min(bi_2.high, bi_4.high) > max(bi_2.low, bi_4.low) > bi_6.high \
|
||||
and min(bi_6.high, bi_8.high) > max(bi_6.low, bi_8.low) \
|
||||
and min(bi_2.low, bi_4.low) > max(bi_6.high, bi_8.high) \
|
||||
and bi_9.height < bi_5.height and bi_9.atan <= bi_5.atan:
|
||||
return ChanSignals.Q1L0.value # k3='类买卖点', v1='类一买', v2='九笔aAb式')
|
||||
|
||||
# 九笔GG 类三买(1357构成中枢,最低点在3或5)
|
||||
if max_high == bi_9.high > bi_9.low \
|
||||
> max([x.high for x in [bi_1, bi_3, bi_5, bi_7]]) \
|
||||
> min([x.high for x in [bi_1, bi_3, bi_5, bi_7]]) \
|
||||
> max([x.low for x in [bi_1, bi_3, bi_5, bi_7]]) \
|
||||
> min([x.low for x in [bi_3, bi_5]]) == min_low:
|
||||
return ChanSignals.Q3L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三买', v2='九笔GG三买')
|
||||
|
||||
# 类三买(357构成中枢,8的力度小于2,9回调不跌破GG构成三买)
|
||||
if bi_8.height < bi_2.height and max_high == bi_9.high > bi_9.low \
|
||||
> max([x.high for x in [bi_3, bi_5, bi_7]]) \
|
||||
> min([x.high for x in [bi_3, bi_5, bi_7]]) \
|
||||
> max([x.low for x in [bi_3, bi_5, bi_7]]) > bi_1.low == min_low:
|
||||
return ChanSignals.Q3L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三买', v2='九笔GG三买')
|
||||
|
||||
# # 九笔三买(789回调)中枢可能在3~7内
|
||||
# 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]]):
|
||||
# v = ChanSignals.Q3L0.value
|
||||
|
||||
if min_low == bi_5.low and max_high == bi_1.high and bi_4.high < bi_2.low: # 前五笔构成向下类趋势
|
||||
zd = max([x.low for x in [bi_5, bi_7]])
|
||||
zg = min([x.high for x in [bi_5, bi_7]])
|
||||
gg = max([x.high for x in [bi_5, bi_7]])
|
||||
if zg > zd and bi_8.high > gg: # 567构成中枢,且8的高点大于gg
|
||||
if bi_9.low > zg:
|
||||
return ChanSignals.Q3L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三买', v2='九笔ZG三买')
|
||||
|
||||
# 类二买
|
||||
if bi_9.high > gg > zg > bi_9.low > zd:
|
||||
return ChanSignals.Q2L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二买', v2='九笔')
|
||||
|
||||
elif direction == 1:
|
||||
if max_high == bi_9.high and min_low == bi_1.low:
|
||||
# aAbBc式顶背驰
|
||||
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 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:
|
||||
v = ChanSignals.SA0.value
|
||||
|
||||
# aAb式顶背驰
|
||||
# 倒9笔是最高点,倒一笔是最低点
|
||||
if max_high == bi_9.high and min_low == bi_1.low:
|
||||
|
||||
# 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) \
|
||||
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
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔aAb式')
|
||||
|
||||
# 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) \
|
||||
and bi_9.height < bi_7.height and bi_9.atan <= bi_7.atan:
|
||||
v = ChanSignals.SA0.value
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔aAbcd式')
|
||||
|
||||
# ABC式顶背驰
|
||||
# ABC式类一卖
|
||||
if bi_3.high > bi_1.high and bi_7.low < bi_9.low \
|
||||
and min(bi_4.high, bi_6.high) > max(bi_4.low, bi_6.low) \
|
||||
and (bi_3.high - bi_1.low) > (bi_9.high - bi_7.low):
|
||||
v = ChanSignals.SA0.value
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔ABC式')
|
||||
|
||||
# 九笔三卖
|
||||
# 类趋势类一卖
|
||||
if bi_8.low > bi_6.high > bi_6.low > bi_4.high > bi_4.low > bi_2.high \
|
||||
and bi_9.atan < max([bi_1.atan, bi_3.atan, bi_5.atan, bi_7.atan]):
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔类趋势')
|
||||
|
||||
# aAbBc式类一卖
|
||||
if max_high == bi_9.high and min_low == min(bi_1.low, bi_3.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 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:
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2='九笔aAbBc式')
|
||||
|
||||
# 九笔类三卖
|
||||
if max_high == bi_1.high and min_low == bi_9.low \
|
||||
and bi_9.high < max([x.low for x in [bi_3, bi_5, bi_7]]) < min([x.high for x in [bi_3, bi_5, bi_7]]):
|
||||
v = ChanSignals.SI0.value
|
||||
return ChanSignals.Q3S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三卖', v2='九笔')
|
||||
|
||||
if min_low == bi_1.low and max_high == bi_5.high and bi_2.high < bi_4.low: # 前五笔构成向上类趋势
|
||||
zd = max([x.low for x in [bi_5, bi_7]])
|
||||
zg = min([x.high for x in [bi_5, bi_7]])
|
||||
dd = min([x.low for x in [bi_5, bi_7]])
|
||||
if zg > zd and bi_8.low < dd: # 567构成中枢,且8的低点小于dd
|
||||
if bi_9.high < zd:
|
||||
return ChanSignals.Q3S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三卖', v2='九笔ZD三卖')
|
||||
|
||||
# 类二卖
|
||||
if dd < zd <= bi_9.high < zg:
|
||||
return ChanSignals.Q2S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二卖', v2='九笔')
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
def check_chan_xt_eleven_bi(kline, bi_list: List[ChanObject]):
|
||||
"""
|
||||
获取线段得背驰形态(含11个分笔)
|
||||
获取线段得的类买卖点(含11个分笔)
|
||||
:param cur_duan:
|
||||
:return:
|
||||
"""
|
||||
@ -538,95 +677,126 @@ def check_chan_xt_eleven_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
max_high = max([x.high for x in bi_list])
|
||||
min_low = min([x.low for x in bi_list])
|
||||
|
||||
# 11笔向下,寻找买点
|
||||
if direction == -1:
|
||||
# 1笔最高,11笔最低
|
||||
if min_low == bi_11.low and max_high == bi_1.high:
|
||||
# aAbBc式底背驰,bi_2-bi_6构成A
|
||||
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_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.atan <= bi_7.atan:
|
||||
v = ChanSignals.LA0.value
|
||||
|
||||
# aAbBc式底背驰,bi_6-bi_10构成B
|
||||
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_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.atan <= bi_5.atan:
|
||||
v = ChanSignals.LA0.value
|
||||
|
||||
# ABC式底背驰,A5B3C3
|
||||
# ABC式类一买,A5B3C3
|
||||
if bi_5.low == min([x.low for x in [bi_1, bi_3, bi_5]]) \
|
||||
and bi_9.low > bi_11.low and bi_9.high > bi_11.high \
|
||||
and bi_8.high > bi_6.low and bi_1.high - bi_5.low > bi_9.high - bi_11.low:
|
||||
v = ChanSignals.LA0.value
|
||||
# C内部背驰
|
||||
if bi_11.height < bi_9.height:
|
||||
v = ChanSignals.LB0.value
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="11笔A5B3C3式")
|
||||
|
||||
# ABC式底背驰,A3B3C5
|
||||
# ABC式类一买,A3B3C5
|
||||
if bi_1.high > bi_3.high and bi_1.low > bi_3.low \
|
||||
and bi_7.high == max([x.high for x in [bi_7, bi_9, bi_11]]) \
|
||||
and bi_6.high > bi_4.low and bi_1.high - bi_3.low > bi_7.high - bi_11.low:
|
||||
v = ChanSignals.LA0.value
|
||||
# C内部背驰
|
||||
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
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="11笔A3B3C5式")
|
||||
|
||||
# ABC式底背驰,A3B5C3
|
||||
# ABC式类一买,A3B5C3
|
||||
if bi_1.low > bi_3.low and min(bi_4.high, bi_6.high, bi_8.high) > max(bi_4.low, bi_6.low, bi_8.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
|
||||
# C内部背驰
|
||||
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.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="11笔A3B5C3式")
|
||||
|
||||
# a1Ab式类一买,a1(1~7构成的类趋势)
|
||||
if bi_2.low > bi_4.high > bi_4.low > bi_6.high > bi_5.low > bi_7.low and bi_10.high > bi_8.low:
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="11笔a1Ab式")
|
||||
|
||||
# 类二买:1~9构成类趋势,11不创新低,斜率低于9
|
||||
if min_low == bi_9.low < bi_8.high < bi_6.low < bi_6.high < bi_4.low < bi_4.high < bi_2.low < bi_1.high == max_high \
|
||||
and bi_11.low > bi_9.low and bi_9.atan > bi_11.atan:
|
||||
return ChanSignals.Q2L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二买', v2="11笔")
|
||||
|
||||
# 类二买(1~7构成盘整背驰,246构成下跌中枢,9/11构成上涨中枢,且上涨中枢ZG大于下跌中枢ZG)
|
||||
if bi_7.atan < bi_1.atan and min_low == bi_7.low < max([x.low for x in [bi_2, bi_4, bi_6]]) \
|
||||
< min([x.high for x in [bi_2, bi_4, bi_6]]) < max(
|
||||
[x.high for x in [bi_9, bi_11]]) < bi_1.high == max_high \
|
||||
and bi_11.low > min([x.low for x in [bi_2, bi_4, bi_6]]) \
|
||||
and min([x.high for x in [bi_9, bi_11]]) > max([x.low for x in [bi_9, bi_11]]):
|
||||
return ChanSignals.Q2L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二买', v2="11笔")
|
||||
|
||||
# 类二买(1~7为区间极值,9~11构成上涨中枢,上涨中枢GG大于4~6的最大值,上涨中枢DD大于4~6的最小值)
|
||||
if max_high == bi_1.high and min_low == bi_7.low \
|
||||
and min(bi_9.high, bi_11.high) > max(bi_9.low, bi_11.low) \
|
||||
and max(bi_11.high, bi_9.high) > max(bi_4.high, bi_6.high) \
|
||||
and min(bi_9.low, bi_11.low) > min(bi_4.low, bi_6.low):
|
||||
return ChanSignals.Q2L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二买', v2="11笔")
|
||||
|
||||
# 类三买(1~9构成大级别中枢,10离开,11回调不跌破GG)
|
||||
gg = max([x.high for x in [bi_1, bi_2, bi_3]])
|
||||
zg = min([x.high for x in [bi_1, bi_2, bi_3]])
|
||||
zd = max([x.low for x in [bi_1, bi_2, bi_3]])
|
||||
dd = min([x.low for x in [bi_1, bi_2, bi_3]])
|
||||
if max_high == bi_11.high and bi_11.low > zg > zd \
|
||||
and gg > bi_5.low and gg > bi_7.low and gg > bi_9.low \
|
||||
and dd < bi_5.high and dd < bi_7.high and dd < bi_9.high:
|
||||
return ChanSignals.Q3L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三买', v2="11笔GG三买")
|
||||
|
||||
# 11笔向上,寻找卖点
|
||||
elif direction == 1:
|
||||
# 1笔最低,11笔最高
|
||||
if max_high == bi_11.high and min_low == bi_1.low:
|
||||
# aAbBC式顶背驰,bi_2-bi_6构成A
|
||||
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 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.atan <= bi_7.atan:
|
||||
v = ChanSignals.SA0.value
|
||||
|
||||
# aAbBC式顶背驰,bi_6-bi_10构成B
|
||||
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 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.atan <= bi_7.atan:
|
||||
v = ChanSignals.SA0.value
|
||||
|
||||
# ABC式顶背驰,A5B3C3
|
||||
if bi_5.high == max([bi_1.high, bi_3.high, bi_5.high]) and bi_9.low < bi_11.low and bi_9.high < bi_11.high \
|
||||
and bi_8.low < bi_6.high and bi_11.high - bi_9.low < bi_5.high - bi_1.low:
|
||||
v = ChanSignals.SA0.value
|
||||
# C内部背驰
|
||||
if bi_11.height < bi_9.height and bi_11.atan <= bi_9.atan:
|
||||
v = ChanSignals.SB0.value
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="11笔A5B3C3式")
|
||||
|
||||
# ABC式顶背驰,A3B3C5
|
||||
if bi_7.low == min([bi_11.low, bi_9.low, bi_7.low]) and bi_1.high < bi_3.high and bi_1.low < bi_3.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
|
||||
# C内部背驰
|
||||
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
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="11笔A3B3C5式")
|
||||
|
||||
# ABC式顶背驰,A3B5C3
|
||||
if bi_1.high < bi_3.high and min(bi_4.high, bi_6.high, bi_8.high) > max(bi_4.low, bi_6.low, bi_8.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
|
||||
# C内部背驰
|
||||
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
|
||||
return ChanSignals.Q1S0.value
|
||||
|
||||
# a1Ab式类一卖,a1(1~7构成的类趋势)
|
||||
if bi_2.high < bi_4.low < bi_4.high < bi_6.low < bi_5.high < bi_7.high and bi_10.low < bi_8.high:
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="11笔a1Ab式")
|
||||
|
||||
# 类二卖:1~9构成类趋势,11不创新高
|
||||
if max_high == bi_9.high > bi_8.low > bi_6.high > bi_6.low > bi_4.high > bi_4.low > bi_2.high > bi_1.low == min_low \
|
||||
and bi_11.high < bi_9.high and bi_9.atan > bi_11.atan:
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二卖', v2="11笔")
|
||||
|
||||
# 类二卖(1~7构成盘整背驰,246构成上涨中枢,9/11构成下跌中枢,且下跌中枢DD小于上涨中枢ZD)
|
||||
if bi_7.atan < bi_1.atan and max_high == bi_7.high \
|
||||
> min([x.high for x in [bi_2, bi_4, bi_6]]) \
|
||||
> max([x.low for x in [bi_2, bi_4, bi_6]]) \
|
||||
> min([x.low for x in [bi_9, bi_11]]) \
|
||||
> bi_1.low == min_low \
|
||||
and bi_11.high < max([x.high for x in [bi_2, bi_4, bi_6]]) \
|
||||
and max([x.low for x in [bi_9, bi_11]]) < min([x.high for x in [bi_9, bi_11]]):
|
||||
return ChanSignals.Q2S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二卖', v2="11笔")
|
||||
|
||||
# 类二卖(1~7为区间极值,9~11构成下跌中枢,下跌中枢DD小于4~6的最小值,下跌中枢GG小于4~6的最大值)
|
||||
if min_low == bi_1.low and max_high == bi_7.high \
|
||||
and max(bi_9.low, bi_11.low) < min(bi_9.high, bi_11.high) \
|
||||
and min(bi_11.low, bi_9.low) < min(bi_4.low, bi_6.low) \
|
||||
and max(bi_9.high, bi_11.high) < max(bi_4.high, bi_6.high):
|
||||
return ChanSignals.Q2S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类二卖', v2="11笔")
|
||||
|
||||
# 类三卖(1~9构成大级别中枢,10离开,11回调不涨破DD)
|
||||
gg = min([x.low for x in [bi_1, bi_2, bi_3]])
|
||||
zg = max([x.low for x in [bi_1, bi_2, bi_3]])
|
||||
zd = min([x.high for x in [bi_1, bi_2, bi_3]])
|
||||
dd = max([x.high for x in [bi_1, bi_2, bi_3]])
|
||||
if min_low == bi_11.low and bi_11.high < zd < zg \
|
||||
and dd < bi_5.high and dd < bi_7.high and dd < bi_9.high \
|
||||
and gg > bi_5.low and gg > bi_7.low and gg > bi_9.low:
|
||||
return ChanSignals.Q3S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类三卖', v2="11笔GG三买")
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
def check_chan_xt_thirteen_bi(kline, bi_list: List[ChanObject]):
|
||||
"""
|
||||
获取线段得背驰形态(含13个分笔)
|
||||
:param cur_duan:
|
||||
获取线段得形态(含13个分笔)
|
||||
:param kline:
|
||||
:param bi_list: 由远及近的十三笔
|
||||
:return:
|
||||
"""
|
||||
v = ChanSignals.Other.value
|
||||
@ -641,78 +811,48 @@ def check_chan_xt_thirteen_bi(kline: CtaLineBar, bi_list: List[ChanObject]):
|
||||
# 下跌线段时,判断背驰类型
|
||||
if direction == -1:
|
||||
if min_low == bi_13.low and max_high == bi_1.high:
|
||||
# aAbBc式底背驰,bi_2-bi_6构成A,bi_8-bi_12构成B
|
||||
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_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.atan <= bi_7.atan:
|
||||
v = ChanSignals.LA0.value
|
||||
|
||||
# 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) \
|
||||
and bi_8.high > bi_6.low and bi_1.high - bi_5.low > bi_9.high - bi_13.low:
|
||||
v = ChanSignals.LA0.value
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B3C5式")
|
||||
|
||||
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
|
||||
|
||||
# ABC式底背驰,A3B5C5
|
||||
# ABC式类一买,A3B5C5
|
||||
if bi_3.low < min(bi_1.low, bi_5.low) and bi_9.high > max(bi_11.high, bi_13.high) \
|
||||
and min(bi_4.high, bi_6.high, bi_8.high) > max(bi_4.low, bi_6.low, bi_8.low) \
|
||||
and bi_1.high - bi_3.low > bi_9.high - bi_13.low:
|
||||
v = ChanSignals.LA0.value
|
||||
|
||||
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
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A3B5C5式")
|
||||
|
||||
# ABC式底背驰,A5B5C3
|
||||
if bi_5.low < min(bi_1.low, bi_3.low) and bi_11.high > max(bi_9.high, bi_13.high) \
|
||||
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:
|
||||
v = ChanSignals.LA0.value
|
||||
|
||||
if bi_13.height < bi_11.height and bi_13.atan <= bi_11.atan:
|
||||
v = ChanSignals.LB0.value
|
||||
return ChanSignals.Q1L0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一买', v2="13笔A5B5C3式")
|
||||
|
||||
# 上涨线段时,判断背驰类型
|
||||
elif direction == 1:
|
||||
if max_high == bi_13.high and min_low == bi_1.low:
|
||||
# aAbBC式顶背驰,bi_2-bi_6构成A,bi_8-bi_12构成B
|
||||
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 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.atan <= bi_7.atan:
|
||||
v = ChanSignals.SA0.value
|
||||
|
||||
# ABC式顶背驰,A5B3C5
|
||||
if bi_5.high > max(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:
|
||||
v = ChanSignals.SA0.value
|
||||
# C内部顶背驰,形成双重顶背驰
|
||||
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
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="13笔A5B3C5式")
|
||||
|
||||
# ABC式顶背驰,A3B5C5
|
||||
if bi_3.high > max(bi_5.high, bi_1.high) and bi_9.low < min(bi_11.low, bi_13.low) \
|
||||
and min(bi_4.high, bi_6.high, bi_8.high) > max(bi_4.low, bi_6.low, bi_8.low) \
|
||||
and bi_3.high - bi_1.low > bi_13.high - bi_9.low:
|
||||
v = ChanSignals.SA0.value
|
||||
# C内部顶背驰,形成双重顶背驰
|
||||
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
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="13笔A3B5C5式")
|
||||
|
||||
# ABC式顶背驰,A5B5C3
|
||||
if bi_5.high > max(bi_3.high, bi_1.high) and bi_11.low < min(bi_9.low, bi_13.low) \
|
||||
and min(bi_6.high, bi_8.high, bi_10.high) > max(bi_6.low, bi_8.low, bi_10.low) \
|
||||
and bi_5.high - bi_1.low > bi_13.high - bi_11.low:
|
||||
v = ChanSignals.SA0.value
|
||||
# C内部顶背驰,形成双重顶背驰
|
||||
if bi_13.height < bi_11.height and bi_13.atan <= bi_11.atan:
|
||||
v = ChanSignals.SB0.value
|
||||
return ChanSignals.Q1S0.value # Signal(k1=freq.value, k2=di_name, k3='类买卖点', v1='类一卖', v2="13笔A5B5C3式")
|
||||
|
||||
return v
|
||||
|
||||
|
||||
def check_pzbc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
# def check_pzbc_1st(big_kline, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
def check_pzbc_1st(big_kline, small_kline, signal_direction: Direction):
|
||||
"""
|
||||
判断中枢盘整背驰1买/1卖信号
|
||||
big_kline当前线段为调整段,与信号方向相反,线段具有盘整一个中枢,
|
||||
@ -806,7 +946,8 @@ def check_pzbc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None],
|
||||
return False
|
||||
|
||||
|
||||
def check_qsbc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
# def check_qsbc_1st(big_kline, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
def check_qsbc_1st(big_kline, small_kline, signal_direction: Direction):
|
||||
"""
|
||||
判断趋势背驰1买/1卖信号
|
||||
big_kline当前线段为趋势,与信号方向相反,线段具有2个中枢,
|
||||
@ -890,7 +1031,8 @@ def check_qsbc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None],
|
||||
return False
|
||||
|
||||
|
||||
def check_pz3bc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
# def check_pz3bc_1st(big_kline, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
def check_pz3bc_1st(big_kline, small_kline, signal_direction: Direction):
|
||||
"""
|
||||
判断三卖后盘整背驰一买/三买后盘整背驰1卖信号
|
||||
big_kline当前线段与信号方向相反,线段具有盘整一个中枢,离开中枢的一笔力度与三买/卖信号后的一笔对比(高度、斜率)
|
||||
@ -966,7 +1108,8 @@ def check_pz3bc_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None],
|
||||
return False
|
||||
|
||||
|
||||
def check_qjt_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
# def check_qjt_1st(big_kline, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
def check_qjt_1st(big_kline, small_kline, signal_direction: Direction):
|
||||
"""
|
||||
判断区间套一买/区间套1卖信号
|
||||
big_kline当前线段与信号方向相反,线段具有盘整一个中枢,
|
||||
@ -1038,7 +1181,8 @@ def check_qjt_1st(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], s
|
||||
return False
|
||||
|
||||
|
||||
def check_qsbc_2nd(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
# def check_qsbc_2nd(big_kline, small_kline: Union[CtaLineBar, None], signal_direction: Direction):
|
||||
def check_qsbc_2nd(big_kline, small_kline, signal_direction: Direction):
|
||||
"""
|
||||
判断趋势背驰1买/1卖后的二买、二卖信号
|
||||
big_kline当前线段为趋势,与信号方向相反,线段具有2个中枢,
|
||||
@ -1136,8 +1280,9 @@ def check_qsbc_2nd(big_kline: CtaLineBar, small_kline: Union[CtaLineBar, None],
|
||||
return True
|
||||
|
||||
|
||||
def check_zs_3rd(big_kline: CtaLineBar,
|
||||
small_kline: Union[CtaLineBar, None],
|
||||
# : Union[CtaLineBar, None]
|
||||
def check_zs_3rd(big_kline,
|
||||
small_kline,
|
||||
signal_direction: Direction,
|
||||
first_zs: bool = True,
|
||||
all_zs: bool = True):
|
||||
@ -1181,7 +1326,7 @@ def check_zs_3rd(big_kline: CtaLineBar,
|
||||
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:
|
||||
if first_zs and zs_num > 1:
|
||||
return False
|
||||
else:
|
||||
# 中枢需要与当前线段有交集[部分交集、或中枢完全在当前段内形成]
|
||||
|
@ -112,7 +112,7 @@ def download_adjust_factor():
|
||||
login_msg = bs.login()
|
||||
if login_msg.error_code != '0':
|
||||
print(f'证券宝登录错误代码:{login_msg.error_code}, 错误信息:{login_msg.error_msg}')
|
||||
return
|
||||
return None
|
||||
|
||||
for k, v in base_dict.items():
|
||||
if v.get('类型') != '股票':
|
||||
@ -127,6 +127,7 @@ def download_adjust_factor():
|
||||
save_data_to_pkb2(factor_dict, cache_file_name)
|
||||
print(f'保存除权除息至文件:{cache_file_name}')
|
||||
|
||||
return factor_dict
|
||||
|
||||
if __name__ == '__main__':
|
||||
download_adjust_factor()
|
||||
|
@ -415,7 +415,7 @@ class PbGateway(BaseGateway):
|
||||
def process_timer_event(self, event) -> None:
|
||||
""""""
|
||||
self.count += 1
|
||||
if self.count < 2:
|
||||
if self.count < 5:
|
||||
return
|
||||
self.count = 0
|
||||
|
||||
@ -1116,10 +1116,26 @@ class PbTdApi(object):
|
||||
'{}{}.dbf'.format(
|
||||
PB_FILE_NAMES.get('accounts'),
|
||||
self.trading_date)))
|
||||
|
||||
copy_dbf = os.path.abspath(os.path.join(self.account_folder,
|
||||
'{}{}_{}.dbf'.format(
|
||||
PB_FILE_NAMES.get('accounts'),
|
||||
self.trading_date,
|
||||
datetime.now().strftime('%H%M'))))
|
||||
try:
|
||||
if not os.path.exists(account_dbf):
|
||||
return
|
||||
if os.path.exists(copy_dbf):
|
||||
os.remove(copy_dbf)
|
||||
|
||||
# =》转移至于新文件
|
||||
os.rename(account_dbf, copy_dbf)
|
||||
if not os.path.exists(copy_dbf):
|
||||
return
|
||||
|
||||
# dbf => 资金帐号信息
|
||||
self.gateway.write_log(f'扫描资金帐号信息:{account_dbf}')
|
||||
table = dbf.Table(account_dbf, codepage='cp936')
|
||||
self.gateway.write_log(f'扫描资金帐号信息:{copy_dbf}')
|
||||
table = dbf.Table(copy_dbf, codepage='cp936')
|
||||
table.open(dbf.READ_ONLY)
|
||||
for data in table:
|
||||
# ["资金账户"]
|
||||
@ -1137,6 +1153,8 @@ class PbTdApi(object):
|
||||
|
||||
table.close()
|
||||
self.warning_dict.pop('query_account', None)
|
||||
if os.path.exists(copy_dbf):
|
||||
os.remove(copy_dbf)
|
||||
|
||||
except Exception as ex:
|
||||
err_msg = f'dbf扫描资金帐号异常:{str(ex)}'
|
||||
@ -1200,10 +1218,24 @@ class PbTdApi(object):
|
||||
'{}{}.dbf'.format(
|
||||
PB_FILE_NAMES.get('positions'),
|
||||
self.trading_date)))
|
||||
|
||||
copy_dbf = os.path.abspath(os.path.join(self.account_folder,
|
||||
'{}{}_{}.dbf'.format(
|
||||
PB_FILE_NAMES.get('positions'),
|
||||
self.trading_date,
|
||||
datetime.now().strftime('%H%M'))))
|
||||
try:
|
||||
if not os.path.exists(position_dbf):
|
||||
return
|
||||
if os.path.exists(copy_dbf):
|
||||
os.remove(copy_dbf)
|
||||
os.rename(position_dbf, copy_dbf)
|
||||
if not os.path.exists(copy_dbf):
|
||||
return
|
||||
|
||||
# dbf => 股票持仓信息
|
||||
self.gateway.write_log(f'扫描股票持仓信息:{position_dbf}')
|
||||
table = dbf.Table(position_dbf, codepage='cp936')
|
||||
self.gateway.write_log(f'扫描股票持仓信息:{copy_dbf}')
|
||||
table = dbf.Table(copy_dbf, codepage='cp936')
|
||||
table.open(dbf.READ_ONLY)
|
||||
for data in table:
|
||||
if str(data.zjzh).strip() != self.userid:
|
||||
@ -1242,6 +1274,9 @@ class PbTdApi(object):
|
||||
table.close()
|
||||
self.warning_dict.pop('query_position', None)
|
||||
|
||||
if os.path.exists(copy_dbf):
|
||||
os.remove(copy_dbf)
|
||||
|
||||
except Exception as ex:
|
||||
|
||||
err_msg = f'dbf扫描股票持仓异常:{str(ex)}'
|
||||
@ -1325,6 +1360,8 @@ class PbTdApi(object):
|
||||
PB_FILE_NAMES.get('orders'),
|
||||
self.trading_date)))
|
||||
try:
|
||||
if not os.path.exists(orders_dbf):
|
||||
return
|
||||
# dbf => 股票委托信息
|
||||
self.gateway.write_log(f'扫描股票委托信息:{orders_dbf}')
|
||||
table = dbf.Table(orders_dbf, codepage='cp936')
|
||||
@ -1506,8 +1543,9 @@ class PbTdApi(object):
|
||||
'{}{}.dbf'.format(
|
||||
PB_FILE_NAMES.get('update_orders'),
|
||||
self.trading_date)))
|
||||
# dbf => 所有委托记录
|
||||
try:
|
||||
if not os.path.exists(orders_dbf):
|
||||
return
|
||||
# dbf => 所有成交记录
|
||||
self.gateway.write_log(f'扫描所有委托查询:{orders_dbf}')
|
||||
table = dbf.Table(orders_dbf, codepage='cp936')
|
||||
@ -1686,6 +1724,8 @@ class PbTdApi(object):
|
||||
PB_FILE_NAMES.get('trades'),
|
||||
self.trading_date)))
|
||||
try:
|
||||
if not os.path.exists(trades_dbf):
|
||||
return
|
||||
# dbf => 股票成交信息
|
||||
self.gateway.write_log(f'扫描股票成交信息:{trades_dbf}')
|
||||
table = dbf.Table(trades_dbf, codepage='cp936')
|
||||
@ -1824,6 +1864,8 @@ class PbTdApi(object):
|
||||
self.trading_date)))
|
||||
|
||||
try:
|
||||
if not os.path.exists(trades_dbf):
|
||||
return
|
||||
# dbf => 所有成交记录
|
||||
self.gateway.write_log(f'扫描所有成交记录:{trades_dbf}')
|
||||
table = dbf.Table(trades_dbf, codepage='cp936')
|
||||
@ -1981,6 +2023,9 @@ class PbTdApi(object):
|
||||
dbf_file = os.path.abspath(os.path.join(self.order_folder,
|
||||
'{}{}.dbf'.format(PB_FILE_NAMES.get('send_order'), self.trading_date)))
|
||||
try:
|
||||
if not os.path.exists(dbf_file):
|
||||
return
|
||||
|
||||
table = dbf.Table(dbf_file, codepage='cp936')
|
||||
table.open(dbf.READ_ONLY)
|
||||
for record in table:
|
||||
|
@ -214,85 +214,20 @@ class ChanSignals(Enum):
|
||||
LB0 = "LB0~双重底背驰"
|
||||
LG0 = "LG0~上颈线突破"
|
||||
LH0 = "LH0~向上中枢完成"
|
||||
LI0 = "LI0~三买"
|
||||
LI0 = "LI0~类三买"
|
||||
LJ0 = "LJ0~向上三角扩张中枢"
|
||||
LK0 = "LK0~向上三角收敛中枢"
|
||||
LL0 = "LL0~向上平台型中枢"
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
LA1 = "LA1~底背驰特例一"
|
||||
LA2 = "LA2~底背驰特例二"
|
||||
LA3 = "LA3~底背驰特例三"
|
||||
|
||||
LB1 = "LB1~双重底背驰特例一"
|
||||
LB2 = "LB2~双重底背驰特例二"
|
||||
LB3 = "LB3~双重底背驰特例三"
|
||||
|
||||
LG1 = "LG1~上颈线突破特例一"
|
||||
LG2 = "LG2~上颈线突破特例二"
|
||||
LG3 = "LG3~上颈线突破特例三"
|
||||
|
||||
LH1 = "LH1~向上中枢完成特例一"
|
||||
LH2 = "LH2~向上中枢完成特例二"
|
||||
LH3 = "LH3~向上中枢完成特例三"
|
||||
|
||||
LI1 = "LI1~三买特例一"
|
||||
LI2 = "LI2~三买特例二"
|
||||
LI3 = "LI3~三买特例三"
|
||||
|
||||
LJ1 = "LJ1~向上三角扩张中枢特例一"
|
||||
LJ2 = "LJ2~向上三角扩张中枢特例二"
|
||||
LJ3 = "LJ3~向上三角扩张中枢特例三"
|
||||
|
||||
LK1 = "LK1~向上三角收敛中枢特例一"
|
||||
LK2 = "LK2~向上三角收敛中枢特例二"
|
||||
LK3 = "LK3~向上三角收敛中枢特例三"
|
||||
|
||||
LL1 = "LL1~向上平台型中枢特例一"
|
||||
LL2 = "LL2~向上平台型中枢特例二"
|
||||
LL3 = "LL3~向上平台型中枢特例三"
|
||||
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
SA0 = "SA0~顶背驰"
|
||||
SB0 = "SB0~双重顶背驰"
|
||||
SG0 = "SG0~下颈线突破"
|
||||
SH0 = "SH0~向下中枢完成"
|
||||
SI0 = "SI0~三卖"
|
||||
SI0 = "SI0~类三卖"
|
||||
SJ0 = "SJ0~向下三角扩张中枢"
|
||||
SK0 = "SK0~向下三角收敛中枢"
|
||||
SL0 = "SL0~向下平台型中枢"
|
||||
# ------------------------------------------------------------------------------------------------------------------
|
||||
SA1 = "SA1~顶背驰特例一"
|
||||
SA2 = "SA2~顶背驰特例二"
|
||||
SA3 = "SA3~顶背驰特例三"
|
||||
|
||||
SB1 = "SB1~双重顶背驰特例一"
|
||||
SB2 = "SB2~双重顶背驰特例二"
|
||||
SB3 = "SB3~双重顶背驰特例三"
|
||||
|
||||
SG1 = "SG1~下颈线突破特例一"
|
||||
SG2 = "SG2~下颈线突破特例二"
|
||||
SG3 = "SG3~下颈线突破特例三"
|
||||
|
||||
SH1 = "SH1~向下中枢完成特例一"
|
||||
SH2 = "SH2~向下中枢完成特例二"
|
||||
SH3 = "SH3~向下中枢完成特例三"
|
||||
|
||||
SI1 = "SI1~三卖特例一"
|
||||
SI2 = "SI2~三卖特例二"
|
||||
SI3 = "SI3~三卖特例三"
|
||||
|
||||
SJ1 = "SJ1~向下三角扩张中枢特例一"
|
||||
SJ2 = "SJ2~向下三角扩张中枢特例二"
|
||||
SJ3 = "SJ3~向下三角扩张中枢特例三"
|
||||
|
||||
SK1 = "SK1~向下三角收敛中枢特例一"
|
||||
SK2 = "SK2~向下三角收敛中枢特例二"
|
||||
SK3 = "SK3~向下三角收敛中枢特例三"
|
||||
|
||||
SL1 = "SL1~向下平台型中枢特例一"
|
||||
SL2 = "SL2~向下平台型中枢特例二"
|
||||
SL3 = "SL3~向下平台型中枢特例三"
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# 信号值编码规则:
|
||||
@ -304,16 +239,24 @@ class ChanSignals(Enum):
|
||||
# 三笔形态信号
|
||||
# --------------------------------------------------------------------------------------------
|
||||
X3LA0 = "X3LA0~向下不重合"
|
||||
X3LB0 = "X3LB0~向下奔走型中枢"
|
||||
X3LC0 = "X3LC0~向下三角收敛中枢"
|
||||
X3LD0 = "X3LD0~向下三角扩张中枢"
|
||||
X3LE0 = "X3LE0~向下盘背中枢"
|
||||
X3LF0 = "X3LF0~向下无背中枢"
|
||||
X3LB0 = "X3LB0~向下奔走型"
|
||||
X3LC0 = "X3LC0~向下收敛"
|
||||
X3LD0 = "X3LD0~向下扩张"
|
||||
X3LE0 = "X3LE0~向下盘背"
|
||||
X3LF0 = "X3LF0~向下无背"
|
||||
|
||||
X3SA0 = "X3SA0~向上不重合"
|
||||
X3SB0 = "X3SB0~向上奔走型中枢"
|
||||
X3SC0 = "X3SC0~向上三角收敛中枢"
|
||||
X3SD0 = "X3SD0~向上三角扩张中枢"
|
||||
X3SE0 = "X3SE0~向上盘背中枢"
|
||||
X3SF0 = "X3SF0~向上无背中枢"
|
||||
X3SB0 = "X3SB0~向上奔走型"
|
||||
X3SC0 = "X3SC0~向上收敛"
|
||||
X3SD0 = "X3SD0~向上扩张"
|
||||
X3SE0 = "X3SE0~向上盘背"
|
||||
X3SF0 = "X3SF0~向上无背"
|
||||
|
||||
# 趋势类买卖点
|
||||
Q1L0 = "Q1L0~趋势类一买"
|
||||
Q2L0 = "Q2L0~趋势类二买"
|
||||
Q3L0 = "Q2L0~趋势类三买"
|
||||
|
||||
Q1S0 = "Q1S0~趋势类一卖"
|
||||
Q2S0 = "Q2S0~趋势类二卖"
|
||||
Q3S0 = "Q2S0~趋势类三卖"
|
||||
|
@ -171,6 +171,8 @@ class MainEngine:
|
||||
gateway = self.get_gateway(gateway_name)
|
||||
if gateway:
|
||||
return gateway.get_default_setting()
|
||||
else:
|
||||
self.write_error(f'获取网格设置时,找不到{gateway_name}')
|
||||
return None
|
||||
|
||||
def get_all_gateway_names(self) -> List[str]:
|
||||
@ -209,6 +211,8 @@ class MainEngine:
|
||||
except Exception as ex:
|
||||
msg = f'gateway:{gateway_name}启动连接失败:{str(ex)}'
|
||||
self.write_log(msg=msg)
|
||||
else:
|
||||
self.write_error(f'连接{gateway_name}时,系统找不到{gateway_name}')
|
||||
|
||||
def subscribe(self, req: SubscribeRequest, gateway_name: str) -> None:
|
||||
"""
|
||||
@ -219,6 +223,8 @@ class MainEngine:
|
||||
gateway = self.get_gateway(gateway_name)
|
||||
if gateway:
|
||||
gateway.subscribe(req)
|
||||
else:
|
||||
self.write_error(f'订阅合约时,找不到{gateway_name}')
|
||||
else:
|
||||
for gateway in self.gateways.values():
|
||||
if gateway:
|
||||
@ -239,6 +245,7 @@ class MainEngine:
|
||||
if gateway:
|
||||
return gateway.send_order(req)
|
||||
else:
|
||||
self.write_error(f'发送委托时,找不到{gateway_name}')
|
||||
return ""
|
||||
|
||||
def cancel_order(self, req: CancelRequest, gateway_name: str) -> bool:
|
||||
@ -253,6 +260,8 @@ class MainEngine:
|
||||
gateway = self.get_gateway(gateway_name)
|
||||
if gateway:
|
||||
return gateway.cancel_order(req)
|
||||
else:
|
||||
self.write_error(f'撤单时,找不到{gateway_name}')
|
||||
return False
|
||||
|
||||
def send_orders(self, reqs: Sequence[OrderRequest], gateway_name: str) -> List[str]:
|
||||
@ -263,6 +272,7 @@ class MainEngine:
|
||||
if gateway:
|
||||
return gateway.send_orders(reqs)
|
||||
else:
|
||||
self.write_error(f'批量发单时,找不到{gateway_name}')
|
||||
return ["" for req in reqs]
|
||||
|
||||
def cancel_orders(self, reqs: Sequence[CancelRequest], gateway_name: str) -> None:
|
||||
@ -271,6 +281,8 @@ class MainEngine:
|
||||
gateway = self.get_gateway(gateway_name)
|
||||
if gateway:
|
||||
gateway.cancel_orders(reqs)
|
||||
else:
|
||||
self.write_error(f'批量撤单时,找不到{gateway_name}')
|
||||
|
||||
def query_history(self, req: HistoryRequest, gateway_name: str) -> Optional[List[BarData]]:
|
||||
"""
|
||||
@ -280,7 +292,7 @@ class MainEngine:
|
||||
if gateway:
|
||||
return gateway.query_history(req)
|
||||
else:
|
||||
self.write_error(f'网关为空,请检查合约得网关是否与连接得网关一致')
|
||||
self.write_error(f'找不到网关{gateway_name},请检查合约得网关是否与连接得网关一致')
|
||||
return None
|
||||
|
||||
def close(self) -> None:
|
||||
|
@ -135,6 +135,7 @@ class OrderData(BaseData):
|
||||
symbol: str
|
||||
exchange: Exchange
|
||||
orderid: str
|
||||
name: str = ""
|
||||
sys_orderid: str = ""
|
||||
accountid: str = ""
|
||||
type: OrderType = OrderType.LIMIT
|
||||
@ -153,6 +154,8 @@ class OrderData(BaseData):
|
||||
self.vt_symbol = f"{self.symbol}.{self.exchange.value}"
|
||||
self.vt_orderid = f"{self.gateway_name}.{self.orderid}"
|
||||
self.vt_accountid = f"{self.gateway_name}.{self.accountid}"
|
||||
if len(self.name) == 0:
|
||||
self.name = self.vt_symbol
|
||||
|
||||
def is_active(self) -> bool:
|
||||
"""
|
||||
@ -184,6 +187,7 @@ class TradeData(BaseData):
|
||||
exchange: Exchange
|
||||
orderid: str
|
||||
tradeid: str
|
||||
name: str = ""
|
||||
sys_orderid: str = ""
|
||||
accountid: str = ""
|
||||
|
||||
@ -208,7 +212,8 @@ class TradeData(BaseData):
|
||||
self.vt_orderid = f"{self.gateway_name}.{self.orderid}"
|
||||
self.vt_tradeid = f"{self.gateway_name}.{self.tradeid}"
|
||||
self.vt_accountid = f"{self.gateway_name}.{self.accountid}"
|
||||
|
||||
if len(self.name) == 0:
|
||||
self.name = self.vt_symbol
|
||||
|
||||
@dataclass
|
||||
class PositionData(BaseData):
|
||||
|
@ -347,6 +347,9 @@ def get_csv_last_dt(file_name, dt_index=0, dt_format='%Y-%m-%d %H:%M:%S', line_l
|
||||
:param line_length: 行数据的长度
|
||||
:return: None,文件不存在,或者时间格式不正确
|
||||
"""
|
||||
if not os.path.exists(file_name):
|
||||
return False
|
||||
|
||||
with open(file_name, 'r') as f:
|
||||
f_size = os.path.getsize(file_name)
|
||||
if f_size < line_length:
|
||||
@ -1442,3 +1445,4 @@ def get_remote_file(remote_ip, remote_file_path, mode='rb'):
|
||||
except Exception as ex:
|
||||
print(u'打开远程目录异常:{}'.format(str(ex)))
|
||||
return None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user