添加第二类卖卖点
This commit is contained in:
@@ -40,6 +40,12 @@ class ChanKLC():
|
||||
self.candle_dir = klu.candle_dir
|
||||
self.range = klu.range
|
||||
self.strength = klu.strength
|
||||
self.last_top_klc = None
|
||||
self.last_bottom_klc = None
|
||||
def set_last_top_klu(self, last_top_klc):
|
||||
self.last_top_klc = last_top_klc
|
||||
def set_last_bottom_klc(self, last_bottom_klc):
|
||||
self.last_bottom_klc = last_bottom_klc
|
||||
def set_klc_fx_type(self, klc_fx_type):
|
||||
#print(self.start_time, klc_fx_type, self.get_feature_data()['klu_macd'], self.get_feature_data()['klu_macdhist'], self.get_feature_data()['klu_rsi'])
|
||||
self.klc_fx_type = klc_fx_type
|
||||
|
||||
+13
-28
@@ -92,20 +92,11 @@ class ChanLun():
|
||||
klc_list = self.get_klc_list(dataframe)
|
||||
bi_list= self.cal_bi_list(klc_list)
|
||||
def get_klc_state_list(self, dataframe):
|
||||
klu_list = self.get_klu_list(dataframe)
|
||||
klc_list = self.get_klc_list(dataframe)
|
||||
bi_list= self.cal_bi_list(klc_list)
|
||||
state_list = []
|
||||
if len(klc_list) > 0:
|
||||
klc_index = 0
|
||||
# 添加趋势强度判断
|
||||
dataframe['trend_strength'] = abs(dataframe['close'].pct_change(20))
|
||||
|
||||
# 添加波动率判断
|
||||
dataframe['volatility'] = dataframe['close'].pct_change().rolling(window=20).std()
|
||||
|
||||
# 添加成交量趋势
|
||||
dataframe['volume_trend'] = dataframe['volume'].rolling(window=20).mean()
|
||||
for index in range(0, len(dataframe)):
|
||||
if klc_index == len(klc_list):
|
||||
klc_index = len(klc_list) - 1
|
||||
@@ -113,27 +104,18 @@ class ChanLun():
|
||||
if klc.end_klu:
|
||||
if klc.end_klu.idx == index:
|
||||
klc_index += 1
|
||||
features = klc.get_feature_data()
|
||||
if (klc.klc_fx_type == Chan_KLC_FX.TOP1 or klc.klc_fx_type == Chan_KLC_FX.TOP2) and klc.bi.dir == Chan_BI_DIR.UP:
|
||||
if klc.klc_fx_type == Chan_KLC_FX.TOP3:
|
||||
state_list.append("10")
|
||||
#print(klc.start_time, klc.klc_fx_type)
|
||||
elif (klc.klc_fx_type == Chan_KLC_FX.BOTTOM1 or klc.klc_fx_type == Chan_KLC_FX.BOTTOM2) and klc.bi.dir == Chan_BI_DIR.DOWN:
|
||||
print(klc.start_time, klc.end_time, klc.klc_fx_type)
|
||||
elif klc.klc_fx_type == Chan_KLC_FX.BOTTOM3:
|
||||
state_list.append("-10")
|
||||
#print(klc.end_time, klc.klc_fx_type, klc.bi.start_time, klc.bi.dir)
|
||||
print(klc.start_time, klc.end_time, klc.klc_fx_type)
|
||||
else:
|
||||
state_list.append("00")
|
||||
else:
|
||||
state_list.append("00")
|
||||
else:
|
||||
state_list.append("00")
|
||||
klu = klu_list[index]
|
||||
if klu.volume_ratio > 4.0:
|
||||
if klu.close < klu.open:
|
||||
state_list[-1] = "99"
|
||||
print(klu.time, klu.volume_ratio, "99")
|
||||
else:
|
||||
state_list[-1] = "-99"
|
||||
print(klu.time, klu.volume_ratio, "-99")
|
||||
else:
|
||||
for index in range(0, len(dataframe)):
|
||||
state_list.append("00")
|
||||
@@ -405,7 +387,6 @@ class ChanLun():
|
||||
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 1")
|
||||
#print(bi.start_time, look_for_top, "UP 2")
|
||||
@@ -434,7 +415,6 @@ class ChanLun():
|
||||
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 3")
|
||||
last_down_sbi = down_sbi
|
||||
@@ -449,8 +429,9 @@ class ChanLun():
|
||||
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, "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)
|
||||
@@ -466,8 +447,9 @@ class ChanLun():
|
||||
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, "UP 6")
|
||||
last_seg.add_bi(bi)
|
||||
|
||||
# Last seg is down
|
||||
else:
|
||||
if bi.dir == Chan_BI_DIR.UP:
|
||||
@@ -499,7 +481,6 @@ class ChanLun():
|
||||
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 1")
|
||||
#print(bi.start_time, look_for_top, "DOWN 2")
|
||||
@@ -528,7 +509,6 @@ class ChanLun():
|
||||
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 3")
|
||||
last_up_sbi = up_sbi
|
||||
@@ -586,6 +566,7 @@ class ChanLun():
|
||||
else:
|
||||
last_down_bi = bi
|
||||
down_bi_list.append(bi)
|
||||
"""
|
||||
if len(seg_list) > 1:
|
||||
seg = seg_list[-1]
|
||||
last_seg = seg_list[-2]
|
||||
@@ -635,6 +616,7 @@ class ChanLun():
|
||||
last_seg = seg
|
||||
last_seg_bi = bi_list[i]
|
||||
break
|
||||
"""
|
||||
return seg_list
|
||||
|
||||
def get_bi_zs_list(self, bi_list):
|
||||
@@ -837,6 +819,7 @@ class ChanLun():
|
||||
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
|
||||
@@ -957,6 +940,8 @@ class ChanLun():
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# --- Do not remove these libs ---
|
||||
from statistics import median
|
||||
from freqtrade.strategy import IStrategy
|
||||
from freqtrade.strategy import IStrategy, stoploss_from_absolute
|
||||
import sys
|
||||
import os
|
||||
# 添加父目录到系统路径
|
||||
@@ -61,9 +61,11 @@ class ChanLun_BTC_30(IStrategy):
|
||||
"2400": 0.025,
|
||||
"3600": 0
|
||||
}
|
||||
can_short = False
|
||||
can_short = True
|
||||
lev = 2.0
|
||||
stoploss = -0.5
|
||||
use_custom_stoploss = True
|
||||
|
||||
trailing_stop = False
|
||||
trailing_stop_positive = 0.025
|
||||
trailing_stop_positive_offset = 0.045
|
||||
@@ -77,10 +79,12 @@ class ChanLun_BTC_30(IStrategy):
|
||||
time30 = 30
|
||||
time60 = 60
|
||||
time4h = 240
|
||||
time30 = 60
|
||||
last_time = datetime.now()
|
||||
chan = ChanLun()
|
||||
chanpy = ChanPY()
|
||||
classifier = ChanLunClassifier(None)
|
||||
last_order = None
|
||||
last_trade = None
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
|
||||
@@ -107,9 +111,9 @@ class ChanLun_BTC_30(IStrategy):
|
||||
#self.chan.plot_dual(dataframe_5, dataframe_30)
|
||||
chanpy_state = self.chanpy.get_bsp_state(dataframe_5)
|
||||
dataframe_5['chanpy_state'] = chanpy_state
|
||||
state_list, fx_list = self.chan.get_klc_strength_list(dataframe_30)
|
||||
dataframe_30['state'] = state_list
|
||||
dataframe_30['fx'] = fx_list
|
||||
state_list = self.chan.get_klc_state_list(dataframe_60)
|
||||
dataframe_60['state'] = state_list
|
||||
dataframe_60['fx'] = state_list
|
||||
|
||||
#bi_list_1 = self.chan.get_bi_list(dataframe)
|
||||
#bi_list_5 = self.chan.get_bi_list(dataframe_5)
|
||||
@@ -126,7 +130,7 @@ class ChanLun_BTC_30(IStrategy):
|
||||
print("-------------------------------------------------------------------------------")
|
||||
self.last_time = datetime.now()
|
||||
dataframe = resampled_merge(dataframe, dataframe_5)
|
||||
dataframe = resampled_merge(dataframe, dataframe_30)
|
||||
dataframe = resampled_merge(dataframe, dataframe_60)
|
||||
#dataframe = resampled_merge(dataframe, dataframe_30)
|
||||
#dataframe = resampled_merge(dataframe, dataframe_60)
|
||||
#dataframe = resampled_merge(dataframe, dataframe_4h)
|
||||
@@ -188,7 +192,7 @@ class ChanLun_BTC_30(IStrategy):
|
||||
new_exitprice = proposed_rate - 50
|
||||
return new_exitprice
|
||||
|
||||
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float,
|
||||
def confirm_trade_entry1(self, pair: str, order_type: str, amount: float, rate: float,
|
||||
time_in_force: str, current_time: datetime, entry_tag: str | None,
|
||||
side: str, **kwargs) -> bool:
|
||||
if self.last_trade:
|
||||
@@ -207,7 +211,20 @@ class ChanLun_BTC_30(IStrategy):
|
||||
#if self.last_trade:
|
||||
#print(self.last_trade.open_date, current_time, self.last_trade.open_date + timedelta(minutes=self.time5))
|
||||
return True
|
||||
|
||||
def custom_stoploss1(self, pair: str, trade: Trade, current_time: datetime,
|
||||
current_rate: float, current_profit: float, after_fill: bool,
|
||||
**kwargs) -> float | None:
|
||||
|
||||
last_high = trade.get_custom_data(key="entry_candle_high")
|
||||
last_low = trade.get_custom_data(key="entry_candle_low")
|
||||
|
||||
# Convert absolute price to percentage relative to current_rate
|
||||
if last_high:
|
||||
return stoploss_from_absolute(last_high, current_rate, is_short=trade.is_short)
|
||||
if last_low:
|
||||
return stoploss_from_absolute(last_low, current_rate, is_short=trade.is_short)
|
||||
# return maximum stoploss value, keeping current stoploss price unchanged
|
||||
return None
|
||||
def custom_exit1(self, pair: str, trade: Trade, current_time: datetime, current_rate: float,
|
||||
current_profit: float, **kwargs):
|
||||
#dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
@@ -229,15 +246,15 @@ class ChanLun_BTC_30(IStrategy):
|
||||
"""
|
||||
if trade.is_short:
|
||||
last_high = trade.get_custom_data(key="entry_candle_high")
|
||||
if current_rate > last_high:
|
||||
if last_high and current_rate > last_high:
|
||||
#print(trade.open_date, last_high, current_rate, "Relay Top FX exit")
|
||||
return "Relay Top FX exit"
|
||||
else:
|
||||
last_low = trade.get_custom_data(key="entry_candle_low")
|
||||
if current_rate < last_low:
|
||||
if last_low and current_rate < last_low:
|
||||
#print(trade.open_date, last_low, current_rate, "Relay Bottom FX exit")
|
||||
return "Relay Bottom FX exit"
|
||||
def order_filled1(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None:
|
||||
def order_filled(self, pair: str, trade: Trade, order: Order, current_time: datetime, **kwargs) -> None:
|
||||
"""
|
||||
Called right after an order fills.
|
||||
Will be called for all order types (entry, exit, stoploss, position adjustment).
|
||||
@@ -250,17 +267,26 @@ class ChanLun_BTC_30(IStrategy):
|
||||
# Obtain pair dataframe (just to show how to access it)
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
|
||||
#last_candle = dataframe.iloc[-1].squeeze()
|
||||
klc_list = self.chan.get_klc_list(resample_to_interval(dataframe, self.get_ticker_indicator() * 30))
|
||||
klc_list = self.chan.get_klc_list(resample_to_interval(dataframe, self.get_ticker_indicator() * self.time30))
|
||||
bi_list = self.chan.cal_bi_list(klc_list)
|
||||
last_high = klc_list[-2].high
|
||||
last_low = klc_list[-2].low
|
||||
if trade.is_short:
|
||||
if (trade.nr_of_successful_entries == 1) and (order.ft_order_side == trade.entry_side):
|
||||
trade.set_custom_data(key="entry_candle_high", value=last_high)
|
||||
if self.last_order is None:
|
||||
if trade.is_short and klc_list[-2].last_top_klc:
|
||||
if (trade.nr_of_successful_entries == 1) and (order.ft_order_side == trade.entry_side):
|
||||
last_high = klc_list[-2].last_top_klc.high
|
||||
print(klc_list[-2].start_time, "--------------------------------", order.order_date, order.side, last_high)
|
||||
trade.set_custom_data(key="entry_candle_high", value=last_high)
|
||||
else:
|
||||
if (trade.nr_of_successful_entries == 1) and (order.ft_order_side == trade.entry_side) and klc_list[-2].last_bottom_klc:
|
||||
last_low = klc_list[-2].last_bottom_klc.low
|
||||
trade.set_custom_data(key="entry_candle_low", value=last_low)
|
||||
print(klc_list[-2].start_time, "--------------------------------", order.order_date, order.side, last_low)
|
||||
#print(trade.open_date, trade.close_date, last_high, last_low, order.ft_order_side, klc_list[-2].start_time, klc_list[-2].end_time)
|
||||
self.last_order = order
|
||||
else:
|
||||
if (trade.nr_of_successful_entries == 1) and (order.ft_order_side == trade.entry_side):
|
||||
trade.set_custom_data(key="entry_candle_low", value=last_low)
|
||||
#print(trade.open_date, trade.close_date, last_high, last_low, order.ft_order_side, klc_list[-2].start_time, klc_list[-2].end_time)
|
||||
if self.last_order.side != order.side:
|
||||
self.last_order = None
|
||||
trade.set_custom_data(key="entry_candle_high", value=None)
|
||||
trade.set_custom_data(key="entry_candle_low", value=None)
|
||||
self.last_trade = trade
|
||||
return None
|
||||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
@@ -272,8 +298,8 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'] == "-30")
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == -1)
|
||||
(dataframe[state_str].shift(shift_time) == "-10")
|
||||
#(dataframe[fx_str].shift(shift_time) == -1)
|
||||
#(dataframe[chanpy_state_str].shift(shift_time+30) == 1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") &
|
||||
@@ -284,8 +310,8 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'] == "-30")
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == 1)
|
||||
(dataframe[state_str].shift(shift_time) == "10")
|
||||
#(dataframe[fx_str].shift(shift_time) == 1)
|
||||
#(dataframe[chanpy_state_str].shift(shift_time+30) == -1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)].shift(self.time5) == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") &
|
||||
@@ -303,8 +329,8 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state']== "30")
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == 1)
|
||||
(dataframe[state_str].shift(shift_time) == "101")
|
||||
#(dataframe[fx_str].shift(shift_time) == 1)
|
||||
#(dataframe[chanpy_state_str].shift(shift_time+30) == -1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "10")
|
||||
@@ -313,8 +339,8 @@ class ChanLun_BTC_30(IStrategy):
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state']== "30")
|
||||
(dataframe[state_str].shift(shift_time) > strength) &
|
||||
(dataframe[fx_str].shift(shift_time) == -1)
|
||||
(dataframe[state_str].shift(shift_time) == "-101")
|
||||
#(dataframe[fx_str].shift(shift_time) == -1)
|
||||
#(dataframe[chanpy_state_str].shift(shift_time+30) == 1)
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "10")
|
||||
|
||||
Reference in New Issue
Block a user