Add config and strategies to the repo
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
# --- Do not remove these libs ---
|
||||
from freqtrade.strategy import IStrategy
|
||||
from typing import Dict, List
|
||||
from functools import reduce
|
||||
from pandas import DataFrame, pandas
|
||||
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
||||
|
||||
import sys
|
||||
import os
|
||||
#sys.setrecursionlimit(1000000) #例如这里设置为一百万
|
||||
#sys.path.append(os.path.abspath("/freqtrade/user_data/Chan"))
|
||||
#sys.path.append(os.path.abspath("/Users/jack/Project/freqtrade/user_data/Chan"))
|
||||
sys.path.append(os.path.abspath("/Users/jack/Documents/GitHub/freqtrade/user_data/Chan"))
|
||||
from ChanLun import ChanLun
|
||||
# --------------------------------
|
||||
from technical.util import resample_to_interval, resampled_merge
|
||||
import talib.abstract as ta
|
||||
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from freqtrade.persistence import Trade, Order
|
||||
from typing import Optional
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
### Now you can use logger.info('asfd') to log
|
||||
|
||||
# freqtrade trade -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL_1 --strategy-path ./user_data/strategies
|
||||
# freqtrade backtesting -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL --strategy-path ./user_data/strategies --timerange=20250309-
|
||||
# freqtrade download-data -c ./user_data/ChanLun_SOL.json -t 1m --pairs SOL/USDT:USDT --timerange=20240101-
|
||||
# freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces roi stoploss --strategy ChanLun_SOL --strategy-path ./user_data/strategies -c ./user_data/ChanLun_SOL.json -e 200 --timerange=20241101-20250201
|
||||
|
||||
# sudo docker compose run --rm chan_btc backtesting -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL --strategy-path ./user_data/strategies --timerange=20250101-
|
||||
# sudo docker compose run --rm chan_btc download-data -c ./user_data/ChanLun_SOL.json --pairs SOL/USDT:USDT -t 1m --timerange 20240101-
|
||||
# sudo docker compose run --rm chan_btc trade -c ./user_data/ChanLun_SOL.json --strategy ChanLun_SOL --strategy-path ./user_data/strategies
|
||||
|
||||
class ChanLun_SOL_1(IStrategy):
|
||||
INTERFACE_VERSION: int = 3
|
||||
# Minimal ROI designed for the strategy.
|
||||
# This attribute will be overridden if the config file contains "minimal_roi"
|
||||
minimal_roi = {
|
||||
"0": 0.253,
|
||||
"480": 0.159,
|
||||
"960": 0.052,
|
||||
"1440": 0
|
||||
}
|
||||
can_short = True
|
||||
# Optimal stoploss designed for the strategy
|
||||
# This attribute will be overridden if the config file contains "stoploss"
|
||||
stoploss = -0.21
|
||||
|
||||
trailing_stop = False
|
||||
trailing_stop_positive = 0.015
|
||||
trailing_stop_positive_offset = 0.043
|
||||
trailing_only_offset_is_reached = False
|
||||
|
||||
# Optimal timeframe for the strategy
|
||||
# timeframe = '15m'
|
||||
startup_candle_count = 2000
|
||||
|
||||
time5 = 5
|
||||
time15 = 15
|
||||
time30 = 30
|
||||
time60 = 60
|
||||
time4h = 240
|
||||
last_time = datetime.now()
|
||||
big_size = 0
|
||||
big_state = "00"
|
||||
big_state_list = []
|
||||
chan = ChanLun()
|
||||
small_size = 0
|
||||
small_state = "00"
|
||||
small_state_list = []
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
|
||||
# resample our dataframes
|
||||
dataframe_5 = resample_to_interval(dataframe, self.get_ticker_indicator() * 5)
|
||||
dataframe_15 = resample_to_interval(dataframe, self.get_ticker_indicator() * 15)
|
||||
dataframe_30 = resample_to_interval(dataframe, self.get_ticker_indicator() * 30)
|
||||
dataframe_60 = resample_to_interval(dataframe, self.get_ticker_indicator() * 60)
|
||||
#dataframe_4h = resample_to_interval(dataframe, self.get_ticker_indicator() * 240)
|
||||
|
||||
#dataframe_1d = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d')
|
||||
#dataframe_1w = resample_to_interval(dataframe_1d, self.get_ticker_indicator() * 10080)
|
||||
#dataframe_1m = resample_to_interval(dataframe_1d, self.get_ticker_indicator() * 43200)
|
||||
|
||||
#dataframe_1d = resample_to_interval(dataframe, self.get_ticker_indicator() * 1440)
|
||||
#dataframe_1w = resample_to_interval(dataframe, self.get_ticker_indicator() * 10080)
|
||||
#dataframe_1m = resample_to_interval(dataframe, self.get_ticker_indicator() * 43200)
|
||||
|
||||
dataframe_5['state'] = self.chan.cal_klu_state(dataframe_5)
|
||||
dataframe_15['state'] = self.chan.cal_klu_state(dataframe_15)
|
||||
dataframe_30['state'] = self.chan.cal_klu_state(dataframe_30)
|
||||
dataframe_60['state'] = self.chan.cal_klu_state(dataframe_60)
|
||||
#dataframe_4h['state'] = self.chan.resample_klc_list(dataframe_4h)
|
||||
#dataframe_5['bsps'], dataframe_5['updown'], dataframe_5['bi_sure'] = self.chanpy.get_bsps(dataframe_5)
|
||||
if self.last_time + timedelta(minutes=1) < datetime.now():
|
||||
#print(informative.iloc[-1])
|
||||
self.print_fx(dataframe, 1)
|
||||
self.print_fx(dataframe_5, 5)
|
||||
self.print_fx(dataframe_15, 15)
|
||||
self.print_fx(dataframe_30, 30)
|
||||
#self.print_fx(dataframe_60, 60)
|
||||
print("-------------------------------------------------------------------------------")
|
||||
self.last_time = datetime.now()
|
||||
#self.print_fx(dataframe_4h, "4h")
|
||||
#self.print_fx_list(dataframe_15)
|
||||
#self.print_fx(dataframe_30, 30)
|
||||
#self.print_fx_list(dataframe_5)
|
||||
#print(dataframe_60['high'].rolling(window).max())
|
||||
#print(dataframe_60['low'].rolling(window).min())
|
||||
#for index in range(0, len(dataframe_5)):
|
||||
#print(dataframe_5[dataframe_5['bi_sure'] == 1][dataframe_5['state'] == "-10"])
|
||||
#print(dataframe_5[dataframe_5['bi_sure'] == 1][dataframe_5['state'] == "10"])
|
||||
#dataframe = resampled_merge(dataframe, dataframe_5)
|
||||
#dataframe = resampled_merge(dataframe, dataframe_15)
|
||||
dataframe = resampled_merge(dataframe, dataframe_30)
|
||||
dataframe = resampled_merge(dataframe, dataframe_60)
|
||||
#dataframe = resampled_merge(dataframe, dataframe_4h)
|
||||
return dataframe
|
||||
def print_fx(self, df, label=5):
|
||||
fx_list = self.chan.get_bsp_list(self.chan.get_klc_list(df))
|
||||
fx1 = fx_list[-1]
|
||||
fx2 = fx_list[-2]
|
||||
fx3 = fx_list[-3]
|
||||
fx4 = fx_list[-4]
|
||||
fx5 = fx_list[-5]
|
||||
#print(fx1.end_time, fx1.fx, fx2.end_time, fx2.fx, fx3.end_time, fx3.fx)
|
||||
logger.info(f'\n{fx5.end_time} {fx5.state} {fx4.end_time} {fx4.state} {fx3.end_time} {fx3.state} {fx2.end_time} {fx2.state} {fx1.end_time} {fx1.state} TF: {label}')
|
||||
def print_fx_list(self, df):
|
||||
bsp_list = self.chan.get_bsp_list(self.chan.get_klc_list(df))
|
||||
for bsp in bsp_list:
|
||||
logger.info(f'{bsp.start_time}, {bsp.end_time}, {bsp.fx}')
|
||||
def print_df(self, df):
|
||||
for index in range(0, len(df)):
|
||||
state = 'state'
|
||||
rsi = 'rsi'
|
||||
logger.info(f'{df[state][index]}, {df[rsi][index]}, {df[state][index]}')
|
||||
def print_resample_df(self, df, time):
|
||||
for index in range(0, len(df)):
|
||||
cn1 = 'resample_{}_date'.format(self.get_ticker_indicator()*time)
|
||||
cn2 = 'resample_{}_rsi'.format(self.get_ticker_indicator()*time)
|
||||
cn3 = 'resample_{}_state'.format(self.get_ticker_indicator()*time)
|
||||
logger.info(f'{df[cn1][index]}, {df[cn2][index]}, {df[cn3][index]}')
|
||||
def local_print(self, df):
|
||||
fast = 7
|
||||
slow = 14
|
||||
macd = ta.MACD(df, fast=fast, slow=slow)
|
||||
df['macd'] = macd['macd']
|
||||
df['macdsignal'] = macd['macdsignal']
|
||||
df['macdhist'] = macd['macdhist']
|
||||
df['ema26'] = ta.EMA(df, timeperiod=26)
|
||||
df['ema52'] = ta.EMA(df, timeperiod=52)
|
||||
df['ma5'] = ta.MA(df, timeperiod=5)
|
||||
df['ma10'] = ta.MA(df, timeperiod=10)
|
||||
df['masub'] = df['ma5'].subtract(df['ma10'])
|
||||
#for index in range(0, len(df)):
|
||||
#print(df['date'][index], df['macdhist'][index], df['macd'][index], df['macdsignal'][index], df['masub'][index])
|
||||
# (1,1) = 1, (1,0) = 2, (-1,1) = 3, (-1, 0) = 4, (0,0) = 0
|
||||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'].shift(1) == "-10") &
|
||||
#((dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)] == "-11") |
|
||||
#(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") &
|
||||
(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)].shift(self.time30) == "-100")
|
||||
#(qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']))
|
||||
),
|
||||
['enter_long', 'enter_tag']] = (1, 'long_signal_chan')
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'].shift(1) == "10") &
|
||||
#((dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time5)] == "11") |
|
||||
#(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") &
|
||||
(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)].shift(self.time30) == "100")
|
||||
#(qtpylib.crossed_above(dataframe['macd'], dataframe['macdsignal']))
|
||||
),
|
||||
['enter_short', 'enter_tag']] = (1, 'short_signal_chan')
|
||||
return dataframe
|
||||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'].shift(1) == "10") &
|
||||
(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)].shift(self.time60) == "10")
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "10")
|
||||
),
|
||||
['exit_long', 'exit_tag']] = (1, 'long_close_signal_chan')
|
||||
dataframe.loc[
|
||||
(
|
||||
#(dataframe['state'].shift(1) == "-10") &
|
||||
(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)].shift(self.time60) == "-10")
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time30)] == "-10") &
|
||||
#(dataframe['resample_{}_state'.format(self.get_ticker_indicator()*self.time60)] == "-10")
|
||||
),
|
||||
['exit_short', 'exit_tag']] = (1, 'short_close_signal_chan')
|
||||
return dataframe
|
||||
def leverage(self, pair: str, current_time: datetime, current_rate: float,
|
||||
proposed_leverage: float, max_leverage: float, entry_tag: Optional[str], side: str,
|
||||
**kwargs) -> float:
|
||||
return 1
|
||||
|
||||
def get_ticker_indicator(self):
|
||||
return int(self.timeframe[:-1])
|
||||
Reference in New Issue
Block a user