增加了新的笔中枢,但是还是线段的好些

This commit is contained in:
jackyu66git
2026-04-02 15:29:15 +08:00
parent 6538982d24
commit ea317fb6f9
7 changed files with 187 additions and 31 deletions
+6 -3
View File
@@ -21,11 +21,11 @@ class ChanBIZS():
self.sure_time = None
self.end_klc = None
self.zs_type = Chan_ZS_TYPE.NORMAL
def set_end_bi(self, end_bi, sure_bi):
def set_end_bi(self, end_bi, sure_time):
self.end_bi = end_bi
self.set_end_time(end_bi.end_klc.end_time)
self.is_sure = True
self.sure_time = sure_bi.sure_time
self.sure_time = sure_time
#print(self.start_time, self.is_sure, len(self.bi_list), self.dir, self.zs_type)
def set_end_time(self, end_time):
self.end_time = end_time
@@ -41,7 +41,10 @@ class ChanBIZS():
if bi:
self.bi_list.append(bi)
self.classify_zs()
def set_pre(self, pre):
self.pre = pre
def set_next(self, next):
self.next = next
def classify_zs(self):
"""
根据中枢内笔的高低点变化趋势,对中枢进行分类
+2 -2
View File
@@ -370,7 +370,7 @@ class ChanKLC():
else:
high = last_top.high
low = self.low
last_top.fx_box = Chan_FX_Box.Chan_FX_Box(last_top.pre.end_time, self.end_time, high, low)
last_top.fx_box = Chan_FX_Box.Chan_FX_Box(last_top.pre.start_time, self.end_time, high, low)
#print(self.end_time, "fx_confirmed new box top")
elif self.in_fx == False and last_bottom.fx_confirmed == False:
pre = last_bottom.pre
@@ -382,7 +382,7 @@ class ChanKLC():
else:
high = self.high
low = last_bottom.low
last_bottom.fx_box = Chan_FX_Box.Chan_FX_Box(last_bottom.pre.end_time, self.end_time, high, low)
last_bottom.fx_box = Chan_FX_Box.Chan_FX_Box(last_bottom.pre.start_time, self.end_time, high, low)
#print(self.end_time, "fx_confirmed new box bottom")
def add_klu(self, klu):
self.klu_list.append(klu)
+6 -2
View File
@@ -233,14 +233,18 @@ class ChanKLU:
self.near0_return = 0
elif self.close > self.ema52 and self.high > self.ema52 and self.low < self.ema52:
self.near0_return = 0
# 向上穿越EMA52 7
if self.close > self.ema52 and self.open < self.ema52:
self.near0_return = 7
self.near0_return = 0
# 向下穿越EMA52 8
elif self.close < self.ema52 and self.open > self.ema52:
self.near0_return = 8
self.near0_return = 0
if self.pre.near0_return == 7:
# 向上穿越后的一根价格再EMA52上方 9
if self.low > self.ema52 and self.close > self.open:
self.near0_return = 9
if self.pre.near0_return == 8:
# 向下穿越后的一根价格再EMA52下方 10
if self.high < self.ema52 and self.close < self.open:
self.near0_return = 10
# CROSS0 仅以 Signal 穿越零轴判定
+3
View File
@@ -163,6 +163,9 @@ class ChanLun():
return self.tf_df.get_zs_list(bi_list, seg_list)
def cal_bi_zs(self, seg_list):
return self.tf_df.cal_bi_zs(seg_list)
def cal_bi_zs_list(self, bi_list):
#return self.tf_df.cal_bi_zs(bi_list)
return self.tf_df.cal_bi_zs_list(bi_list)
def get_decimal(self, value):
return Decimal("{:.2f}".format(value))
def get_klc_list(self, klu_list):
+4 -4
View File
@@ -113,7 +113,7 @@ class ChanSEG():
else:
if bi.index > last_zs.bi_list[-1].index and bi.dir == Chan_BI_DIR.DOWN and bi.is_sure:
if bi.low > last_zs.zg or bi.high < last_zs.zd:
last_zs.set_end_bi(last_zs.bi_list[-1], bi)
last_zs.set_end_bi(last_zs.bi_list[-1], last_zs.bi_list[-1].sure_time)
if bi.next and bi.next.next and bi.next.next.is_sure and bi.next.next.index <= self.bi_list[-1].index and bi.check_bi_zs_overlap() and bi.dir == Chan_BI_DIR.DOWN:
zg = min(bi.high, bi.next.high, bi.next.next.high)
zd = max(bi.low, bi.next.low, bi.next.next.low)
@@ -133,7 +133,7 @@ class ChanSEG():
last_zs.add_bi(bi)
if index == len(self.bi_list) - 1 and last_zs and not last_zs.is_sure:
#print(bi.start_time, "BI", last_zs.is_sure)
last_zs.set_end_bi(last_zs.bi_list[-1], last_zs.bi_list[-1])
last_zs.set_end_bi(last_zs.bi_list[-1], last_zs.bi_list[-1].sure_time)
else:
for index in range(1, len(self.bi_list)):
bi = self.bi_list[index]
@@ -155,7 +155,7 @@ class ChanSEG():
else:
if bi.index > last_zs.bi_list[-1].index and bi.dir == Chan_BI_DIR.UP and bi.is_sure:
if bi.low > last_zs.zg or bi.high < last_zs.zd:
last_zs.set_end_bi(last_zs.bi_list[-1], bi)
last_zs.set_end_bi(last_zs.bi_list[-1], last_zs.bi_list[-1].sure_time)
if bi.next and bi.next.next and bi.next.next.is_sure and bi.next.next.index <= self.bi_list[-1].index and bi.check_bi_zs_overlap() and bi.dir == Chan_BI_DIR.UP:
zg = min(bi.high, bi.next.high, bi.next.next.high)
zd = max(bi.low, bi.next.low, bi.next.next.low)
@@ -175,7 +175,7 @@ class ChanSEG():
last_zs.add_bi(bi)
if index == len(self.bi_list) - 1 and last_zs and not last_zs.is_sure:
#print(bi.start_time, "BI", last_zs.is_sure)
last_zs.set_end_bi(last_zs.bi_list[-1], last_zs.bi_list[-1])
last_zs.set_end_bi(last_zs.bi_list[-1], last_zs.bi_list[-1].sure_time)
#print(self.start_time, len(zs_list))
#print(self.bi_list[-1].end_time, "end_bi")
+157 -9
View File
@@ -7,6 +7,7 @@ from ChanBI import ChanBI
from ChanSBI import ChanSBI
from ChanSEG import ChanSEG
from ChanZS import ChanZS, ChanZS_Big
from ChanBIZS import ChanBIZS
from ChanBSP import ChanBSP
import talib.abstract as ta
import pandas as pd
@@ -72,8 +73,8 @@ class TF_DF():
return self.klc_list[-2]
return None
def add_indicators(self, df):
fast = 12
slow = 26
fast = 26
slow = 52
period = 9
macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period)
bb365 = ta.BBANDS(df, timeperiod=365, nbdevup=3.0, nbdevdn=3.0, matype=0)
@@ -175,6 +176,23 @@ class TF_DF():
klu_state_list.append("0")
return klu_state_list
def check_fx(self, klc):
if klc.pre and klc.next:
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
if klc.pre.pre and klc.next.next:
if klc.high > klc.pre.pre.high and klc.high > klc.next.next.high:
#if (klc.close > klc.ema52 or klc.next.close > klc.next.ema52) and klc.macd > 0:
klc.set_fx(Chan_FX_TYPE.TOP)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time, klc.macd, klc.state, klc.fx, "TOP")
return Chan_FX_TYPE.TOP
elif klc.low < klc.pre.low and klc.low < klc.next.low and klc.high < klc.pre.high and klc.high < klc.next.high:
#if (klc.close < klc.ema52 or klc.next.close < klc.next.ema52) and klc.macd < 0:
if klc.pre.pre and klc.next.next:
if klc.low < klc.pre.pre.low and klc.low < klc.next.next.low:
klc.set_fx(Chan_FX_TYPE.BOTTOM)
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time, klc.macd, klc.state, klc.fx, "BOTTOM")
return Chan_FX_TYPE.BOTTOM
return Chan_FX_TYPE.UNKNOWN
def check_fx1(self, klc):
if klc.pre and klc.next:
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
#if (klc.close > klc.ema52 or klc.next.close > klc.next.ema52) and klc.macd > 0:
@@ -903,7 +921,7 @@ class TF_DF():
last_seg_bi = bi_list[i]
break
"""
self.cal_bi_zs(seg_list)
#self.cal_bi_zs(seg_list)
return seg_list
def cal_bi_list(self, klc_list):
@@ -917,11 +935,11 @@ class TF_DF():
klc.check_klc_state(last_fx_klc)
klc.check_fx_confirmed(last_top, last_bottom)
fx = self.check_fx(klc)
if fx == Chan_FX_TYPE.TOP and False:
if fx == Chan_FX_TYPE.TOP:
if last_bottom:
if self.check_top_fx(last_bottom, klc) == False:
fx = Chan_FX_TYPE.UNKNOWN
if fx == Chan_FX_TYPE.BOTTOM and False:
if fx == Chan_FX_TYPE.BOTTOM:
if last_top:
if self.check_bottom_fx(last_top, klc) == False:
#print(klc.end_time, last_top.end_time, "---")
@@ -1250,7 +1268,137 @@ class TF_DF():
for seg in seg_list:
zs_list = seg.cal_bi_zs()
if len(zs_list) > 0:
bi_zs_list.append(zs_list)
bi_zs_list = list(bi_zs_list) + list(zs_list)
return bi_zs_list
def cal_bi_zs_list(self, bi_list):
"""
根据缠论笔中枢定义计算中枢(参照 get_zs_list 线段中枢判断规则)
从第4根笔开始(索引3),每3根笔为一组检查
上涨中枢:后中枢 zd > 前中枢 zg(不重叠上移)
下跌中枢:后中枢 zg < 前中枢 zd(不重叠下移)
中枢可按两笔一组继续扩展到5根、7根...
"""
bi_zs_list = []
if len(bi_list) < 3:
return bi_zs_list
last_zs = None
start_idx = 3
while start_idx < len(bi_list):
if start_idx + 2 >= len(bi_list):
break
bi1 = bi_list[start_idx]
bi2 = bi_list[start_idx + 1]
bi3 = bi_list[start_idx + 2]
if not (bi1.is_sure and bi2.is_sure and bi3.is_sure):
start_idx += 1
continue
zg = min(bi1.high, bi2.high, bi3.high)
zd = max(bi1.low, bi2.low, bi3.low)
if zg <= zd:
start_idx += 1
continue
valid = False
if last_zs is None:
if bi1.dir == Chan_BI_DIR.DOWN:
zs_dir = Chan_ZS_DIR.UP
valid = (bi2.dir == Chan_BI_DIR.UP and bi3.dir == Chan_BI_DIR.DOWN)
else:
zs_dir = Chan_ZS_DIR.DOWN
valid = (bi2.dir == Chan_BI_DIR.DOWN and bi3.dir == Chan_BI_DIR.UP)
else:
is_up_zs = zg > last_zs.zg
is_down_zs = zd < last_zs.zd
if is_up_zs:
zs_dir = Chan_ZS_DIR.UP
valid = (bi1.dir == Chan_BI_DIR.DOWN and bi2.dir == Chan_BI_DIR.UP and bi3.dir == Chan_BI_DIR.DOWN)
elif is_down_zs:
zs_dir = Chan_ZS_DIR.DOWN
valid = (bi1.dir == Chan_BI_DIR.UP and bi2.dir == Chan_BI_DIR.DOWN and bi3.dir == Chan_BI_DIR.UP)
if not valid:
start_idx += 1
continue
gg = max(bi1.high, bi2.high, bi3.high)
dd = min(bi1.low, bi2.low, bi3.low)
zs = ChanBIZS(bi1, len(bi_zs_list), zs_dir)
zs.set_zg(zg)
zs.set_zd(zd)
zs.set_gg(gg)
zs.set_dd(dd)
zs.is_sure = False
zs.bi_list = [bi1, bi2, bi3]
added_after_leave = []
leave_index = start_idx + 4
while leave_index < len(bi_list):
b = bi_list[leave_index]
if not b.is_sure:
break
if b.high >= zs.zd and b.low <= zs.zg:
added_after_leave.append(b.pre)
added_after_leave.append(b)
else:
break
leave_index += 2
if added_after_leave:
bis_for_zs = list(zs.bi_list) + list(added_after_leave)
bi_highs = [bi.high for bi in bis_for_zs]
bi_lows = [bi.low for bi in bis_for_zs]
zs.set_gg(max(bi_highs))
zs.set_dd(min(bi_lows))
zs.bi_list = bis_for_zs
bi = bis_for_zs[-1]
if bi.end_klc:
zs.set_end_bi(bi, bi.sure_time)
start_idx = start_idx + len(added_after_leave)
else:
zs.set_end_bi(bi3, bi3.sure_time)
if last_zs:
last_zs.set_next(zs)
zs.set_pre(last_zs)
bi_zs_list.append(zs)
last_zs = zs
start_idx += 4
if last_zs:
last_zs.is_sure = bi_list[-1].is_sure
if last_zs and not last_zs.is_sure:
if last_zs.bi_list and len(last_zs.bi_list) > 0:
last_bi_of_zs = last_zs.bi_list[-1]
last_bi_idx = -1
for i, bi in enumerate(bi_list):
if bi == last_bi_of_zs:
last_bi_idx = i
break
has_leave = False
if last_bi_idx >= 0 and last_bi_idx + 1 < len(bi_list):
for i in range(last_bi_idx + 1, len(bi_list)):
bi = bi_list[i]
if bi.is_sure:
leave = (bi.low > last_zs.zg and bi.high > last_zs.zg) or \
(bi.high < last_zs.zd and bi.low < last_zs.zd)
if leave:
has_leave = True
break
if has_leave:
if last_bi_of_zs.end_klc:
last_zs.set_end_bi(last_bi_of_zs, last_bi_of_zs.sure_time)
return bi_zs_list
def find_all_bsp(self, bi_list, bi_zs_list):
"""
@@ -1566,9 +1714,9 @@ class TF_DF():
bsp_list.append(bsp)
return bsp_list
def calculate_zs(self, bi_list, seg_list):
return self.get_zs_list(bi_list, seg_list)
def get_zs_list(self, bi_list, seg_list):
def calculate_zs(self, seg_list):
return self.get_zs_list(seg_list)
def get_zs_list(self, seg_list):
"""
根据缠论线段中枢定义计算中枢
从第4根线段开始(索引3),每3根线段为一组检查
+9 -11
View File
@@ -33,7 +33,7 @@ class TRADE_POINT_TYPE:
SELL3 = -3 # 三类卖点
app = Flask(__name__)
macd_factor = 2
# 初始化交易所
exchange = ccxt.binance({
'enableRateLimit': True,
@@ -421,8 +421,8 @@ def get_a_stock_kl_data(symbol, timeframe, limit=100000, start_time=None, end_ti
return None
def add_indicators(df):
fast = 12*1
slow = 26*1
fast = 12*macd_factor
slow = 26*macd_factor
period = 9*1
macd = ta.MACD(df, fastperiod=fast, slowperiod=slow, signalperiod=period)
@@ -509,8 +509,8 @@ def add_indicators(df):
def calculate_macd(df):
"""计算MACD指标"""
exp1 = df['close'].ewm(span=26, adjust=False).mean()
exp2 = df['close'].ewm(span=52, adjust=False).mean()
exp1 = df['close'].ewm(span=12*macd_factor, adjust=False).mean()
exp2 = df['close'].ewm(span=26*macd_factor, adjust=False).mean()
macd = exp1 - exp2
signal = macd.ewm(span=9, adjust=False).mean()
histogram = macd - signal
@@ -534,13 +534,11 @@ def analyze_chan(df, symbol=None, timeframe=None):
#for index in range(0, 10):
#print(bi_list[index].start_time, bi_list[index].start_klc.end_time, bi_list[index].dir)
seg_list = chan.get_seg_list(bi_list)
zs_list = chan.calculate_zs(bi_list, seg_list)
zs_list = chan.calculate_zs(seg_list)
# 计算笔中枢(BI中枢)并拍平成列表
try:
bi_zs_nested = chan.cal_bi_zs(seg_list)
bi_zs_list = [zs for group in bi_zs_nested for zs in (group or [])] if bi_zs_nested else []
except Exception:
bi_zs_list = []
#bi_zs_list = chan.cal_bi_zs_list(bi_list)
bi_zs_list = chan.cal_bi_zs(seg_list)
bsp_list = []
if len(bi_zs_list) > 0:
bsp_list = chan.find_all_bsp(bi_list, bi_zs_list)