添加新的数据结构类

This commit is contained in:
Porter
2025-09-20 10:00:37 +08:00
parent 272e2522ea
commit e84108cb80
2 changed files with 893 additions and 10 deletions
+3 -10
View File
@@ -32,18 +32,11 @@ class ChanLun():
time8h = 480
time12h = 720
time1d = 1440
def create_all_data(self, dataframe, ticker_indicator):
all_data = dict()
all_data['1m'] = dataframe
timeframes = [time1, time3, time5, time15]
def init_data(self, dataframe, ticker_indicator):
for timeframe in self.timeframes:
df = resample_to_interval(dataframe, ticker_indicator*self.times[timeframe])
all_data[timeframe] = df
return all_data
klu_list, klc_list, bi_list = self.get_list_by_time(dataframe, ticker_indicator, timeframe)
def calculate_bsp(self, dataframe, ticker_indicator):
klu1, klc1, bi1 = self.get_list_by_time(dataframe, self.time1)
klu3, klc3, bi3 = self.get_list_by_time(dataframe, self.time3)
klu5, klc5, bi5 = self.get_list_by_time(dataframe, self.time5)
klu15, klc15, bi15 = self.get_list_by_time(dataframe, self.time15)
return dataframe
def get_list_by_time(self, dataframe, ticker_indicator, time):
+890
View File
@@ -0,0 +1,890 @@
from datetime import timedelta
from pandas import DataFrame
from ChanEnum import Chan_FX_TYPE, Chan_KLINE_DIR, Chan_BI_DIR, Chan_SEG_DIR, Chan_ZS_DIR, Chan_BSP_DIR, Chan_BSP_TYPE, Chan_KLC_FX
from ChanKLU import ChanKLU
from ChanKLC import ChanKLC
from ChanBI import ChanBI
from ChanSBI import ChanSBI
from ChanSEG import ChanSEG
from ChanZS import ChanZS
from ChanBSP import ChanBSP
import talib.abstract as ta
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, date2num
import matplotlib.patches as patches
from technical.util import resample_to_interval
from decimal import Decimal
import xgboost as xgb
import numpy as np
from ChanMACD import ChanMACD
class TF_DF():
def __init__(self, timeframe, df, ticker_indicator):
self.timeframe = timeframe
self.dataframe = resample_to_interval(df, ticker_indicator*timeframe)
self.ticker_indicator = ticker_indicator
self.klu_list = []
self.klc_list = []
self.bi_list = []
self.zs_list = []
self.bsp_list = []
self.seg_list = []
self.init_TF_DF()
def init_TF_DF(self):
self.klu_list = self.cal_kl_data(self.dataframe)
self.klc_list = self.cal_klc_list(self.klu_list)
self.bi_list = self.cal_bi_list(self.klc_list)
self.seg_list = self.cal_seg_list(self.bi_list)
self.zs_list = self.cal_zs_list(self.bi_list, self.seg_list)
return True
def check_fx(self, klc):
if klc.pre and klc.next:
if klc.high > klc.pre.high and klc.high > klc.next.high:
if klc.pre.pre and klc.high > klc.pre.pre.high and klc.next.next and klc.high > klc.next.next.high:
if klc.pre.pre.pre and klc.high > klc.pre.pre.pre.high and klc.next.next.next and klc.high > klc.next.next.next.high:
if klc.macd > 0 and klc.macd > klc.signal and klc.signal > klc.macdhist:
klc.set_fx(Chan_FX_TYPE.TOP)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "TOP")
return Chan_FX_TYPE.TOP
elif klc.low < klc.pre.low and klc.low < klc.next.low:
if klc.pre.pre and klc.low < klc.pre.pre.low and klc.next.next and klc.low < klc.next.next.low:
if klc.pre.pre.pre and klc.low < klc.pre.pre.pre.low and klc.next.next.next and klc.low < klc.next.next.next.low:
if klc.macd < 0 and klc.macd < klc.signal and klc.signal < klc.macdhist:
klc.set_fx(Chan_FX_TYPE.BOTTOM)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time,klc.fx, "BOTTOM")
return Chan_FX_TYPE.BOTTOM
return Chan_FX_TYPE.UNKNOWN
def cal_kl_data(self, dataframe:DataFrame):
fields = "time,open,high,low,close,volume"
klu_list = []
last_klu = None
for i in range(0, len(dataframe)):
item = dataframe.iloc[i]
date = item['date']
o = item['open']
h = item['high']
l = item['low']
c = item['close']
v = item['volume']
#time_obj = date.fromtimestamp(date)
#date = date + timedelta(hours=8)
time_str = date.strftime('%Y-%m-%d %H:%M:%S')
item_data = [
time_str,
o,
h,
l,
c,
v
]
#klu = KLU(self.create_item_dict(item_data, GetColumnNameFromFieldList(fields)))
klu = ChanKLU(time_str, o, h, l, c, v)
#print(klu.time, klu.open, klu.high, klu.low, klu.close, klu.volume)
klu.set_idx(i)
klu_list.append(klu)
if last_klu:
last_klu.set_next(klu)
klu.set_pre(last_klu)
last_klu = klu
if 'macd' in item:
klu.set_indicators(item)
return klu_list
def cal_klc_list(self, klu_list):
klc_list = []
last_klu = None
macd = ChanMACD(klu_list)
klu_list = macd.cal_macd_state()
for klu in klu_list:
if len(klc_list) > 0:
last_klc = klc_list[-1]
included = last_klc.check_klu_included(klu)
if not included:
ddir = Chan_KLINE_DIR.DOWN
if last_klc.high < klu.high:
ddir = Chan_KLINE_DIR.UP
klc = ChanKLC(klu, index=len(klc_list), ddir=ddir)
klc_list.append(klc)
last_klc.set_next(klc)
klc.set_pre(last_klc)
last_klc.set_end_klu(last_klu)
klc.set_pre_fx()
else:
last_klc.add_klu(klu)
else:
ddir = Chan_KLINE_DIR.UP
if klu.open > klu.close:
ddir = Chan_KLINE_DIR.DOWN
klc = ChanKLC(klu, 0, ddir)
klc_list.append(klc)
last_klu = klu
return klc_list
def cal_seg_list(self, bi_list):
seg_list = []
up_bi_list = []
down_bi_list = []
last_up_bi = None
last_down_bi = None
last_up_sbi = None
last_down_sbi = None
last_seg = None
up_sbi_list = []
down_sbi_list = []
look_for_bottom = False
look_for_top = False
for bi in bi_list:
#print(len(up_sbi_list), len(down_sbi_list))
if len(seg_list) > 0:
# Last seg is up
if last_seg.dir == Chan_SEG_DIR.UP:
if bi.dir == Chan_BI_DIR.DOWN:
if len(down_sbi_list) > 1:
# Check down sbi inclusion
included = last_down_sbi.check_bi_included(bi)
if not included:
down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir)
last_down_sbi.set_next(down_sbi)
last_down_sbi.set_end_bi(last_down_bi)
down_sbi.set_pre(last_down_sbi)
down_sbi_list.append(down_sbi)
fx = last_down_sbi.check_fx()
# Found top
if fx == Chan_FX_TYPE.TOP:
if look_for_top:
seg_list[-2].set_sure(bi)
look_for_top = False
#print(bi.start_time, look_for_top, "UP 1")
# Has gap and search for bottom fx
if last_down_sbi.has_fx_gap:
look_for_bottom = True
last_seg.pre_set_end_bi(bi_list[last_down_sbi.start_bi.index - 1])
seg = ChanSEG(last_down_sbi.start_bi, len(seg_list), Chan_SEG_DIR.DOWN)
seg_list.append(seg)
last_seg.set_next(seg)
seg.set_pre(last_seg)
last_seg = seg
up_sbi_list = []
last_up_sbi = ChanSBI(last_up_bi, len(up_sbi_list), last_up_bi.dir)
up_sbi_list.append(last_up_sbi)
#up_sbi_list.append(last_up_sbi)
#print(last_up_bi.start_time, last_up_sbi.start_bi.start_time, "Reset up sbi list 1")
#print(bi.start_time, look_for_top, "UP 2")
# No gap end SEG
else:
if look_for_bottom:
look_for_bottom = False
last_seg.set_start_bi(last_down_sbi.start_bi)
seg_list[-2].set_end_bi(bi_list[last_down_sbi.start_bi.index - 1], bi)
up_sbi_list = []
last_up_sbi = ChanSBI(last_up_bi, len(up_sbi_list), last_up_bi.dir)
up_sbi_list.append(last_up_sbi)
last_seg.add_bi(bi)
#up_sbi_list.append(last_up_sbi)
#print(last_up_bi.start_time, last_up_sbi.start_bi.start_time, "Reset up sbi list 2")
#print(bi.start_time, look_for_top, "UP 3")
else:
last_seg.set_end_bi(bi_list[last_down_sbi.start_bi.index - 1], bi)
seg = ChanSEG(last_down_sbi.start_bi, len(seg_list), Chan_SEG_DIR.DOWN)
seg_list.append(seg)
last_seg.set_next(seg)
seg.set_pre(last_seg)
last_seg = seg
#print(last_down_sbi.end_bi.start_time, "Normal UP SEG", last_up_sbi.start_bi.start_time, bi.start_time)
#l_up_sbi = up_sbi_list[-1]
up_sbi_list = []
last_up_sbi = ChanSBI(last_up_bi, len(up_sbi_list), last_up_bi.dir)
up_sbi_list.append(last_up_sbi)
#up_sbi_list.append(last_up_sbi)
#print(last_up_bi.start_time, last_up_sbi.start_bi.start_time, "Reset up sbi list 3")
last_down_sbi = down_sbi
last_seg.add_bi(bi)
else:
if len(down_sbi_list) == 1:
included = last_down_sbi.check_bi_included(bi)
if not included:
down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir)
last_down_sbi.set_next(down_sbi)
last_down_sbi.set_end_bi(last_down_bi)
down_sbi.set_pre(last_down_sbi)
down_sbi_list.append(down_sbi)
last_down_sbi = down_sbi
#print(bi.start_time, look_for_top, "UP 4")
last_seg.add_bi(bi)
else:
last_down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir)
down_sbi_list.append(last_down_sbi)
last_seg.add_bi(bi)
#print(bi.start_time, look_for_top, "UP 5")
else:
if last_up_sbi:
included = last_up_sbi.check_bi_included(bi)
if not included:
up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir)
last_up_sbi.set_next(up_sbi)
last_up_sbi.set_end_bi(last_up_bi)
up_sbi.set_pre(last_up_sbi)
up_sbi_list.append(up_sbi)
last_up_sbi = up_sbi
#print(bi.start_time, look_for_top, "UP 6")
last_seg.add_bi(bi)
# Last seg is down
else:
if bi.dir == Chan_BI_DIR.UP:
if len(up_sbi_list) > 1:
# Check down sbi inclusion
included = last_up_sbi.check_bi_included(bi)
if not included:
up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir)
last_up_sbi.set_next(up_sbi)
last_up_sbi.set_end_bi(last_up_bi)
up_sbi.set_pre(last_up_sbi)
up_sbi_list.append(up_sbi)
fx = last_up_sbi.check_fx()
# Found bottom
if fx == Chan_FX_TYPE.BOTTOM:
if look_for_bottom:
seg_list[-2].set_sure(bi)
look_for_bottom = False
#print(bi.start_time, look_for_top, "DOWN 1")
# Has gap and search for bottom fx
if last_up_sbi.has_fx_gap:
look_for_top = True
last_seg.pre_set_end_bi(bi_list[last_up_sbi.start_bi.index - 1])
seg = ChanSEG(last_up_sbi.start_bi, len(seg_list), Chan_SEG_DIR.UP)
seg_list.append(seg)
last_seg.set_next(seg)
seg.set_pre(last_seg)
last_seg = seg
down_sbi_list = []
last_down_sbi = ChanSBI(last_down_bi, len(down_sbi_list), last_down_bi.dir)
down_sbi_list.append(last_down_sbi)
#down_sbi_list.append(last_down_sbi)
#print(last_down_bi.start_time, last_down_sbi.start_bi.start_time, "Reset down sbi list 1")
#print(bi.start_time, look_for_top, "DOWN 2")
# No gap end SEG
else:
if look_for_top:
look_for_top = False
last_seg.set_start_bi(last_up_sbi.start_bi)
seg_list[-2].set_end_bi(bi_list[last_up_sbi.start_bi.index - 1], bi)
down_sbi_list = []
last_down_sbi = ChanSBI(last_down_bi, len(down_sbi_list), last_down_bi.dir)
down_sbi_list.append(last_down_sbi)
last_seg.add_bi(bi)
#down_sbi_list.append(last_down_sbi)
#print(last_down_bi.start_time, last_down_sbi.start_bi.start_time, "Reset down sbi list 2")
#print(bi.start_time, look_for_top, "DOWN 3")
else:
last_seg.set_end_bi(bi_list[last_up_sbi.start_bi.index - 1], bi)
seg = ChanSEG(last_up_sbi.start_bi, len(seg_list), Chan_SEG_DIR.UP)
#print(last_up_sbi.start_bi.start_time)
last_seg.set_next(seg)
seg.set_pre(last_seg)
seg_list.append(seg)
last_seg = seg
#print(last_up_sbi.end_bi.start_time, "Normal DOWN SEG", last_down_sbi.start_bi.start_time, bi.start_time)
down_sbi_list = []
last_down_sbi = ChanSBI(last_down_bi, len(down_sbi_list), last_down_bi.dir)
down_sbi_list.append(last_down_sbi)
#down_sbi_list.append(last_down_sbi)
#print(last_down_bi.start_time, last_down_sbi.start_bi.start_time, "Reset down sbi list 3")
last_up_sbi = up_sbi
last_seg.add_bi(bi)
else:
if len(up_sbi_list) == 1:
#last_up_sbi = up_sbi_list[-1]
included = last_up_sbi.check_bi_included(bi)
if not included:
up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir)
last_up_sbi.set_next(up_sbi)
last_up_sbi.set_end_bi(last_up_bi)
up_sbi.set_pre(last_up_sbi)
up_sbi_list.append(up_sbi)
last_up_sbi = up_sbi
last_seg.add_bi(bi)
#print(bi.start_time, look_for_top, "DOWN 4")
else:
last_up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir)
up_sbi_list.append(last_up_sbi)
last_seg.add_bi(bi)
#print(bi.start_time, look_for_top, "DOWN 5")
else:
if last_down_sbi:
included = last_down_sbi.check_bi_included(bi)
if not included:
down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir)
last_down_sbi.set_next(down_sbi)
last_down_sbi.set_end_bi(last_down_bi)
down_sbi.set_pre(last_down_sbi)
down_sbi_list.append(down_sbi)
last_down_sbi = down_sbi
last_seg.add_bi(bi)
#print(bi.start_time, look_for_top, look_for_bottom, "DOWN 6")
# len(seg_list) = 0
else:
if bi.check_overlap():
if bi.dir == Chan_BI_DIR.UP:
seg = ChanSEG(bi, len(seg_list), Chan_SEG_DIR.UP)
last_up_bi = bi
last_up_sbi = ChanSBI(bi, len(up_sbi_list), bi.dir)
seg_list.append(seg)
last_seg = seg
#print(bi.start_time, 'Create first UP SEG')
else:
seg = ChanSEG(bi, len(seg_list), Chan_SEG_DIR.DOWN)
last_down_bi = bi
last_down_sbi = ChanSBI(bi, len(down_sbi_list), bi.dir)
seg_list.append(seg)
last_seg = seg
#print(bi.start_time, 'Create first DOWN SEG')
if bi.dir == Chan_BI_DIR.UP:
last_up_bi = bi
up_bi_list.append(bi)
else:
last_down_bi = bi
down_bi_list.append(bi)
"""
if len(seg_list) > 1:
seg = seg_list[-1]
last_seg = seg_list[-2]
last_seg_bi = last_seg.bi_list[-3]
bi_index = seg.start_bi.index
for i in range(bi_index, len(bi_list) - 1):
# last seg is down
if seg.dir == Chan_SEG_DIR.UP:
if bi_list[i].dir == Chan_BI_DIR.UP:
last_seg_peak = last_seg_bi.high
if bi_list[i].high > last_seg_peak:
# The confirmed
print("Last UP seg is broken, create a new seg. 1")
seg.pre_set_end_bi(bi_list[i])
seg = ChanSEG(bi_list[i+1], len(seg_list), Chan_SEG_DIR.DOWN)
seg_list.append(seg)
last_seg = seg_list[-2]
if len(last_seg.bi_list) > 3:
last_seg_bi = last_seg.bi_list[-3]
else:
if bi_list[i].dir == Chan_BI_DIR.DOWN:
last_seg_peak = last_seg_bi.low
if bi_list[i].low < last_seg_peak:
print("Last DOWN seg is broken, create a new seg. 1")
seg.pre_set_end_bi(bi_list[i])
seg = ChanSEG(bi_list[i+1], len(seg_list), Chan_SEG_DIR.UP)
seg_list.append(seg)
last_seg = seg_list[-2]
if len(last_seg.bi_list) > 3:
last_seg_bi = last_seg.bi_list[-3]
else:
if len(seg_list) == 1:
last_seg = seg_list[-1]
bi_index = last_seg.bi_list[0].index
for i in range(bi_index, len(bi_list) - 1):
if i > bi_index + 2:
last_seg_peak = bi_list[i-2].high
# last seg is down
if last_seg.dir == Chan_SEG_DIR.DOWN:
if bi_list[i].dir == Chan_BI_DIR.UP:
if bi_list[i].high > last_seg_peak:
print("Last seg is broken, create a new seg. 2")
last_seg.pre_set_end_bi(bi_list[i-1])
seg = ChanSEG(bi_list[i], len(seg_list), Chan_SEG_DIR.UP)
seg_list.append(seg)
last_seg = seg
last_seg_bi = bi_list[i]
break
"""
return seg_list
def cal_bi_list(self, klc_list):
bi_list = []
last_top = None
last_bottom = None
for klc in klc_list:
fx = self.check_fx(klc)
# Do nothing
if fx == Chan_FX_TYPE.UNKNOWN:
continue
if len(bi_list) > 0 and klc.end_klu:
last_bi = bi_list[-1]
#print(klc.start_time, last_bi.start_time, last_bi.end_time, last_bi.dir, last_bi.high, last_bi.low, last_bottom.end_time, "last bi")
if last_top and last_bi.dir == Chan_BI_DIR.DOWN:
if last_bottom and klc.high > last_bi.high:
last_bi.set_end_klc(last_bottom, klc)
bi = ChanBI(last_bottom, len(bi_list), Chan_BI_DIR.UP)
#klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM7)
#klc.bb_out = True
last_bi.set_next(bi)
bi.set_pre(last_bi)
for klc_index in range(last_bi.end_klc.index, len(klc_list)):
bi.add_klc(klc_list[klc_index])
bi_list.append(bi)
last_top = klc
klc.set_bi(bi)
#print(klc.start_time, bi.start_time, bi.end_time, bi.dir, bi.high, bi.low, bi.is_sure)
else:
if last_bottom and last_bi.dir == Chan_BI_DIR.UP:
if last_top and klc.low < last_bi.low:
last_bi.set_end_klc(last_top, klc)
bi = ChanBI(last_top, len(bi_list), Chan_BI_DIR.DOWN)
#klc.set_klc_fx_type(Chan_KLC_FX.TOP6)
#klc.bb_out = True
last_bi.set_next(bi)
bi.set_pre(last_bi)
for klc_index in range(last_bi.end_klc.index, len(klc_list)):
bi.add_klc(klc_list[klc_index])
bi_list.append(bi)
last_bottom = klc
klc.set_bi(bi)
#print(klc.start_time, bi.start_time, bi.end_time, bi.dir, bi.high, bi.low, bi.is_sure)
else:
if fx == Chan_FX_TYPE.TOP:
if last_top:
if last_bottom:
#print(klc.start_time, last_bottom.start_time, last_top.start_time)
if last_bottom.index < last_top.index:
# Second top lower to be second sell point
if last_top.high > klc.high:
#klc.set_fx(Chan_FX_TYPE.TT)
#klc.set_state("20")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#klc.set_klc_fx_type(Chan_KLC_FX.TOP3)
klc.set_last_top_klu(last_top)
#print(klc.start_time, klc.fx, "二类卖点Sell 1")
else:
# A new top found
#last_top.set_fx(Chan_FX_TYPE.UNKNOWN)
last_top = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 1")
klc.set_klc_fx_type(Chan_KLC_FX.TOP1)
#print(klc.end_time, klc.fx, "一类卖点Sell 1")
#klc.set_fx(fx)
#klc.set_state("10")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
# 不满足结合律的分型
if last_bottom.index + 4 > klc.index:
if last_top.high > klc.high:
#print(klc.start_time, klc.fx, "二类卖点Sell 1")
#klc.set_fx(Chan_FX_TYPE.PTOP)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
# New TOP Found replace last top
else:
if last_top.index + 4 < klc.index and len(bi_list) > 1:
pre_last_bi = bi_list[-2]
last_bi = bi_list[-1]
if pre_last_bi.is_sure and not last_bi.is_sure and pre_last_bi.dir == Chan_BI_DIR.UP and False:
pre_last_bi.update_bi(klc)
bi_list.remove(last_bi)
pre_last_bi.set_next(None)
#last_top.set_fx(Chan_FX_TYPE.PTOP)
last_top = klc
last_bottom = pre_last_bi.start_klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Bottom Change 1")
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
#print(klc.start_time, last_bi.start_klc.start_time, "New TOP Found reset last bi")
#klc.set_state("10")
#print(klc.start_time, klc.fx, "笔卖点Sell 1")
###klc.set_klc_fx_type(Chan_KLC_FX.TOP2) # when bi is down but the fx is top
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
klc.set_fx(Chan_FX_TYPE.PTOP)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "无效分型")
# 满足结合律
else:
# New Temp TOP and last bottom confirmed ***** confirm last down bi(last bottom and last top)
last_bi = bi_list[-1]
if not last_bi.is_sure:
last_bi.set_end_klc(last_bottom, klc)
bi = ChanBI(last_bottom, len(bi_list), Chan_BI_DIR.UP)
#klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM7)
#klc.bb_out = True
last_bi.set_next(bi)
bi.set_pre(last_bi)
bi.add_klc(klc)
bi_list.append(bi)
last_top = klc
#print(klc.end_time, klc.fx, bi_list[-1].dir, "Last Top Change 2")
klc.set_klc_fx_type(Chan_KLC_FX.TOP2)
#klc.set_state('30')
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, last_bottom.start_time, "Normal TOP Found, Confirm down bi 4")
#print(klc.start_time, klc.fx, "笔卖点Sell 2")
# last bottom = None
else:
if last_top.high < klc.high:
last_bi = bi_list[-1]
last_bi.set_start_klc(klc, Chan_BI_DIR.DOWN)
#last_top.set_fx(Chan_FX_TYPE.UNKNOWN)
last_top = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 3")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "笔卖点Sell 3")
else:
klc.set_fx(Chan_FX_TYPE.TT)
#klc.set_state('20')
#print(klc.start_time, klc.fx, "二类卖点Sell 2")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
if last_bottom:
# 不满足结合律的分型
if last_bottom.index + 4 > klc.index:
#klc.set_fx(Chan_FX_TYPE.PTOP)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "中枢卖点Sell 1")
else:
# First temp top and last bottom confirmed
last_top = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 4")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "一类卖点Sell 1")
# Last top = None, last bottom = None, create first down bi
else:
# First temp top
last_top = klc
bi = ChanBI(klc, len(bi_list), Chan_BI_DIR.DOWN)
#klc.set_klc_fx_type(Chan_KLC_FX.TOP6)
#klc.bb_out = True
bi_list.append(bi)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 5")
#print(klc.start_time, 'Create first top')
#print(klc.start_time, klc.fx, "笔卖点Sell 1")
#klc.fx = Bottom ========================
else:
if last_bottom:
if last_top:
# Bottom after top and find a new bottom
if last_top.index < last_bottom.index:
# Second bottom uppper to be second buy point and confirm last bi
if last_bottom.low < klc.low:
#klc.set_fx(Chan_FX_TYPE.BB)
#klc.set_state("-20")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM3)
klc.set_last_bottom_klc(last_bottom)
#print(last_bottom.start_time, last_bottom.end_time, "--------------------------------1")
#print(klc.start_time, klc.fx, "二类买点Buy 1")
else:
# A new bottom found
#last_bottom.set_fx(Chan_FX_TYPE.UNKNOWN)
last_bottom = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 1")
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM1)
#print(klc.start_time, klc.fx, "一类买点Buy 1")
#klc.set_state("-10")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
# 不满足结合律的分型
if last_top.index + 4 > klc.index:
if last_bottom.low < klc.low:
#klc.set_fx(Chan_FX_TYPE.PBOTTOM)
#klc.set_fx(Chan_FX_TYPE.BB)
#klc.set_state("-100")
#print(klc.start_time, klc.fx, "中枢买点Buy 1")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
# Found new bottom
else:
if last_bottom.index + 4 < klc.index and len(bi_list) > 1:
pre_last_bi = bi_list[-2]
last_bi = bi_list[-1]
if pre_last_bi.is_sure and not last_bi.is_sure and pre_last_bi.dir == Chan_BI_DIR.DOWN and False:
pre_last_bi.update_bi(klc)
bi_list.remove(last_bi)
pre_last_bi.set_next(None)
#last_bottom.set_fx(Chan_FX_TYPE.PBOTTOM)
last_bottom = klc
last_top = pre_last_bi.start_klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Bottom Change 2")
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2)
#print(klc.start_time, last_bi.start_klc.start_time, "New BOTTOM Found reset last bi")
#klc.set_state("-10")
#print(klc.start_time, klc.fx, "笔买点Buy 1")
###klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2) # when bi is up but the fx is bottom
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
else:
#klc.set_fx(Chan_FX_TYPE.UNKNOWN)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "无效分型")
# 满足结合律的分型
else:
# New Temp Bottom and last top confirmed ***** confirm last up bi(last bottom and last top)
last_bi = bi_list[-1]
if not last_bi.is_sure:
last_bi.set_end_klc(last_top, klc)
bi = ChanBI(last_top, len(bi_list), Chan_BI_DIR.DOWN)
#klc.set_klc_fx_type(Chan_KLC_FX.TOP6)
#klc.bb_out = True
last_bi.set_next(bi)
bi.set_pre(last_bi)
bi.add_klc(klc)
bi_list.append(bi)
last_bottom = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 2")
klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM2)
#klc.set_state('-30')
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "笔买点Buy 2")
#print(klc.start_time, last_top.start_time, "Normal Bottom Found, Confirm up bi 6")
# last_top = None
else:
if last_bottom.low > klc.low:
last_bi = bi_list[-1]
last_bi.set_start_klc(klc, Chan_BI_DIR.UP)
#last_bottom.set_fx(Chan_FX_TYPE.UNKNOWN)
last_bottom = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 3")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "笔买点Buy 3")
else:
klc.set_fx(Chan_FX_TYPE.BB)
#klc.set_state('-20')
#print(klc.start_time, klc.fx, "二类买点Buy 2")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
# last_bottom = None
else:
if last_top:
# 不满足结合律的分型
if last_top.index + 4 > klc.index:
#klc.set_fx(Chan_FX_TYPE.PBOTTOM)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "中枢买点Buy 1")
else:
# First temp bottom and last top confirmed
last_bottom = klc
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 4")
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, "一类买点Buy 1")
# Last top = None, last bottom = None, create first up bi
else:
# First temp bottom and no top yet
last_bottom = klc
bi = ChanBI(klc, len(bi_list), Chan_BI_DIR.UP)
#klc.set_klc_fx_type(Chan_KLC_FX.BOTTOM7)
#klc.bb_out = True
bi_list.append(bi)
bi_list[-1].add_klc(klc)
klc.set_bi(bi_list[-1])
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Bottom Change 5")
#print(klc.start_time, klc.fx, "笔买点Buy 4")
#if klc.fx != Chan_FX_TYPE.UNKNOWN:
#print(klc.start_time, klc.fx, klc.index)
"""
for klc in klc_list:
if klc.fx == Chan_FX_TYPE.TOP:
klc.state = "10"
#print(klc.time, klc.state)
if klc.fx == Chan_FX_TYPE.BOTTOM:
klc.state = "-10"
#print(klc.time, klc.state)
"""
#for index in range(0, 10):
#print(bi_list[index].start_time, bi_list[index].start_klc.start_time, bi_list[index].dir)
return bi_list
def get_decimal(self, value):
return Decimal("{:.2f}".format(value))
def cal_zs_list(self, bi_list, seg_list):
zs_list = []
bsp_list = []
if len(seg_list) > 3:
last_zs = None
first_bi_out = None
in_again = False
bi_out_count = 0
zs_count = 0
for seg in seg_list:
# No zs or Last ZS is completed
if len(zs_list) == 0 or (last_zs and last_zs.is_sure):
# Has three completed segments
if seg.next and seg.next.next:
if seg.next.next.is_sure:
zg = min(seg.high, seg.next.high, seg.next.next.high)
zd = max(seg.low, seg.next.low, seg.next.next.low)
gg = max(seg.high, seg.next.high, seg.next.next.high)
dd = min(seg.low, seg.next.low, seg.next.next.low)
ddir = Chan_ZS_DIR.UP
ddir = None
if last_zs:
if zg < last_zs.zd:
ddir = Chan_ZS_DIR.DOWN
else:
if zd > last_zs.zg:
ddir = Chan_ZS_DIR.UP
else:
ddir = None
else:
if seg.dir == Chan_SEG_DIR.UP:
ddir = Chan_ZS_DIR.DOWN
else:
ddir = Chan_ZS_DIR.UP
if (seg.dir == Chan_SEG_DIR.DOWN and ddir == Chan_ZS_DIR.DOWN) or (seg.dir == Chan_SEG_DIR.UP and ddir == Chan_ZS_DIR.UP):
ddir = None
if ddir and zg > zd:
# New ZS
zs = ChanZS(seg, len(zs_list), ddir)
zs.set_zg(zg)
zs.set_zd(zd)
zs.set_gg(gg)
zs.set_dd(dd)
if last_zs:
last_zs.set_next(zs)
zs.set_pre(last_zs)
zs_list.append(zs)
if last_zs and last_zs.dir == zs.dir:
zs_count += 1
else:
zs_count = 1
last_zs = zs
# Last ZS is not completed
else:
# Last ZS is not completed
if last_zs and not last_zs.is_sure:
if first_bi_out:
# SEG is not in ZS
if seg.is_sure:
if ((seg.low > last_zs.zg and seg.high > last_zs.zg) or (seg.high < last_zs.zd and seg.low < last_zs.zd)):
last_zs.set_end_klc(last_zs.last_bi_in.end_klc, seg.sure_time, bi_out_count, seg)
bi_out_count = 0
#print(seg.start_bi.start_klc.start_time)
first_bi_out = None
# Last ZS is completed and look for new ZS
if seg.next and seg.next.next:
if seg.next.next.is_sure:
zg = min(seg.high, seg.next.high, seg.next.next.high)
zd = max(seg.low, seg.next.low, seg.next.next.low)
gg = max(seg.high, seg.next.high, seg.next.next.high)
dd = min(seg.low, seg.next.low, seg.next.next.low)
ddir = None
if last_zs:
if zg < last_zs.zd:
ddir = Chan_ZS_DIR.DOWN
else:
if zd > last_zs.zg:
ddir = Chan_ZS_DIR.UP
else:
ddir = None
else:
if seg.dir == Chan_SEG_DIR.UP:
ddir = Chan_ZS_DIR.DOWN
else:
ddir = Chan_ZS_DIR.UP
if (seg.dir == Chan_SEG_DIR.DOWN and ddir == Chan_ZS_DIR.DOWN) or (seg.dir == Chan_SEG_DIR.UP and ddir == Chan_ZS_DIR.UP):
ddir = None
if ddir and zg > zd:
# New ZS
zs = ChanZS(seg, len(zs_list), ddir)
zs.set_zg(zg)
zs.set_zd(zd)
zs.set_gg(gg)
zs.set_dd(dd)
last_zs.set_next(zs)
zs.set_pre(last_zs)
zs_list.append(zs)
if last_zs and last_zs.dir == zs.dir:
zs_count += 1
else:
zs_count = 1
last_zs = zs
# Last SEG is in ZS
else:
# SEG is inside ZS
if seg.end_bi:
for index in range(seg.start_bi.index, seg.end_bi.index+1):
bi = bi_list[index]
if (bi.high >= last_zs.zd and bi.high <= last_zs.zg) or (bi.low >= last_zs.zd and bi.low <= last_zs.zg) or (bi.high >= last_zs.zg and bi.low <= last_zs.zd):
in_again = True
last_zs.set_bi_out(None, None)
last_zs.set_last_bi_in(None)
last_zs.set_end_seg(None)
first_bi_out = None
#print("Bi in again 3", bi.start_klc.start_time)
if in_again and (bi.low > last_zs.zg or bi.high < last_zs.zd):
last_zs.set_bi_out(bi, seg)
last_zs.set_last_bi_in(bi_list[index - 1])
#last_zs.set_end_seg(seg.next.next)
bi_out_count += 1
first_bi_out = bi
if (bi.dir == Chan_BI_DIR.UP and seg.dir == Chan_SEG_DIR.DOWN) or (bi.dir == Chan_BI_DIR.DOWN and seg.dir == Chan_SEG_DIR.UP):
bsp = ChanBSP(first_bi_out, len(bsp_list), Chan_BSP_TYPE.T3, Chan_BSP_DIR.BUY if first_bi_out.dir == Chan_BI_DIR.DOWN else Chan_BSP_DIR.SELL, first_bi_out.sure_time, zs_count, zs, seg)
bsp_list.append(bsp)
#print("First bi out 3", first_bi_out.start_klc.start_time)
in_again = False
""""
if first_bi_out:
if seg.dir == Chan_SEG_DIR.UP and bi.dir == Chan_BI_DIR.UP:
#print(bi.start_klc.start_time, bi.high, seg.high)
if bi.high == seg.high:
bsp = ChanBSP(bi, len(bsp_list), Chan_BSP_TYPE.T3E, Chan_BSP_DIR.SELL if bi.dir == Chan_BI_DIR.DOWN else Chan_BSP_DIR.BUY, bi.sure_time, zs_count, zs, seg)
bsp_list.append(bsp)
else:
if seg.dir == Chan_SEG_DIR.DOWN and bi.dir == Chan_BI_DIR.DOWN:
if bi.low == seg.low:
bsp = ChanBSP(bi, len(bsp_list), Chan_BSP_TYPE.T3E, Chan_BSP_DIR.BUY if bi.dir == Chan_BI_DIR.DOWN else Chan_BSP_DIR.SELL, bi.sure_time, zs_count, zs, seg)
bsp_list.append(bsp)
"""
else:
# SEG in ZS and not out and find first bi out
if seg.end_bi:
for index in range(seg.start_bi.index, seg.end_bi.index+1):
bi = bi_list[index]
if (bi.high >= last_zs.zd and bi.high <= last_zs.zg) or (bi.low >= last_zs.zd and bi.low <= last_zs.zg) or (bi.high >= last_zs.zg and bi.low <= last_zs.zd):
in_again = True
last_zs.set_bi_out(None, None)
last_zs.set_last_bi_in(None)
last_zs.set_end_seg(None)
first_bi_out = None
#print("Bi in again 4", bi.start_klc.start_time)
if in_again and (bi.low > last_zs.zg or bi.high < last_zs.zd):
last_zs.set_bi_out(bi, seg)
last_zs.set_last_bi_in(bi_list[index - 1])
#last_zs.set_end_seg(seg.next.next)
bi_out_count += 1
first_bi_out = bi
if (bi.dir == Chan_BI_DIR.UP and seg.dir == Chan_SEG_DIR.DOWN) or (bi.dir == Chan_BI_DIR.DOWN and seg.dir == Chan_SEG_DIR.UP):
bsp = ChanBSP(first_bi_out, len(bsp_list), Chan_BSP_TYPE.T3, Chan_BSP_DIR.BUY if first_bi_out.dir == Chan_BI_DIR.DOWN else Chan_BSP_DIR.SELL, first_bi_out.sure_time, zs_count, zs, seg)
bsp_list.append(bsp)
#print("First bi out 4", first_bi_out.start_klc.start_time)
in_again = False
if first_bi_out:
if seg.dir == Chan_SEG_DIR.UP and bi.dir == Chan_BI_DIR.UP:
#print(bi.start_klc.start_time, bi.high, seg.high)
if bi.high == seg.high:
bsp = ChanBSP(bi, len(bsp_list), Chan_BSP_TYPE.T3E, Chan_BSP_DIR.SELL if bi.dir == Chan_BI_DIR.DOWN else Chan_BSP_DIR.BUY, bi.sure_time, zs_count, zs, seg)
bsp_list.append(bsp)
else:
if seg.dir == Chan_SEG_DIR.DOWN and bi.dir == Chan_BI_DIR.DOWN:
if bi.low == seg.low:
bsp = ChanBSP(bi, len(bsp_list), Chan_BSP_TYPE.T3E, Chan_BSP_DIR.BUY if bi.dir == Chan_BI_DIR.DOWN else Chan_BSP_DIR.SELL, bi.sure_time, zs_count, zs, seg)
bsp_list.append(bsp)
#self.print_zs(zs_list)
return zs_list