Change some thing
This commit is contained in:
@@ -30,6 +30,7 @@ class ChanBI():
|
|||||||
self.macd_div = 0.0
|
self.macd_div = 0.0
|
||||||
else:
|
else:
|
||||||
self.macd_div = self.macd_hist / self.pre.pre.macd_hist
|
self.macd_div = self.macd_hist / self.pre.pre.macd_hist
|
||||||
|
#print(self.start_time, self.end_time, self.macd_hist, self.pre.pre.macd_hist, self.macd_div)
|
||||||
def cal_macdhist(self):
|
def cal_macdhist(self):
|
||||||
self.macd_hist = 0
|
self.macd_hist = 0
|
||||||
for klc in self.klc_list:
|
for klc in self.klc_list:
|
||||||
|
|||||||
+11
-1
@@ -31,6 +31,7 @@ class ChanKLC():
|
|||||||
self.rsi = klu.rsi
|
self.rsi = klu.rsi
|
||||||
self.volume_ratio = klu.volume_ratio
|
self.volume_ratio = klu.volume_ratio
|
||||||
self.macdhist = 0
|
self.macdhist = 0
|
||||||
|
self.strength_list = []
|
||||||
def set_klc_fx_type(self, klc_fx_type):
|
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'])
|
#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
|
self.klc_fx_type = klc_fx_type
|
||||||
@@ -49,7 +50,16 @@ class ChanKLC():
|
|||||||
self.volume_ratio = self.volume_ratio / len(self.klus)
|
self.volume_ratio = self.volume_ratio / len(self.klus)
|
||||||
self.volume = self.volume / len(self.klus)
|
self.volume = self.volume / len(self.klus)
|
||||||
self.macdhist = self.macdhist / len(self.klus)
|
self.macdhist = self.macdhist / len(self.klus)
|
||||||
|
self.cal_self_strength()
|
||||||
|
def cal_self_strength(self):
|
||||||
|
strength = 0
|
||||||
|
if self.klus:
|
||||||
|
if len(self.klus) == 1:
|
||||||
|
strength = 1
|
||||||
|
else:
|
||||||
|
if len(self.klus) > 1:
|
||||||
|
strength = 0
|
||||||
|
self.strength_list.append(strength)
|
||||||
def set_next(self, klc):
|
def set_next(self, klc):
|
||||||
self.next = klc
|
self.next = klc
|
||||||
def set_pre(self, klc):
|
def set_pre(self, klc):
|
||||||
|
|||||||
+2
-2
@@ -754,7 +754,7 @@ class ChanLun():
|
|||||||
last_top = klc
|
last_top = klc
|
||||||
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 1")
|
#print(klc.start_time, klc.fx, bi_list[-1].dir, "Last Top Change 1")
|
||||||
klc.set_klc_fx_type(Chan_KLC_FX.TOP1)
|
klc.set_klc_fx_type(Chan_KLC_FX.TOP1)
|
||||||
print(klc.end_time, klc.fx, "一类卖点Sell 1")
|
#print(klc.end_time, klc.fx, "一类卖点Sell 1")
|
||||||
#klc.set_fx(fx)
|
#klc.set_fx(fx)
|
||||||
#klc.set_state("10")
|
#klc.set_state("10")
|
||||||
bi_list[-1].add_klc(klc)
|
bi_list[-1].add_klc(klc)
|
||||||
@@ -804,7 +804,7 @@ class ChanLun():
|
|||||||
bi.add_klc(klc)
|
bi.add_klc(klc)
|
||||||
bi_list.append(bi)
|
bi_list.append(bi)
|
||||||
last_top = klc
|
last_top = klc
|
||||||
print(klc.end_time, klc.fx, bi_list[-1].dir, "Last Top Change 2")
|
#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_klc_fx_type(Chan_KLC_FX.TOP2)
|
||||||
#klc.set_state('30')
|
#klc.set_state('30')
|
||||||
bi_list[-1].add_klc(klc)
|
bi_list[-1].add_klc(klc)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class ChanPY():
|
|||||||
"divergence_rate": float("inf"),
|
"divergence_rate": float("inf"),
|
||||||
"bsp2_follow_1": False,
|
"bsp2_follow_1": False,
|
||||||
"bsp3_follow_1": False,
|
"bsp3_follow_1": False,
|
||||||
"min_zs_cnt": 0,
|
"min_zs_cnt": 1,
|
||||||
"bs1_peak": False,
|
"bs1_peak": False,
|
||||||
"macd_algo": "peak",
|
"macd_algo": "peak",
|
||||||
"bs_type": '1,2,3a,1p,2s,3b',
|
"bs_type": '1,2,3a,1p,2s,3b',
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ from ChanBI import ChanBI
|
|||||||
class ChanSEG():
|
class ChanSEG():
|
||||||
def __init__(self, start_bi: ChanBI, index, ddir=Chan_SEG_DIR.UP):
|
def __init__(self, start_bi: ChanBI, index, ddir=Chan_SEG_DIR.UP):
|
||||||
self.start_bi = start_bi
|
self.start_bi = start_bi
|
||||||
|
self.start_time = start_bi.start_time
|
||||||
|
self.end_time = None
|
||||||
self.end_bi = None
|
self.end_bi = None
|
||||||
self.dir = ddir
|
self.dir = ddir
|
||||||
self.low = 0
|
self.low = 0
|
||||||
@@ -38,6 +40,7 @@ class ChanSEG():
|
|||||||
else:
|
else:
|
||||||
self.low = bi.low
|
self.low = bi.low
|
||||||
self.is_sure = True
|
self.is_sure = True
|
||||||
|
self.end_time = bi.end_klc.end_time
|
||||||
if sure_bi.is_sure:
|
if sure_bi.is_sure:
|
||||||
self.sure_time = sure_bi.end_klc.end_time
|
self.sure_time = sure_bi.end_klc.end_time
|
||||||
def pre_set_end_bi(self, bi: ChanBI):
|
def pre_set_end_bi(self, bi: ChanBI):
|
||||||
@@ -47,6 +50,7 @@ class ChanSEG():
|
|||||||
self.high = bi.high
|
self.high = bi.high
|
||||||
else:
|
else:
|
||||||
self.low = bi.low
|
self.low = bi.low
|
||||||
|
self.end_time = bi.end_klc.end_time
|
||||||
def set_pre(self, seg):
|
def set_pre(self, seg):
|
||||||
self.pre = seg
|
self.pre = seg
|
||||||
def set_next(self, seg):
|
def set_next(self, seg):
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ class ChanLun_BTC_30(IStrategy):
|
|||||||
state_list, fx_list = self.chan.get_klc_strength_list(dataframe_30)
|
state_list, fx_list = self.chan.get_klc_strength_list(dataframe_30)
|
||||||
dataframe_30['state'] = state_list
|
dataframe_30['state'] = state_list
|
||||||
dataframe_30['fx'] = fx_list
|
dataframe_30['fx'] = fx_list
|
||||||
|
|
||||||
#bi_list_1 = self.chan.get_bi_list(dataframe)
|
#bi_list_1 = self.chan.get_bi_list(dataframe)
|
||||||
#bi_list_5 = self.chan.get_bi_list(dataframe_5)
|
#bi_list_5 = self.chan.get_bi_list(dataframe_5)
|
||||||
#bi_list_15 = self.chan.get_bi_list(dataframe_15)
|
#bi_list_15 = self.chan.get_bi_list(dataframe_15)
|
||||||
@@ -121,6 +122,7 @@ class ChanLun_BTC_30(IStrategy):
|
|||||||
#self.print_bi(bi_list_15)
|
#self.print_bi(bi_list_15)
|
||||||
#self.print_bi(bi_list_30)
|
#self.print_bi(bi_list_30)
|
||||||
#self.print_bi(bi_list_60)
|
#self.print_bi(bi_list_60)
|
||||||
|
self.print_seg(dataframe_5)
|
||||||
print("-------------------------------------------------------------------------------")
|
print("-------------------------------------------------------------------------------")
|
||||||
self.last_time = datetime.now()
|
self.last_time = datetime.now()
|
||||||
dataframe = resampled_merge(dataframe, dataframe_5)
|
dataframe = resampled_merge(dataframe, dataframe_5)
|
||||||
@@ -129,6 +131,13 @@ class ChanLun_BTC_30(IStrategy):
|
|||||||
#dataframe = resampled_merge(dataframe, dataframe_60)
|
#dataframe = resampled_merge(dataframe, dataframe_60)
|
||||||
#dataframe = resampled_merge(dataframe, dataframe_4h)
|
#dataframe = resampled_merge(dataframe, dataframe_4h)
|
||||||
return dataframe
|
return dataframe
|
||||||
|
def print_seg(self, dataframe):
|
||||||
|
klc_list = self.chan.get_klc_list(dataframe)
|
||||||
|
bi_list = self.chan.cal_bi_list(klc_list)
|
||||||
|
seg_list = self.chan.get_seg_list(bi_list)
|
||||||
|
seg = seg_list[-1]
|
||||||
|
bi = bi_list[-1]
|
||||||
|
print(seg.start_time, seg.dir, bi.start_time, bi.dir)
|
||||||
def print_bi(self, bi_list):
|
def print_bi(self, bi_list):
|
||||||
if bi_list and len(bi_list) > 2:
|
if bi_list and len(bi_list) > 2:
|
||||||
bi1 = bi_list[-1]
|
bi1 = bi_list[-1]
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
from freqtrade.strategy import IStrategy
|
||||||
|
from pandas_ta import ema
|
||||||
|
import pandas as pd
|
||||||
|
import pandas_ta as ta
|
||||||
|
import numpy as np
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from freqtrade.persistence import Trade, Order
|
||||||
|
# freqtrade backtesting -c ./user_data/Chan/config/ChanLun_BTC_30.json --strategy HammerRsiStrategy --strategy-path ./user_data/Chan/strategies --timerange=20250520-
|
||||||
|
|
||||||
|
|
||||||
|
class HammerRsiStrategy(IStrategy):
|
||||||
|
timeframe = "1m" # 1分钟K线
|
||||||
|
minimal_roi = {"0": 0.005} # 0.5% 止盈
|
||||||
|
stoploss = -0.002 # 0.2% 固定止损
|
||||||
|
trailing_stop = True
|
||||||
|
trailing_stop_positive = 0.001 # 0.1% 追踪止损
|
||||||
|
trailing_stop_positive_offset = 0.002 # 0.2% 触发追踪止损
|
||||||
|
startup_candle_count = 20 # 启动K线数
|
||||||
|
|
||||||
|
def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
|
||||||
|
dataframe['rsi'] = ta.rsi(dataframe['close'], length=14)
|
||||||
|
dataframe['ema_fast'] = ta.ema(dataframe['close'], length=5)
|
||||||
|
dataframe['ema_slow'] = ta.ema(dataframe['close'], length=20)
|
||||||
|
dataframe['atr'] = ta.atr(dataframe['high'], dataframe['low'], dataframe['close'], length=14)
|
||||||
|
return dataframe
|
||||||
|
|
||||||
|
def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
|
||||||
|
conditions = (
|
||||||
|
(dataframe['ema_fast'] > dataframe['ema_slow']) & # 快EMA上穿慢EMA
|
||||||
|
(dataframe['rsi'] < 45) # RSI < 45
|
||||||
|
)
|
||||||
|
print(f"Signal check: ema_fast={dataframe['ema_fast'].iloc[-1]}, ema_slow={dataframe['ema_slow'].iloc[-1]}, rsi={dataframe['rsi'].iloc[-1]}")
|
||||||
|
dataframe.loc[conditions, ['enter_long', 'enter_tag']] = (1, 'ema_rsi_entry')
|
||||||
|
return dataframe
|
||||||
|
|
||||||
|
def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
|
||||||
|
conditions = (
|
||||||
|
(dataframe['ema_fast'] < dataframe['ema_slow']) | # 快EMA下穿慢EMA
|
||||||
|
(dataframe['rsi'] > 60) # RSI > 60
|
||||||
|
)
|
||||||
|
dataframe.loc[conditions, ['exit_long', 'exit_tag']] = (1, 'ema_rsi_exit')
|
||||||
|
return dataframe
|
||||||
|
|
||||||
|
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime,
|
||||||
|
current_rate: float, current_profit: float, **kwargs) -> float:
|
||||||
|
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||||
|
atr = dataframe['atr'].iloc[-1]
|
||||||
|
return -1.5 * atr / current_rate # 止损为1.5倍ATR
|
||||||
|
|
||||||
|
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
|
||||||
|
proposed_stake: float, min_stake: float, max_stake: float,
|
||||||
|
entry_tag: str) -> float:
|
||||||
|
return proposed_stake * 0.01 # 1%账户余额
|
||||||
@@ -1124,6 +1124,9 @@
|
|||||||
// 应用保存的逻辑范围到所有图表
|
// 应用保存的逻辑范围到所有图表
|
||||||
tvWidget.mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
tvWidget.mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
tvWidget.volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
tvWidget.volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
|
if (tvWidget.atrChart) {
|
||||||
|
tvWidget.atrChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
|
}
|
||||||
if (tvWidget.macdChart) {
|
if (tvWidget.macdChart) {
|
||||||
tvWidget.macdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
tvWidget.macdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
}
|
}
|
||||||
@@ -1131,6 +1134,9 @@
|
|||||||
// 如果没有逻辑范围,使用时间戳范围
|
// 如果没有逻辑范围,使用时间戳范围
|
||||||
tvWidget.mainChart.timeScale().setVisibleRange(visibleRange);
|
tvWidget.mainChart.timeScale().setVisibleRange(visibleRange);
|
||||||
tvWidget.volumeChart.timeScale().setVisibleRange(visibleRange);
|
tvWidget.volumeChart.timeScale().setVisibleRange(visibleRange);
|
||||||
|
if (tvWidget.atrChart) {
|
||||||
|
tvWidget.atrChart.timeScale().setVisibleRange(visibleRange);
|
||||||
|
}
|
||||||
if (tvWidget.macdChart) {
|
if (tvWidget.macdChart) {
|
||||||
tvWidget.macdChart.timeScale().setVisibleRange(visibleRange);
|
tvWidget.macdChart.timeScale().setVisibleRange(visibleRange);
|
||||||
}
|
}
|
||||||
@@ -5355,14 +5361,16 @@
|
|||||||
if (logicalRange) {
|
if (logicalRange) {
|
||||||
tvWidget.mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
tvWidget.mainChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
|
if (tvWidget.atrChart) tvWidget.atrChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleLogicalRange(logicalRange);
|
||||||
} else if (visibleRange) {
|
} else if (visibleRange) {
|
||||||
tvWidget.mainChart.timeScale().setVisibleRange(visibleRange);
|
tvWidget.mainChart.timeScale().setVisibleRange(visibleRange);
|
||||||
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleRange(visibleRange);
|
if (tvWidget.volumeChart) tvWidget.volumeChart.timeScale().setVisibleRange(visibleRange);
|
||||||
|
if (tvWidget.atrChart) tvWidget.atrChart.timeScale().setVisibleRange(visibleRange);
|
||||||
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleRange(visibleRange);
|
if (tvWidget.macdChart) tvWidget.macdChart.timeScale().setVisibleRange(visibleRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('图表可见范围已恢复');
|
console.log('图表可见范围已恢复(包括ATR图表)');
|
||||||
} else {
|
} else {
|
||||||
console.error('恢复图表可见范围失败 - 图表未初始化');
|
console.error('恢复图表可见范围失败 - 图表未初始化');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user