Scripts calcul hyperopt multiple
This commit is contained in:
18
tools/create_params_tree.sh
Executable file
18
tools/create_params_tree.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage: create_params_tree.sh <PAIR1> [PAIR2] ...
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $0 <PAIR1> [PAIR2] ..." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for PAIR in "$@"; do
|
||||
DIR="params/$PAIR"
|
||||
mkdir -p "$DIR"
|
||||
echo "Created: $DIR"
|
||||
for REGIME in bull bear range; do
|
||||
mkdir -p "$DIR/$REGIME"
|
||||
echo " -> $DIR/$REGIME"
|
||||
done
|
||||
done
|
||||
114
tools/detect_regime.py
Executable file
114
tools/detect_regime.py
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Detect bull/bear/range regimes from historical CSV data (SMA50/SMA200 crossovers)
|
||||
Usage: python3 detect_regime.py <PAIR> <CSV_FILE>
|
||||
CSV must contain at least columns: timestamp, close
|
||||
"""
|
||||
|
||||
# python3 user_data/strategies/tools/detect_regime.py BTC /home/jerome/Perso/freqtradeDocker/user_data/data/binance/BTC_USDT-1d.feather
|
||||
|
||||
import sys
|
||||
import pandas as pd
|
||||
import ta
|
||||
import talib.abstract as talib
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: detect_regime.py <PAIR> <FEATHER_FILE>")
|
||||
sys.exit(1)
|
||||
|
||||
pair = sys.argv[1]
|
||||
file = sys.argv[2]
|
||||
|
||||
# lecture du fichier feather
|
||||
df = pd.read_feather(file)
|
||||
# ne garder que timestamp et close pour detect_regime.py
|
||||
df[['date', 'close']].rename(columns={'date':'timestamp'}).to_csv(
|
||||
f"user_data/data/{pair}-usdt-1d.csv", index=False
|
||||
)
|
||||
|
||||
df = pd.read_csv(f"user_data/data/{pair}-usdt-1d.csv")
|
||||
|
||||
if 'close' not in df.columns or 'timestamp' not in df.columns:
|
||||
print("CSV must contain 'timestamp' and 'close' columns")
|
||||
sys.exit(1)
|
||||
|
||||
# --- paramètres ---
|
||||
SMOOTH_WIN = 5 # EMA pour lisser la pente
|
||||
NUM_TOP = 3 # nombre de segments à garder par classe
|
||||
|
||||
# --- charger les données ---
|
||||
df['timestamp'] = pd.to_datetime(df['timestamp'], errors='coerce')
|
||||
|
||||
# --- calcul SMA14 ---
|
||||
df['sma14'] = ta.trend.sma_indicator(df['close'], 14)
|
||||
|
||||
# --- pente brute ---
|
||||
df['slope'] = df['sma14'].diff()
|
||||
|
||||
# --- lissage EMA ---
|
||||
df['slope_smooth'] = df['slope'].ewm(span=SMOOTH_WIN, adjust=False).mean()
|
||||
|
||||
# --- normalisation relative ---
|
||||
df['slope_norm'] = df['slope_smooth'] / df['close']
|
||||
df['slope_norm'].fillna(0, inplace=True)
|
||||
|
||||
# --- classification dynamique via quantiles ---
|
||||
q = df['slope_norm'].quantile([0.07, 0.21, 0.35, 0.65, 0.79, 0.93]).values
|
||||
q1, q2, q3, q4, q5, q6 = q
|
||||
|
||||
def classify(v):
|
||||
if v <= q1:
|
||||
return 'BR3'
|
||||
elif v <= q2:
|
||||
return 'BR2'
|
||||
elif v <= q3:
|
||||
return 'BR1'
|
||||
elif v <= q4:
|
||||
return 'RG'
|
||||
elif v <= q5:
|
||||
return 'BU1'
|
||||
elif v <= q6:
|
||||
return 'BU2'
|
||||
else:
|
||||
return 'BU3'
|
||||
|
||||
df['trend_class'] = df['slope_norm'].apply(classify)
|
||||
|
||||
# --- boucle pour détecter les segments ---
|
||||
segments = []
|
||||
trend = None
|
||||
start_idx = None
|
||||
|
||||
for i in range(len(df)):
|
||||
new_trend = df['trend_class'].iloc[i]
|
||||
|
||||
if trend is None:
|
||||
trend = new_trend
|
||||
start_idx = i
|
||||
elif new_trend != trend:
|
||||
start_ts = df['timestamp'].iloc[start_idx]
|
||||
end_ts = df['timestamp'].iloc[i]
|
||||
segments.append((trend, start_ts, end_ts))
|
||||
trend = new_trend
|
||||
start_idx = i
|
||||
|
||||
# fermer le dernier segment
|
||||
if trend is not None and start_idx is not None:
|
||||
start_ts = df['timestamp'].iloc[start_idx]
|
||||
end_ts = df['timestamp'].iloc[len(df)-1]
|
||||
segments.append((trend, start_ts, end_ts))
|
||||
|
||||
# --- extraire les 5 plus longs segments par classe ---
|
||||
top_segments_by_class = {}
|
||||
for cls in ['BR3','BR2','BR1','RG','BU1','BU2','BU3']:
|
||||
cls_segments = [(t,s,e) for t,s,e in segments if t==cls]
|
||||
# calcul de la durée
|
||||
cls_segments = [(t,s,e,(e-s).total_seconds()) for t,s,e in cls_segments]
|
||||
cls_segments.sort(key=lambda x: x[3], reverse=True)
|
||||
top_segments_by_class[cls] = [(t,s,e) for t,s,e,d in cls_segments[:NUM_TOP]]
|
||||
|
||||
# --- affichage ---
|
||||
for cls, segs in top_segments_by_class.items():
|
||||
print(f"--- {cls} ---")
|
||||
for t,s,e in segs:
|
||||
print(f"{t} {s} {e}")
|
||||
80
tools/run_hyperopt_batch.sh
Executable file
80
tools/run_hyperopt_batch.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage: run_hyperopt_batch.sh <PAIR_LIST_FILE>
|
||||
# <PAIR_LIST_FILE> contains one pair per line, e.g., BTC-USDT\nETH-USDT
|
||||
#
|
||||
# This script will read each pair, detect regimes (using detect_regime.py),
|
||||
# and run freqtrade hyperopt for each detected regime, saving user_data/strategies/params in user_data/strategies/params/PAIR/REGIME/
|
||||
|
||||
# Lanement par docker exec -i freqtrade user_data/strategies/tools/run_hyperopt_batch.sh user_data/strategies/pairs.txt
|
||||
# user_data/strategies/tools/run_hyperopt_batch.sh user_data/strategies/pairs.txt
|
||||
|
||||
STRATEGIE="Zeus_8_3_2_B_4_2"
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <PAIR_LIST_FILE>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PAIR_LIST_FILE="$1"
|
||||
|
||||
if [ ! -f "$PAIR_LIST_FILE" ]; then
|
||||
echo "File not found: $PAIR_LIST_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "ici $PAIR_LIST_FILE"
|
||||
|
||||
while read -r PAIR; do
|
||||
echo $PAIR
|
||||
[ -z "$PAIR" ] && continue
|
||||
echo "\nProcessing pair: $PAIR"
|
||||
|
||||
DATA_FEATHER="user_data/data/binance/$(echo $PAIR | tr '[:upper:]' '[:upper:]')-1d.feather"
|
||||
if [ ! -f "$DATA_FEATHER" ]; then
|
||||
echo "Data file not found for $PAIR: $DATA_FEATHER" >&2
|
||||
continue
|
||||
fi
|
||||
echo "Work with data file $PAIR: $DATA_FEATHER" >&2
|
||||
|
||||
# Detect regimes using Python script
|
||||
REGIMES=$(python3 user_data/strategies/tools/detect_regime.py "$PAIR" "$DATA_FEATHER") # | awk '{print tolower($1) " " $2 " " $4}')
|
||||
|
||||
while read -r REGIME START st END et; do
|
||||
echo "Work with dates $REGIME : $START - $END" >&2
|
||||
|
||||
if [ -z "$START" ] || [ -z "$END" ]; then
|
||||
echo "Skipping $PAIR $REGIME : cannot determine timerange" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$START" < "2024-09-01" ]]; then
|
||||
echo "TOO OLD $START"
|
||||
continue
|
||||
fi
|
||||
|
||||
TIMERANGE="${START//-/}-${END//-/}"
|
||||
echo "Running hyperopt for $PAIR $REGIME with timerange $TIMERANGE"
|
||||
|
||||
OUTPUT_JSON="user_data/strategies/params/$PAIR/$REGIME/$START-$END-hyperopt_result.json"
|
||||
OUTPUT_TXT="user_data/strategies/params/$PAIR/$REGIME/$START-$END-hyperopt_result.txt"
|
||||
mkdir -p "user_data/strategies/params/$PAIR/$REGIME"
|
||||
|
||||
converted="${PAIR/_//}"
|
||||
|
||||
# COLUMNS=200 LINES=40 script -q -c "
|
||||
|
||||
freqtrade hyperopt --strategy $STRATEGIE --config user_data/config.json --hyperopt-loss OnlyProfitHyperOptLoss --timerange $TIMERANGE --timeframe 5m --spaces sell buy protection --pair $converted -e 80 -j7
|
||||
|
||||
echo "Saved hyperopt output to $OUTPUT_JSON"
|
||||
|
||||
cp user_data/strategies/$STRATEGIE.json $OUTPUT_JSON
|
||||
|
||||
# COLUMNS=120 LINES=40 script -q -c "
|
||||
# docker exec -i freqtrade
|
||||
freqtrade hyperopt-list --profitable --no-details > $OUTPUT_TXT
|
||||
|
||||
sleep 1
|
||||
|
||||
done <<< "$REGIMES"
|
||||
|
||||
done < "$PAIR_LIST_FILE"
|
||||
21
tools/save_params.sh
Executable file
21
tools/save_params.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Usage: save_params.sh <pair> <regime> <sourcefile> <destname>
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -ne 4 ]; then
|
||||
echo "Usage: $0 <pair> <bull|bear> <sourcefile> <destname>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PAIR="$1"
|
||||
REGIME="$2"
|
||||
SRC="$3"
|
||||
DESTNAME="$4"
|
||||
|
||||
mkdir -p "params/${PAIR}/${REGIME}"
|
||||
|
||||
DEST="params/${PAIR}/${REGIME}/${DESTNAME}.json"
|
||||
cp "$SRC" "$DEST"
|
||||
echo "Saved: $DEST"
|
||||
Reference in New Issue
Block a user