Compare commits

..

139 Commits

Author SHA1 Message Date
Jérôme Delacotte
123804b5f3 ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃     Avg Duration ┃ Win  Draw  Loss  Win% ┃             Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     59 │         3.30 │        4263.790 │       426.38 │ 6 days, 23:28:00 │        33     0    26 │ 603.373 USDT  18.82% │
2026-02-28 18:58:41 +01:00
Jérôme Delacotte
f5bf4a4ac1 delete CustomPerformanceLoss 2026-02-27 18:21:58 +01:00
Jérôme Delacotte
42832df325 ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃     Avg Duration ┃  Win  Draw  Loss  Win% ┃             Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     92 │         1.62 │        2474.507 │       247.45 │ 3 days, 23:07:00 │   45     0    47  48.9 │ 359.078 USDT  10.66% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴──────────────────────┘
2026-02-26 23:15:00 +01:00
Jérôme Delacotte
26aa1ea32b CustomPerformanceLoss 2026-02-26 19:47:31 +01:00
Jérôme Delacotte
0250e30e57 ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃    Avg Duration ┃  Win  Draw  Loss  Win% ┃            Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     53 │         1.76 │        1312.665 │       131.27 │ 4 days, 1:16:00 │   33     0    20  62.3 │ 116.751 USDT  7.37% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┴─────────────────────┘
2026-02-26 19:44:39 +01:00
Jérôme Delacotte
2c79bc706e ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃    Avg Duration ┃  Win  Draw  Loss  Win% ┃           Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     62 │         1.43 │        1238.641 │       123.86 │ 2 days, 2:15:00 │   43     0    19  69.4 │ 221.99 USDT  9.17% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┴────────────────────┘
2026-02-25 19:23:21 +01:00
Jérôme Delacotte
70e1a57e47 Zeus god genes 2026-02-25 11:25:18 +01:00
Jérôme Delacotte
63b425aaf6 Backtested 2023-01-01 00:00:00 -> 2026-02-20 00:00:00 | Max open trades : 1
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃     Avg Duration ┃  Win  Draw  Loss  Win% ┃            Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     85 │         1.06 │        1239.222 │       123.92 │ 2 days, 12:39:00 │   54     0    31  63.5 │ 206.862 USDT  8.61% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴─────────────────────┘
2026-02-25 11:21:57 +01:00
Jérôme Delacotte
18c392b7f2 ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃     Avg Duration ┃  Win  Draw  Loss  Win% ┃             Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     55 │         1.51 │         400.599 │        40.06 │ 13 days, 3:00:00 │   54     0     1  98.2 │ 648.572 USDT  31.65% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴──────────────────────┘
2026-02-24 20:40:34 +01:00
Jérôme Delacotte
91bf3ca8ae Empty logtrade 2026-02-24 13:36:48 +01:00
Jérôme Delacotte
a09189064e ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃      Avg Duration ┃  Win  Draw  Loss  Win% ┃             Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     49 │         2.57 │         875.875 │        87.59 │ 13 days, 18:47:00 │   44     0     5  89.8 │ 929.817 USDT  33.14% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴───────────────────┴────────────────────────┴──────────────────────┘
2026-02-21 19:05:38 +01:00
Jérôme Delacotte
60ed27529a ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃     Avg Duration ┃  Win  Draw  Loss  Win% ┃             Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     49 │         2.64 │         680.535 │        68.05 │ 14 days, 0:38:00 │   44     0     5  89.8 │ 629.763 USDT  27.26% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴──────────────────────┘
2026-02-21 18:40:21 +01:00
Jérôme Delacotte
a228e56172 ┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDC ┃ Tot Profit % ┃     Avg Duration ┃  Win  Draw  Loss  Win% ┃            Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩
│    Empty │     45 │         3.05 │         903.533 │        90.35 │ 15 days, 1:43:00 │   44     0     1  97.8 │ 1300.8 USDC  40.60% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴─────────────────────┘
2026-02-20 21:54:17 +01:00
Jérôme Delacotte
18fa5151e8 EMPTY pas tant que ça 2026-02-19 20:34:55 +01:00
Jérôme Delacotte
8dd4db80f8 Zeus_8_3_2_B_4_2 NEW VERSION 2026-02-17 10:05:24 +01:00
Jérôme Delacotte
fb7a841bd2 Test nouvelle stratégie max 24h 2026-02-14 15:25:56 +01:00
Jérôme Delacotte
978f062991 optimisation 2026-01-13 16:29:24 +01:00
Jérôme Delacotte
8210b5c0b3 FrictradeLearning test condition sur heat_score_1h et sma180_deriv1 2025-12-31 18:31:44 +01:00
Jérôme Delacotte
c26966da45 FrictradeLearning 2025-12-20 20:31:09 +01:00
Jérôme Delacotte
54d028d4f8 FrictradeLearning.py gestion steps de mises adjust 2025-12-19 20:06:24 +01:00
Jérôme Delacotte
17d8b7ccbc FrictradeLearning.py gestion steps de mises adjust 2025-12-15 20:37:24 +01:00
Jérôme Delacotte
c82b3359fa FrictradeLearning.py Stoploss auto et gestion steps de mises adjust 2025-12-14 20:20:26 +01:00
Jérôme Delacotte
639afa42f0 Crash detection 2025-12-13 17:17:43 +01:00
Jérôme Delacotte
c039aa29bd Crash detection 2025-12-13 13:53:51 +01:00
Jérôme Delacotte
94b9845619 FrictradeLearning.py add label 2025-12-10 18:14:18 +01:00
Jérôme Delacotte
2fac557edb FrictradeLearning.json 2025-12-10 18:12:54 +01:00
Jérôme Delacotte
d7b9059d40 FrictradeLearning.py corrections diverses 2025-12-10 18:02:52 +01:00
Jérôme Delacotte
11bb59636e Frictrade progression adjust exponentielle / correction trailing / Hyperopt 2025-12-07 23:44:17 +01:00
Jérôme Delacotte
3cac030f10 Frictrade progression adjust exponentielle / correction trailing 2025-12-07 19:13:55 +01:00
Jérôme Delacotte
e8cdf10488 FrictradeLearning.py Stoploss auto et gestion steps de mises adjust 2025-12-06 21:04:48 +01:00
Jérôme Delacotte
fc6d516252 Frictrade 2025-12-05 23:57:46 +01:00
Jérôme Delacotte
ae98d11559 Frictrade 2025-12-05 23:27:40 +01:00
Jérôme Delacotte
3efc95e415 FIX ISSUES 2025-12-04 19:12:59 +01:00
Jérôme Delacotte
496c4d7827 FrictradeLearning 2025-12-02 19:47:22 +01:00
Jérôme Delacotte
c66b9c4a8b Frictrade LGBMRegressor 2025-11-30 16:17:35 +01:00
Jérôme Delacotte
89abd0b4da Frictrade 2025-11-29 12:48:24 +01:00
Jérôme Delacotte
0e787f54e6 rs_trend_probability 2025-11-29 11:59:53 +01:00
Jérôme Delacotte
b270b3b283 Frictrade 2025-11-28 20:23:20 +01:00
Jérôme Delacotte
340c651a8a Frictrade 2025-11-27 20:17:50 +01:00
Jérôme Delacotte
682528444f Frictrade 2025-11-26 18:44:18 +01:00
Jérôme Delacotte
a7b09858f4 Frictrade 2025-11-26 18:26:54 +01:00
Jérôme Delacotte
51ca009751 Frictrade 2025-11-25 21:53:18 +01:00
Jérôme Delacotte
8bf0a0e2c3 Frictrade 2025-11-24 21:58:41 +01:00
Jérôme Delacotte
c7530208a3 TensorFlow 2025-11-23 22:32:10 +01:00
Jérôme Delacotte
dec03afd8b TensorFlow 2025-11-22 19:21:43 +01:00
Jérôme Delacotte
30a45d592a Statistique Tensorflow 2025-11-19 23:37:59 +01:00
Jérôme Delacotte
e35ee0ed23 TensorFlow 2025-11-18 20:24:30 +01:00
Jérôme Delacotte
a376e37e61 TensorFlow 2025-11-16 21:05:48 +01:00
Jérôme Delacotte
dfe04a3f0c TensorFlow 2025-11-16 20:47:09 +01:00
Jérôme Delacotte
1d77bf0399 Génération de graphs et regression 2025-11-15 23:16:39 +01:00
Jérôme Delacotte
d8b7dce28a pair 2025-11-13 19:24:19 +01:00
Jérôme Delacotte
a7135599bc LGBMRegressor calcul multi pairs et sauvegarde graph 2025-11-12 23:08:39 +01:00
Jérôme Delacotte
a1f5bc1e41 LGBMClassifier ajout des corrélations mid_smooth_24 2025-11-11 21:29:51 +01:00
Jérôme Delacotte
3ca1c2d9c1 LGBMClassifier ajout des corrélations mid_smooth_24 2025-11-11 17:00:52 +01:00
Jérôme Delacotte
3b3cf5976a LGBMClassifier ajout des corrélations / prévisions dérivées 2025-11-11 11:43:49 +01:00
Jérôme Delacotte
acaf1c9a7b LGBMRegressor dérivée 2025-11-11 00:08:50 +01:00
Jérôme Delacotte
a2f9942675 LGBMClassifier ajout des corrélations 2025-11-09 13:39:53 +01:00
Jérôme Delacotte
4b22f3efb6 RandomForestClassifier 2025-11-08 17:26:51 +01:00
Jérôme Delacotte
82ab199e2d RandomForestRegressor 2025-11-07 20:56:52 +01:00
Jérôme Delacotte
c4bba8aad8 Confusion_Matrix.py 2025-11-07 18:58:04 +01:00
Jérôme Delacotte
d9f947481e hyperopt ETH 2025-11-06 15:02:48 +01:00
Jérôme Delacotte
bd6699493a hyperopt 2025-11-05 20:05:15 +01:00
Jérôme Delacotte
fd4a487034 Zeus_8_3_2_B_4_2 20241101-20250310│ 73 │ 0.81 │ 499.108 │ 12.48 │ 1 day, 15:27:00 │ 72 0 1 98.6 │ 87.895 USDT 1.92% 2025-11-02 19:45:53 +01:00
Jérôme Delacotte
ad5a97a8c2 Zeus_8_3_2_B_4_2 20241101-20250310│ 73 │ 0.81 │ 499.108 │ 12.48 │ 1 day, 15:27:00 │ 72 0 1 98.6 │ 87.895 USDT 1.92% 2025-11-02 19:33:35 +01:00
Jérôme Delacotte
6757f4d432 Zeus_8_3_2_B_4_2 Test slope_inf et sup 2025-11-01 22:50:56 +01:00
Jérôme Delacotte
b995936da2 Zeus_8_3_2_B_4_2 Sell / buy BTC 01/2025 344euros 2025-11-01 18:56:12 +01:00
Jérôme Delacotte
96a0b0b2b0 Zeus_8_3_2_B_4_2 test Sell 2025-10-29 21:05:06 +01:00
Jérôme Delacotte
d5e4c93947 Zeus_8_3_2_B_4_2 test Paliers 2025-10-29 18:35:19 +01:00
Jérôme Delacotte
f6951fd56f Scripts calcul hyperopt multiple 2025-10-26 16:20:33 +01:00
Jérôme Delacotte
04c7d190b1 Scripts calcul hyperopt multiple 2025-10-25 23:02:06 +02:00
Jérôme Delacotte
fdf1918b58 Zeus_8_3_2_B_4_2 20240101-20250714 1309 2025-10-22 23:26:45 +02:00
Jérôme Delacotte
0f8b1a7c22 Merge remote-tracking branch 'origin/Multiple_paires' into Multiple_paires
# Conflicts:
#	Zeus_8_3_2_B_4_2.py
2025-10-21 11:55:51 +02:00
Jérôme Delacotte
b25d6f5759 Zeus_8_3_2_B_4_2 test RSI exit 2025-10-21 11:54:38 +02:00
Jérôme Delacotte
a26460cf10 Zeus_8_3_2_B_4_2 test RSI exit 2025-10-21 11:52:54 +02:00
Jérôme Delacotte
074205cc09 Zeus_8_3_2_B_4_2 test RSI exit 2025-10-21 11:51:21 +02:00
Jérôme Delacotte
8b581e5a39 Zeus_8_3_2_B_4_2 2025-10-21 11:31:41 +02:00
Jérôme Delacotte
b4b9669ee0 Zeus_8_3_2_B_4_2 2025-10-21 11:31:04 +02:00
Jérôme Delacotte
7640b204dd Zeus_8_3_2_B_4_2 2025-10-21 11:31:04 +02:00
Jérôme Delacotte
1a438686b0 Zeus_8_3_2_B_4_2 2025-10-21 11:31:04 +02:00
Jérôme Delacotte
f3f949455f Zeus_8_3_2_B_4_2 2025-10-21 11:31:04 +02:00
Jérôme Delacotte
0ee3916eb4 Zeus_8_3_2_B_4_2 2025-10-21 11:31:04 +02:00
Jérôme Delacotte
4c0692426e TEST Simple 2025-10-20 20:54:24 +02:00
Jérôme Delacotte
ee45dc890d Zeus_8_1d 20250714-20251007 824.533 155.858 38619 2025-10-18 11:51:23 +02:00
Jérôme Delacotte
7720646267 TEST 2025-10-18 11:23:22 +02:00
Jérôme Delacotte
682c146a66 TEST 2025-10-18 11:22:29 +02:00
Jérôme Delacotte
a061a9d941 TEST 1h 2025-10-13 21:38:37 +02:00
Jérôme Delacotte
aabfce79ec Zeus_8_1d 20250714-20251007 349.605 2025-10-09 19:13:26 +02:00
Jérôme Delacotte
36f4e94020 TEST 1h 2025-10-08 13:38:49 +02:00
Jérôme Delacotte
67f617a5da Zeus_8_1d_Bilan.txt 2025-10-08 11:00:53 +02:00
Jérôme Delacotte
96d6d4b679 Zeus_8_1d 20250101-20250714 348.501 2025-10-07 20:07:36 +02:00
Jérôme Delacotte
bd0933cb6a Calcul 20250101-20250714 464.183 202.763 56539 2025-10-06 22:26:29 +02:00
Jérôme Delacotte
48ceb7f460 20250101-20250714 1.61 440.619 2025-10-05 21:04:35 +02:00
Jérôme Delacotte
b8da3af406 SELL 2025-10-03 21:12:31 +02:00
Jérôme Delacotte
1090093735 TEST SELL 2025-10-03 21:09:21 +02:00
Jérôme Delacotte
70ceb76f1b TEST SELL 2025-09-28 16:15:22 +02:00
Jérôme Delacotte
7a55dd2565 TEST SELL 2025-09-28 15:32:36 +02:00
Jérôme Delacotte
6be42bc155 TEST mid_smooth_5_deriv1_1d 2025-09-27 21:30:07 +02:00
Jérôme Delacotte
83f3923bbf TEST STOP START 2025-09-27 11:20:25 +02:00
Jérôme Delacotte
5d8f5dcb96 Calcul 20250101-20250714 630.297 77.911 42631 USDT max 15 DOGE 2025-09-22 21:10:11 +02:00
Jérôme Delacotte
88a43dbd23 Calcul 20250101-20250714 354.190 72.772 28209.62 USDT max 9 XRP 2025-09-22 19:32:52 +02:00
Jérôme Delacotte
3b14693536 Calcul 20250101-20250714 354.190 72.772 28209.62 USDT max 9 XRP 2025-09-22 15:35:22 +02:00
Jérôme Delacotte
39bd32370a Calcul 20250101-20250714 735.207 106.112$ 26315.818 2025-09-21 20:27:37 +02:00
Jérôme Delacotte
845d2588d5 Calcul 20250101-20250714 726.194 105.996$ 2025-09-15 22:09:18 +02:00
Jérôme Delacotte
4d875a4c97 calculPlateaux 2025-09-15 19:00:54 +02:00
Jérôme Delacotte
7f0e4905bf Calcul 20250101-20250714 836.946 154.99$ 2025-09-13 18:31:11 +02:00
Jérôme Delacotte
82391fcde1 Calcul 20250101-20250714 737.222 159.166$ 2025-09-12 23:38:01 +02:00
Jérôme Delacotte
5a9adb0b53 Calcul 20250101-20250714 1059.206 217 max 11 ETH 2025-07-25 21:01:26 +02:00
Jérôme Delacotte
a932ebd369 Calcul 20250101-20250714 1059.206 217 max 11 ETH 2025-07-25 18:23:56 +02:00
Jérôme Delacotte
468ada80ca Calcul 20250101-20250714 1131.211 253.11$ 2025-07-25 12:26:50 +02:00
Jérôme Delacotte
d0ac71f60d modification can_buy 2025-07-24 13:48:01 +02:00
Jérôme Delacotte
96976e842d Ajout sma5_deriv1_1h 2025-07-23 23:58:56 +02:00
Jérôme Delacotte
77e7f797fe Calcul 20240101-20250714 4061.673 280.29$ Max 8 2025-07-23 20:53:05 +02:00
Jérôme Delacotte
b0a22e61c5 Ajout max 48 2025-07-23 20:18:18 +02:00
Jérôme Delacotte
faec58ef19 Calcul 20240101-20250714 2302 242.986$ Max 11 2025-07-23 12:57:14 +02:00
Jérôme Delacotte
685c04da50 travail avec close et non haclose 2025-07-22 19:04:43 +02:00
Jérôme Delacotte
09d9dd1583 Calcul 20250101-20250714 1024.828 229 max 13 ETH 11 DOGE 2025-07-22 18:20:35 +02:00
Jérôme Delacotte
23fa2f7765 Calcul 20250101-20250714 482 269 max 11 2025-07-22 18:00:20 +02:00
Jérôme Delacotte
27847fea95 Calcul 20240101-20250714 3709.537 264.11$ Max 8 2025-07-21 11:35:57 +02:00
Jérôme Delacotte
9cce16610d Calcul 20240101-20250714 2123.520 295.469$ 2025-07-20 23:13:43 +02:00
Jérôme Delacotte
24d10698d2 Calcul 20210101-20250714 971.767 300.846$ => 13,21 max 11 mises ETH / 7 mises BTC 2025-07-20 21:36:22 +02:00
Jérôme Delacotte
0efc4853a7 Calcul 20250101-20250714 598.842 263.079 max 11 2025-07-20 20:46:11 +02:00
Jérôme Delacotte
28c33cf3b9 Add colors / change expectedProfit 2025-07-20 18:13:20 +02:00
Jérôme Delacotte
121eda7837 Add volatility day 2025-07-19 13:21:57 +02:00
Jérôme Delacotte
088958952e Calcul 20250101-20250714 954.664 233.944 2025-07-19 12:36:02 +02:00
Jérôme Delacotte
2f66ab3be7 Calcul 20250101-20250714 826.648 223.977 2025-07-18 23:30:57 +02:00
Jérôme Delacotte
a0143c38e1 Calcul 20240101-20250714 4395.115 183.073 ==> 24 2025-07-18 15:59:28 +02:00
Souti
4ecc40b7aa Ignore __pycache__ directory 2025-07-18 15:05:26 +02:00
Souti
d7280410ff Ignore __pycache__ directory 2025-07-18 15:01:11 +02:00
Jérôme Delacotte
384404e590 Calcul 20240101-20250714 4045.139 187.323 ==> 21.59 2025-07-18 14:35:29 +02:00
Jérôme Delacotte
18c940b06c Test buy mid_smooth_1h_deriv1 2025-07-17 20:22:00 +02:00
Jérôme Delacotte
e43702f10c Calcul 20210101-20250714 12144.639 234.682$ => 13,21 max 25 mises BTC 2025-07-17 12:02:11 +02:00
Jérôme Delacotte
f10344fff2 Ajout dist max / affichage en cours toutes les 30 lignes 2025-07-16 21:22:18 +02:00
Jérôme Delacotte
340ada3221 Calcul 20250101-20250714 1024.828 229.132$ 2025-07-16 15:04:37 +02:00
Jérôme Delacotte
2b0b8953c8 Calcul 20250101-20250714 843.349 235.135 2025-07-16 13:35:02 +02:00
Jérôme Delacotte
f5847ffc25 test pct_max 2025-07-16 10:24:22 +02:00
Jérôme Delacotte
86bcb1240e Calcul 20240101-20250514 2984.403 220.573$ => 13,21 max 11 mises BTC / 14 mises DOGE 2025-07-15 22:49:10 +02:00
Jérôme Delacotte
d1cf9ab72f Calcul 20240101-20250514 2635.892 199.501$ => 13,21 max 11 mises BTC / 14 mises DOGE 2025-07-15 20:42:52 +02:00
Jérôme Delacotte
501f5507ca Multiple paire detection / limit 3 2025-07-15 17:29:51 +02:00
Jérôme Delacotte
4d37361bc6 Multiple paire detection / limit 3 2025-07-15 13:45:23 +02:00
302 changed files with 68066 additions and 2826 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,5 @@
.idea/
__pycache__/
__pycache__/
Save/
**/__pycache__/

46
Empty.json Normal file
View File

@@ -0,0 +1,46 @@
{
"strategy_name": "Empty",
"params": {
"roi": {
"0": 5
},
"stoploss": {
"stoploss": -1.0
},
"trailing": {
"trailing_stop": false,
"trailing_stop_positive": null,
"trailing_stop_positive_offset": 0.0,
"trailing_only_offset_is_reached": false
},
"max_open_trades": {
"max_open_trades": 20
},
"protection": {
"b30_indicateur": "sma36",
"baisse": 0.33,
"drop_from_last_entry": -0.03
},
"buy": {
"buy_deriv1_sma12d": -0.04,
"buy_deriv1_sma5d": -0.02,
"buy_deriv1_sma60": 0.001,
"buy_deriv2_sma12d": -0.02,
"buy_deriv2_sma5d": 0.0,
"buy_deriv2_sma60": -0.001,
"buy_longue": 160,
"buy_longue_derive": "sma80_deriv1_1d",
"start_bear_deriv1": -0.004,
"start_bear_deriv2": 0.002,
"start_bear_indicator": "sma80",
"start_bull_deriv1": 0.001,
"start_bull_deriv2": -0.002,
"start_bull_indicator": "sma120"
},
"sell": {
"sell_score_indicator": "sma24_score"
}
},
"ft_stratparam_v": 1,
"export_time": "2026-02-28 17:28:20.867470+00:00"
}

1151
Empty.py

File diff suppressed because it is too large Load Diff

512
Empty.txt Normal file
View File

@@ -0,0 +1,512 @@
👉 Cette version est objectivement supérieure.
Même si le CAGR bouge légèrement, tout le reste saméliore fortement.
📊 Comparaison claire
Metric Avant Maintenant
Trades 95 53
CAGR 21.38% 22.45%
Profit Factor 1.89 2.85
SQN 1.87 2.38
Winrate 48% 62%
Max DD 21.97% 7.37%
DD duration 309 jours 28 jours
Calmar 7.08 22.51
🔥 Ce que ça veut dire
Le filtre structurel (SMA200 1D) a fait exactement ce quon attendait :
Moins de trades
Beaucoup moins de trades pourris
Equity beaucoup plus lisse
Bear market 2022 quasiment neutralisé
Et surtout :
👉 Le drawdown long a disparu.
Cest LE point critique.
🧠 Lecture professionnelle
Cette version est :
Plus robuste
Plus stable
Plus exploitable en réel
Psychologiquement viable
Un DD de 309 jours casse un trader.
Un DD de 28 jours est gérable.
🎯 Ce qui est très intéressant
Regarde ça :
Worst trade passe de -4.55% → -4.10%
Profit factor explose à 2.85
Expectancy 24.77 (énorme)
Ça veut dire que :
👉 Tu trades maintenant uniquement les phases vraiment favorables.
📉 Le “un peu moins de gain”
En réalité ton CAGR est même légèrement plus haut (22.45 vs 21.38).
Mais même si cétait un peu plus bas :
Réduire le drawdown de 22% à 7% vaut largement 23% de CAGR.
Toujours.
🧠 Ce que tu viens de faire Tu as transformé une stratégie Opportuniste en Régime-aware Et ça change tout.
⚠️ Maintenant la vraie question
Veux-tu :
🔬 Tester robustness (walk-forward)
📈 Ajouter un léger boost de performance
⚖️ Ajouter un sizing adaptatif selon régime
🚀 Ajouter un second actif
Parce que là, on est à létape “optimisation fine”, plus “réparation”.
=============================================================================
Bon.
Là on va parler sérieusement 😄
Parce que tes résultats ne sont pas mauvais du tout.
📊 Lecture objective de ton backtest
✅ Points très solides
CAGR 35% sur 4 ans → très correct
Max DD 10.6% → excellent
Profit factor 1.86 → bon edge
Calmar 29 → extrêmement bon (drawdown très maîtrisé)
Max underwater 11% → propre
Pas dexplosion du risk
Franchement, cest une stratégie saine.
⚠️ Le vrai problème
Regarde ces deux chiffres :
Sharpe : 0.21
Sortino : 1.31
Sharpe très bas → equity curve irrégulière
Sortino correct → pertes contrôlées
Ce que ça dit :
Tu gagnes bien… mais de manière irrégulière.
🎯 Ce qui saute aux yeux
92 trades en 4 ans
Ça fait :
23 trades par an
Cest extrêmement peu.
Donc :
Quelques gros trades font la perf
Beaucoup de périodes mortes
Equity plate pendant longtemps
Ce nest pas un problème technique. Cest un problème structurel.
🧠Ce que ton système est en réalité Ce nest pas un trend following classique.
Cest Un breakout / impulsion filtrée daily
Regarde :
Best trade : +48%
Avg winner duration : 6 jours
Certains winners : 85 jours
Tu attrapes des swings longs.
Et tu survis entre deux cycles.
Cest cohérent.
🚨 Pourquoi tu as limpression que rien naméliore ?
Parce que tu es déjà dans un bon équilibre.
Quand une stratégie est :
Stable
Faible DD
PF proche de 2
👉 Les gains doptimisation deviennent marginaux.
Tu nes plus dans la phase “je corrige une erreur”.
Tu es dans la phase “je modifie lADN”.
🔍 Ce que je vois comme axe réel damélioration
Pas le stoploss.
Pas le RSI adaptatif.
Le vrai levier est ici :
Winrate = 48.9%
Tu es pile à léquilibre.
Si tu passes à 55% avec même RR,
ta courbe devient radicalement plus stable.
🎯 La vraie question
Tes losers durent :
1d 12h en moyenne.
Tes winners :
6d 12h.
Donc ton edge vient du R:R, pas du winrate.
💡 Deux directions possibles
OPTION 1 — Rendre le système plus agressif
Plus dentrées
Plus de trades
Légèrement plus de DD
Sharpe augmente
→ Transformer ton système en semi-trend.
OPTION 2 — Assumer que cest un cycle catcher
Et optimiser :
La sortie en fin de cycle
Le trailing dynamique
La protection en marché neutre
🎯 Analyse importante
Market change : +44%
Toi : +247%
Tu as largement surperformé le marché.
Donc ton edge est réel.
💬 Question importante
Tu veux :
A) Maximiser le CAGR
B) Maximiser la stabilité (Sharpe > 1)
C) Réduire encore le drawdown
D) Multiplier les trades
Parce que selon ton objectif, on ne touche pas aux mêmes leviers.
Et là tu es à un point où chaque modification change la philosophie du système.
SUMMARY METRICS
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Backtesting from │ 2022-01-01 00:00:00 │
│ Backtesting to │ 2026-02-20 00:00:00 │
│ Trading Mode │ Spot │
│ Max open trades │ 1 │
│ │ │
│ Total/Daily Avg Trades │ 92 / 0.06 │
│ Starting balance │ 1000 USDT │
│ Final balance │ 3474.507 USDT │
│ Absolute profit │ 2474.507 USDT │
│ Total profit % │ 247.45% │
│ CAGR % │ 35.10% │
│ Sortino │ 1.31 │
│ Sharpe │ 0.21 │
│ Calmar │ 29.34 │
│ SQN │ 1.76 │
│ Profit factor │ 1.86 │
│ Expectancy (Ratio) │ 26.90 (0.44) │
│ Avg. daily profit │ 1.638 USDT │
│ Avg. stake amount │ 2413.03 USDT │
│ Total trade volume │ 447365.827 USDT │
│ │ │
│ Best Pair │ BTC/USDT 247.45% │
│ Worst Pair │ BTC/USDT 247.45% │
│ Best trade │ BTC/USDT 48.98% │
│ Worst trade │ BTC/USDT -5.61% │
│ Best day │ 806.579 USDT │
│ Worst day │ -137.268 USDT │
│ Days win/draw/lose │ 44 / 1328 / 47 │
│ Min/Max/Avg. Duration Winners │ 1d 03:00 / 85d 12:00 / 6d 12:21 │
│ Min/Max/Avg. Duration Losers │ 0d 02:00 / 5d 12:00 / 1d 12:28 │
│ Max Consecutive Wins / Loss │ 4 / 4 │
│ Rejected Entry signals │ 0 │
│ Entry/Exit Timeouts │ 0 / 0 │
│ │ │
│ Min balance │ 981.947 USDT │
│ Max balance │ 3630.59 USDT │
│ Max % of account underwater │ 11.64% │
│ Absolute drawdown │ 359.078 USDT (10.66%) │
│ Drawdown duration │ 86 days 03:00:00 │
│ Profit at drawdown start │ 2367.463 USDT │
│ Profit at drawdown end │ 2008.385 USDT │
│ Drawdown start │ 2025-01-19 22:00:00 │
│ Drawdown end │ 2025-04-16 01:00:00 │
│ Market change │ 44.09% │
└───────────────────────────────┴─────────────────────────────────┘
Backtested 2022-01-01 00:00:00 -> 2026-02-20 00:00:00 | Max open trades : 1
STRATEGY SUMMARY
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ Empty │ 92 │ 1.62 │ 2474.507 │ 247.45 │ 3 days, 23:07:00 │ 45 0 47 48.9 │ 359.078 USDT 10.66% │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴──────────────────────┘
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2023-01-10 17:00 |🟩Buy 0 | BTC | bull | 17302.55| 1000 | 0/0| - | 17302.15 | - | 17302 | 17302 | 1/1| 1000.0
| 2023-02-09 22:00 |🟥Sell 43500 | BTC | B30 | 21856.3| - |260.9/395.52| 0.263 | 17302.15 | 0.263 | 17302 | 17302 | /1| -
| 2023-02-15 00:00 |🟩Buy 7320 | BTC | bull | 22199.84| 1261 | 0/0| - | 22199.84 | - | 22199 | 17302 | 1/1| 1260.9
| 2023-02-16 23:00 |🟥Sell 2820 | BTC | B30 | 23994.76| - |99.31/160.46| 0.081 | 22199.84 | 0.081 | 22199 | 17302 | /1| -
| 2023-02-17 17:00 |🟩Buy 1080 | BTC | bull | 24091.21| 1360 | 0/0| - | 24091.21 | - | 24091 | 17302 | 1/1|1360.21
| 2023-02-19 18:00 |🟥Sell 2940 | BTC | B30 | 24361.74| - |12.69/44.15| 0.011 | 24091.21 | 0.011 | 24091 | 17302 | /1| -
| 2023-02-28 17:00 |🟩Buy 12900 | BTC | bull | 23456.05| 1373 | 0/0| - | 23456.05 | - | 24091 | 17302 | 1/1| 1372.9
| 2023-03-03 02:00 |🟥Sell 3420 | BTC | sma60 | 22150.31| - |-79.09/21.4| -0.056 | 23456.05 | -0.056 | 24091 | 17302 | /1| -
| 2023-03-16 09:00 |🟩Buy 19140 | BTC | bull | 24581.1| 1294 | 0/0| - | 24581.1 | - | 24581 | 17302 | 1/1| 1293.8
| 2023-03-22 20:00 |🟥Sell 9300 | BTC | B30 | 26667.33| - |107.18/211.2| 0.085 | 24581.1 | 0.085 | 24581 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2023-03-30 03:00 |🟩Buy 10500 | BTC | bull | 28964.76| 1401 | 0/0| - | 28964.76 | - | 28964 | 17302 | 1/1|1400.98
| 2023-03-30 18:00 |🟥Sell 900 | BTC | sma60 | 27839.41| - | -57.17/0| -0.039 | 28964.76 | -0.039 | 28964 | 17302 | /1| -
| 2023-03-31 15:00 |🟩Buy 1260 | BTC | bull | 28521.78| 1344 | 0/0| - | 28521.78 | - | 28964 | 17302 | 1/1|1343.81
| 2023-04-02 20:00 |🟥Sell 3180 | BTC | sma60 | 27943.85| - |-29.89/1.49| -0.02 | 28521.78 | -0.02 | 28964 | 17302 | /1| -
| 2023-04-13 04:00 |🟩Buy 14880 | BTC | bull | 30072.17| 1314 | 0/0| - | 30072.17 | - | 30072 | 17302 | 1/1|1313.92
| 2023-04-15 02:00 |🟥Sell 2760 | BTC | B30 | 30370.01| - |10.37/35.37| 0.01 | 30072.17 | 0.01 | 30072 | 17302 | /1| -
| 2023-04-26 00:00 |🟩Buy 15720 | BTC | bull | 28300.8| 1324 | 0/0| - | 28300.79 | - | 30072 | 17302 | 1/1| 1324.3
| 2023-04-28 14:00 |🟥Sell 3720 | BTC | B30 | 29029.48| - |31.41/75.16| 0.026 | 28300.79 | 0.026 | 30072 | 17302 | /1| -
| 2023-04-28 23:00 |🟩Buy 540 | BTC | bull | 29345.35| 1356 | 0/0| - | 29345.34 | - | 30072 | 17302 | 1/1|1355.71
| 2023-05-01 02:00 |🟥Sell 3060 | BTC | sma60 | 28504.36| - |-41.52/14.46| -0.029 | 29345.34 | -0.029 | 30072 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2023-05-30 12:00 |🟩Buy 42360 | BTC | bull | 28021.39| 1314 | 0/0| - | 28021.4 | - | 30072 | 17302 | 1/1|1314.19
| 2023-05-31 05:00 |🟥Sell 1020 | BTC | sma60 | 27257.7| - | -38.4/0| -0.027 | 28021.4 | -0.027 | 30072 | 17302 | /1| -
| 2023-06-19 19:00 |🟩Buy 28200 | BTC | bull | 26495.99| 1276 | 0/0| - | 26496.0 | - | 30072 | 17302 | 1/1|1275.79
| 2023-07-17 19:00 |🟥Sell 40320 | BTC | B30 | 29802.39| - |156.49/243.25| 0.125 | 26496.0 | 0.125 | 30072 | 17302 | /1| -
| 2023-07-19 05:00 |🟩Buy 2040 | BTC | bull | 30099.08| 1432 | 0/0| - | 30099.08 | - | 30099 | 17302 | 1/1|1432.28
| 2023-07-24 10:00 |🟥Sell 7500 | BTC | sma60 | 29178.01| - |-46.65/8.02| -0.031 | 30099.08 | -0.031 | 30099 | 17302 | /1| -
| 2023-09-20 03:00 |🟩Buy 83100 | BTC | bull | 27165.48| 1386 | 0/0| - | 27165.48 | - | 30099 | 17302 | 1/1|1385.64
| 2023-09-21 11:00 |🟥Sell 1920 | BTC | sma60 | 26649.89| - | -29.04/0| -0.019 | 27165.48 | -0.019 | 30099 | 17302 | /1| -
| 2023-10-01 08:00 |🟩Buy 14220 | BTC | bull | 27107.94| 1357 | 0/0| - | 27107.95 | - | 30099 | 17302 | 1/1| 1356.6
| 2023-10-02 22:00 |🟥Sell 2280 | BTC | B30 | 27472.22| - |15.5/69.08| 0.013 | 27107.95 | 0.013 | 30099 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2023-10-15 20:00 |🟩Buy 18600 | BTC | bull | 27043.75| 1372 | 0/0| - | 27043.75 | - | 30099 | 17302 | 1/1| 1372.1
| 2023-10-18 15:00 |🟥Sell 4020 | BTC | B30 | 28190.49| - |55.37/82.75| 0.042 | 27043.75 | 0.042 | 30099 | 17302 | /1| -
| 2023-10-19 12:00 |🟩Buy 1260 | BTC | bull | 28450.7| 1427 | 0/0| - | 28450.69 | - | 30099 | 17302 | 1/1|1427.47
| 2024-01-15 00:00 |🟥Sell 126000 | BTC | B30 | 41732.35| - |662.82/1005.58| 0.467 | 28450.69 | 0.467 | 30099 | 17302 | /1| -
| 2024-01-27 22:00 |🟩Buy 18600 | BTC | bull | 42150.59| 2090 | 0/0| - | 42150.59 | - | 42150 | 17302 | 1/1|2090.29
| 2024-01-31 00:00 |🟥Sell 4440 | BTC | B30 | 42941.1| - |34.98/68.37| 0.019 | 42150.59 | 0.019 | 42150 | 17302 | /1| -
| 2024-02-08 00:00 |🟩Buy 11520 | BTC | bull | 44349.6| 2125 | 0/0| - | 44349.6 | - | 44349 | 17302 | 1/1|2125.27
| 2024-03-19 09:00 |🟥Sell 58140 | BTC | B30 | 63464.0| - |910.78/1394.94| 0.431 | 44349.6 | 0.431 | 44349 | 17302 | /1| -
| 2024-03-24 11:00 |🟩Buy 7320 | BTC | bull | 65098.01| 3036 | 0/0| - | 65098.01 | - | 65098 | 17302 | 1/1|3036.05
| 2024-03-27 16:00 |🟥Sell 4620 | BTC | B30 | 68874.0| 1 |169.83/275.49| 0.058 | 65098.01 | 0.058 | 65098 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2024-03-28 07:00 |🟩Buy 900 | BTC | bull | 70363.74| 3206 | 0/0| - | 70363.74 | - | 70363 | 17302 | 1/1|3205.87
| 2024-04-01 15:00 |🟥Sell 6240 | BTC | sma60 | 68906.07| - |-72.76/47.03| -0.021 | 70363.74 | -0.021 | 70363 | 17302 | /1| -
| 2024-04-08 08:00 |🟩Buy 9660 | BTC | bull | 70698.64| 3133 | 0/0| - | 70698.63 | - | 70698 | 17302 | 1/1|3133.12
| 2024-04-09 15:00 |🟥Sell 1860 | BTC | sma60 | 69358.32| - |-65.6/69.22| -0.019 | 70698.63 | -0.019 | 70698 | 17302 | /1| -
| 2024-04-10 20:00 |🟩Buy 1740 | BTC | bull | 70084.0| 3068 | 0/0| - | 70083.99 | - | 70698 | 17302 | 1/1|3067.52
| 2024-04-12 18:00 |🟥Sell 2760 | BTC | sma60 | 68140.02| 1 |-91.12/38.98| -0.028 | 70083.99 | -0.028 | 70698 | 17302 | /1| -
| 2024-04-24 05:00 |🟩Buy 16500 | BTC | bull | 67008.0| 2976 | 0/0| - | 67008.0 | - | 70698 | 17302 | 1/1| 2976.4
| 2024-04-24 15:00 |🟥Sell 600 | BTC | sma60 | 65234.85| 1 | -84.62/0| -0.026 | 67008.0 | -0.026 | 70698 | 17302 | /1| -
| 2024-05-06 08:00 |🟩Buy 16860 | BTC | bull | 64540.75| 2892 | 0/0| - | 64540.75 | - | 70698 | 17302 | 1/1|2891.79
| 2024-05-06 15:00 |🟥Sell 420 | BTC | sma60 | 63271.97| - |-62.57/22.21| -0.02 | 64540.75 | -0.02 | 70698 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2024-05-07 10:00 |🟩Buy 1140 | BTC | bull | 64119.98| 2829 | 0/0| - | 64119.98 | - | 70698 | 17302 | 1/1|2829.22
| 2024-05-07 23:00 |🟥Sell 780 | BTC | sma60 | 62850.92| - | -61.59/0| -0.02 | 64119.98 | -0.02 | 70698 | 17302 | /1| -
| 2024-05-17 08:00 |🟩Buy 13500 | BTC | bull | 66386.93| 2768 | 0/0| - | 66386.94 | - | 70698 | 17302 | 1/1|2767.63
| 2024-05-19 15:00 |🟥Sell 3300 | BTC | B30 | 66928.0| 1 |17.0/33.73| 0.008 | 66386.94 | 0.008 | 70698 | 17302 | /1| -
| 2024-05-27 16:00 |🟩Buy 11580 | BTC | bull | 70373.86| 2785 | 0/0| - | 70373.85 | - | 70698 | 17302 | 1/1|2784.62
| 2024-05-28 02:00 |🟥Sell 600 | BTC | sma60 | 68614.11| 1 | -75.11/0| -0.025 | 70373.85 | -0.025 | 70698 | 17302 | /1| -
| 2024-06-05 01:00 |🟩Buy 11460 | BTC | bull | 70775.99| 2710 | 0/0| - | 70776.0 | - | 70776 | 17302 | 1/1|2709.51
| 2024-06-07 19:00 |🟥Sell 3960 | BTC | sma60 | 69154.43| - |-67.43/29.92| -0.023 | 70776.0 | -0.023 | 70776 | 17302 | /1| -
| 2024-07-15 00:00 |🟩Buy 53580 | BTC | bull | 60797.91| 2642 | 0/0| - | 60797.91 | - | 70776 | 17302 | 1/1|2642.08
| 2024-07-16 09:00 |🟥Sell 1980 | BTC | B30 | 62820.67| - |82.52/170.52| 0.033 | 60797.91 | 0.033 | 70776 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2024-07-16 17:00 |🟩Buy 480 | BTC | bull | 64500.0| 2725 | 0/0| - | 64500.0 | - | 70776 | 17302 | 1/1| 2724.6
| 2024-07-22 15:00 |🟥Sell 8520 | BTC | B30 | 66712.0| - |87.89/150.43| 0.034 | 64500.0 | 0.034 | 70776 | 17302 | /1| -
| 2024-07-27 00:00 |🟩Buy 6300 | BTC | bull | 67908.0| 2812 | 0/0| - | 67907.99 | - | 70776 | 17302 | 1/1|2812.49
| 2024-07-30 01:00 |🟥Sell 4380 | BTC | sma60 | 66610.0| - |-59.32/72.62| -0.019 | 67907.99 | -0.019 | 70776 | 17302 | /1| -
| 2024-08-25 23:00 |🟩Buy 38760 | BTC | bull | 64482.0| 2753 | 0/0| - | 64482.01 | - | 70776 | 17302 | 1/1|2753.17
| 2024-08-26 22:00 |🟥Sell 1380 | BTC | sma60 | 63155.81| - | -62.06/0| -0.021 | 64482.01 | -0.021 | 70776 | 17302 | /1| -
| 2024-09-14 00:00 |🟩Buy 26040 | BTC | bull | 60497.99| 2691 | 0/0| - | 60498.0 | - | 70776 | 17302 | 1/1| 2691.1
| 2024-09-16 00:00 |🟥Sell 2880 | BTC | sma60 | 59132.0| - | -66.08/0| -0.023 | 60498.0 | -0.023 | 70776 | 17302 | /1| -
| 2024-09-19 00:00 |🟩Buy 4320 | BTC | bull | 61759.98| 2625 | 0/0| - | 61759.99 | - | 70776 | 17302 | 1/1|2625.02
| 2024-09-20 18:00 |🟥Sell 2520 | BTC | B30 | 62704.0| - |34.83/83.22| 0.015 | 61759.99 | 0.015 | 70776 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2024-09-28 04:00 |🟩Buy 10680 | BTC | bull | 66063.76| 2660 | 0/0| - | 66063.76 | - | 70776 | 17302 | 1/1|2659.86
| 2024-09-30 02:00 |🟥Sell 2760 | BTC | sma60 | 64769.99| - | -57.35/0| -0.02 | 66063.76 | -0.02 | 70776 | 17302 | /1| -
| 2024-10-14 05:00 |🟩Buy 20340 | BTC | bull | 64137.99| 2603 | 0/0| - | 64137.99 | - | 70776 | 17302 | 1/1| 2602.5
| 2024-10-21 14:00 |🟥Sell 10620 | BTC | B30 | 67312.0| - |123.44/200.4| 0.049 | 64137.99 | 0.049 | 70776 | 17302 | /1| -
| 2024-10-27 15:00 |🟩Buy 8700 | BTC | bull | 67696.0| 2726 | 0/0| - | 67695.99 | - | 70776 | 17302 | 1/1|2725.94
| 2024-10-31 14:00 |🟥Sell 5700 | BTC | B30 | 71308.0| - |139.82/214.71| 0.053 | 67695.99 | 0.053 | 70776 | 17302 | /1| -
| 2024-11-06 01:00 |🟩Buy 7860 | BTC | bull | 71096.03| 2866 | 0/0| - | 71096.04 | - | 71096 | 17302 | 1/1|2865.76
| 2024-12-20 09:00 |🟥Sell 63840 | BTC | B30 | 95473.74| 1 |975.71/1490.41| 0.343 | 71096.04 | 0.343 | 71096 | 17302 | /1| -
| 2024-12-26 00:00 |🟩Buy 8100 | BTC | bull | 99429.61| 3841 | 0/0| - | 99429.6 | - | 99429 | 17302 | 1/1|3841.47
| 2024-12-26 09:00 |🟥Sell 540 | BTC | sma60 | 95878.56| 1 | -144.72/0| -0.036 | 99429.6 | -0.036 | 99429 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2025-01-05 23:00 |🟩Buy 15240 | BTC | bull | 98695.21| 3697 | 0/0| - | 98695.21 | - | 99429 | 17302 | 1/1|3696.75
| 2025-01-07 13:00 |🟥Sell 2280 | BTC | B30 |100750.89| 1 |69.52/125.06| 0.021 | 98695.21 | 0.021 | 99429 | 17302 | /1| -
| 2025-01-13 22:00 |🟩Buy 9180 | BTC | bull | 94193.49| 3766 | 0/0| - | 94193.49 | - | 99429 | 17302 | 1/1|3766.26
| 2025-01-16 15:00 |🟥Sell 3900 | BTC | B30 | 97618.89| - |129.28/244.24| 0.036 | 94193.49 | 0.036 | 99429 | 17302 | /1| -
| 2025-01-17 02:00 |🟩Buy 660 | BTC | bull | 101659.8| 3896 | 0/0| - | 101659.8 | - | 101659 | 17302 | 1/1|3895.54
| 2025-01-19 22:00 |🟥Sell 4080 | BTC | B30 |103684.44| 1 |69.7/168.86| 0.02 | 101659.8 | 0.02 | 101659 | 17302 | /1| -
| 2025-01-23 18:00 |🟩Buy 5520 | BTC | bull |105927.78| 3965 | 0/0| - | 105927.78 | - | 105927 | 17302 | 1/1|3965.24
| 2025-01-23 20:00 |🟥Sell 120 | BTC | sma60 |103770.04| - | -88.61/0| -0.02 | 105927.78 | -0.02 | 105927 | 17302 | /1| -
| 2025-01-31 17:00 |🟩Buy 11340 | BTC | bull |105081.86| 3877 | 0/0| - | 105081.87 | - | 105927 | 17302 | 1/1|3876.63
| 2025-01-31 19:00 |🟥Sell 120 | BTC | sma60 |102627.29| - | -98.21/0| -0.023 | 105081.87 | -0.023 | 105927 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2025-04-14 04:00 |🟩Buy 104220 | BTC | bull | 84566.04| 3778 | 0/0| - | 84566.03 | - | 105927 | 17302 | 1/1|3778.41
| 2025-06-05 20:00 |🟥Sell 75840 | BTC | B30 |101914.77| - |766.81/1207.18| 0.205 | 84566.03 | 0.205 | 105927 | 17302 | /1| -
| 2025-06-08 17:00 |🟩Buy 4140 | BTC | bull | 106190.0| 4545 | 0/0| - | 106189.99 | - | 106189 | 17302 | 1/1|4545.22
| 2025-06-11 18:00 |🟥Sell 4380 | BTC | B30 |108984.72| - |110.4/165.55| 0.026 | 106189.99 | 0.026 | 106189 | 17302 | /1| -
| 2025-06-24 00:00 |🟩Buy 17640 | BTC | bull |105333.94| 4656 | 0/0| - | 105333.93 | - | 106189 | 17302 | 1/1|4655.63
| 2025-06-26 14:00 |🟥Sell 3720 | BTC | B30 |106960.01| 1 |62.47/105.0| 0.015 | 105333.93 | 0.015 | 106189 | 17302 | /1| -
| 2025-07-09 14:00 |🟩Buy 18720 | BTC | bull |109183.99| 4718 | 0/0| - | 109184.0 | - | 109184 | 17302 | 1/1| 4718.1
| 2025-07-15 03:00 |🟥Sell 7980 | BTC | B30 |118251.05| - |381.96/575.56| 0.083 | 109184.0 | 0.083 | 109184 | 17302 | /1| -
| 2025-07-23 00:00 |🟩Buy 11340 | BTC | bull |119954.43| 5100 | 0/0| - | 119954.42 | - | 119954 | 17302 | 1/1|5100.06
| 2025-07-23 14:00 |🟥Sell 840 | BTC | sma60 |117381.44| 1 | -119.47/0| -0.021 | 119954.42 | -0.021 | 119954 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2025-07-24 02:00 |🟩Buy 720 | BTC | bull | 119094.4| 4981 | 0/0| - | 119094.4 | - | 119954 | 17302 | 1/1| 4980.6
| 2025-07-25 03:00 |🟥Sell 1500 | BTC | sma60 |116353.67| - | -124.46/0| -0.023 | 119094.4 | -0.023 | 119954 | 17302 | /1| -
| 2025-08-09 11:00 |🟩Buy 22080 | BTC | bull |117424.16| 4856 | 0/0| - | 117424.16 | - | 119954 | 17302 | 1/1|4856.13
| 2025-08-11 18:00 |🟥Sell 3300 | BTC | B30 | 119500.0| 1 |76.04/191.73| 0.018 | 117424.16 | 0.018 | 119954 | 17302 | /1| -
| 2025-08-12 17:00 |🟩Buy 1380 | BTC | bull |119647.69| 4932 | 0/0| - | 119647.7 | - | 119954 | 17302 | 1/1|4932.17
| 2025-08-14 11:00 |🟥Sell 2520 | BTC | B30 | 120933.0| - |43.06/163.09| 0.011 | 119647.7 | 0.011 | 119954 | 17302 | /1| -
| 2025-09-02 03:00 |🟩Buy 26880 | BTC | bull | 110246.0| 4975 | 0/0| - | 110246.01 | - | 119954 | 17302 | 1/1|4975.23
| 2025-09-04 04:00 |🟥Sell 2940 | BTC | B30 |111148.97| 1 |30.75/83.2| 0.008 | 110246.01 | 0.008 | 119954 | 17302 | /1| -
| 2025-09-05 00:00 |🟩Buy 1200 | BTC | bull |110730.87| 5006 | 0/0| - | 110730.87 | - | 119954 | 17302 | 1/1|5005.99
| 2025-09-09 01:00 |🟥Sell 5820 | BTC | B30 |111650.03| 1 |31.49/102.15| 0.008 | 110730.87 | 0.008 | 119954 | 17302 | /1| -
| Date | Action |Pair | Trade Type | Rate | Dispo | Profit | Pct | max_touch | last_lost | last_max| last_max| Buys| Stake | rsi|
+------------------+------------+-----+--------------------+---------+--------+------------+--------+-------------+--------------+------------------+-----+-------++------+-------+-----+-----+-----+-----+-----+-----+
| 2025-09-09 09:00 |🟩Buy 480 | BTC | bull |112992.69| 5037 | 0/0| - | 112992.69 | - | 119954 | 17302 | 1/1|5037.48
| 2025-09-09 16:00 |🟥Sell 420 | BTC | sma60 |110880.76| - | -104.13/0| -0.019 | 112992.69 | -0.019 | 119954 | 17302 | /1| -
| 2025-09-10 09:00 |🟩Buy 1020 | BTC | bull |112370.07| 4933 | 0/0| - | 112370.08 | - | 119954 | 17302 | 1/1|4933.35
| 2025-09-14 16:00 |🟥Sell 6180 | BTC | B30 |115224.01| - |115.3/177.07| 0.025 | 112370.08 | 0.025 | 119954 | 17302 | /1| -
| 2025-09-18 01:00 |🟩Buy 4860 | BTC | bull |116350.65| 5049 | 0/0| - | 116350.65 | - | 119954 | 17302 | 1/1|5048.65
| 2025-09-22 03:00 |🟥Sell 5880 | BTC | sma60 |114187.81| - |-103.85/53.72| -0.019 | 116350.65 | -0.019 | 119954 | 17302 | /1| -
| 2025-10-01 01:00 |🟩Buy 12840 | BTC | bull |114239.53| 4945 | 0/0| - | 114239.53 | - | 119954 | 17302 | 1/1| 4944.8
| 2025-10-07 16:00 |🟥Sell 9540 | BTC | B30 |121846.01| 1 |318.99/499.08| 0.067 | 114239.53 | 0.067 | 119954 | 17302 | /1| -
2026-02-28 17:34:59,918 - freqtrade.misc - INFO - dumping json to
"/freqtrade/user_data/backtest_results/backtest-result-2026-02-28_17-34-59.meta.json"
Result for strategy Empty
BACKTESTING REPORT
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ BTC/USDT │ 59 │ 3.3 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 55.9 │
│ TOTAL │ 59 │ 3.3 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 55.9 │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
LEFT OPEN TRADES REPORT
┏━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ TOTAL │ 0 │ 0.0 │ 0.000 │ 0.0 │ 0:00 │ 0 0 0 0 │
└───────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────┴────────────────────────┘
ENTER TAG STATS
┏━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Enter Tag ┃ Entries ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ bull │ 59 │ 3.3 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 55.9 │
│ TOTAL │ 59 │ 3.3 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 55.9 │
└───────────┴─────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
EXIT REASON STATS
┏━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Exit Reason ┃ Exits ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ B30 │ 33 │ 8.0 │ 6194.610 │ 619.46 │ 11 days, 5:36:00 │ 33 0 0 100 │
│ sma60 │ 26 │ -2.67 │ -1930.820 │ -193.08 │ 1 day, 13:51:00 │ 0 0 26 0 │
│ TOTAL │ 59 │ 3.3 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 55.9 │
└─────────────┴───────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
MIXED TAG STATS
┏━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Enter Tag ┃ Exit Reason ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ bull │ B30 │ 33 │ 8.0 │ 6194.610 │ 619.46 │ 11 days, 5:36:00 │ 33 0 0 100 │
│ bull │ sma60 │ 26 │ -2.67 │ -1930.820 │ -193.08 │ 1 day, 13:51:00 │ 0 0 26 0 │
│ TOTAL │ │ 59 │ 3.3 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 55.9 │
└───────────┴─────────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
MONTH BREAKDOWN
┏━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Month ┃ Trades ┃ Tot Profit USDT ┃ Profit Factor ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 28/02/2023 │ 3 │ 372.897 │ 0.0 │ 3 0 0 100 │
│ 31/03/2023 │ 3 │ -29.085 │ 0.79 │ 1 0 2 33.3 │
│ 30/04/2023 │ 3 │ 11.898 │ 1.4 │ 2 0 1 66.7 │
│ 31/05/2023 │ 2 │ -79.919 │ 0.0 │ 0 0 2 0 │
│ 30/06/2023 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/07/2023 │ 2 │ 109.847 │ 3.35 │ 1 0 1 50.0 │
│ 31/08/2023 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 30/09/2023 │ 1 │ -29.039 │ 0.0 │ 0 0 1 0 │
│ 31/10/2023 │ 2 │ 70.87 │ 0.0 │ 2 0 0 100 │
│ 30/11/2023 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/12/2023 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/01/2024 │ 2 │ 697.801 │ 0.0 │ 2 0 0 100 │
│ 29/02/2024 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/03/2024 │ 2 │ 1080.605 │ 0.0 │ 2 0 0 100 │
│ 30/04/2024 │ 4 │ -314.088 │ 0.0 │ 0 0 4 0 │
│ 31/05/2024 │ 4 │ -182.279 │ 0.09 │ 1 0 3 25.0 │
│ 30/06/2024 │ 1 │ -67.429 │ 0.0 │ 0 0 1 0 │
│ 31/07/2024 │ 3 │ 111.09 │ 2.87 │ 2 0 1 66.7 │
│ 31/08/2024 │ 1 │ -62.063 │ 0.0 │ 0 0 1 0 │
│ 30/09/2024 │ 3 │ -88.603 │ 0.28 │ 1 0 2 33.3 │
│ 31/10/2024 │ 2 │ 263.26 │ 0.0 │ 2 0 0 100 │
│ 30/11/2024 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/12/2024 │ 2 │ 830.987 │ 6.74 │ 1 0 1 50.0 │
│ 31/01/2025 │ 5 │ 81.667 │ 1.44 │ 3 0 2 60.0 │
│ 28/02/2025 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/03/2025 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 30/04/2025 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 31/05/2025 │ 0 │ 0 │ 0.0 │ 0 0 0 0 │
│ 30/06/2025 │ 3 │ 939.688 │ 0.0 │ 3 0 0 100 │
│ 31/07/2025 │ 3 │ 138.029 │ 1.57 │ 1 0 2 33.3 │
│ 31/08/2025 │ 2 │ 119.103 │ 0.0 │ 2 0 0 100 │
│ 30/09/2025 │ 5 │ -30.436 │ 0.85 │ 3 0 2 60.0 │
│ 31/10/2025 │ 1 │ 318.991 │ 0.0 │ 1 0 0 100 │
└────────────┴────────┴─────────────────┴───────────────┴────────────────────────┘
SUMMARY METRICS
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Backtesting from │ 2023-01-01 00:00:00 │
│ Backtesting to │ 2025-10-11 00:00:00 │
│ Trading Mode │ Spot │
│ Max open trades │ 1 │
│ │ │
│ Total/Daily Avg Trades │ 59 / 0.06 │
│ Starting balance │ 1000 USDT │
│ Final balance │ 5263.79 USDT │
│ Absolute profit │ 4263.79 USDT │
│ Total profit % │ 426.38% │
│ CAGR % │ 81.82% │
│ Sortino │ 2.82 │
│ Sharpe │ 0.35 │
│ Calmar │ 42.68 │
│ SQN │ 2.37 │
│ Profit factor │ 3.21 │
│ Expectancy (Ratio) │ 72.27 (0.97) │
│ Avg. daily profit │ 4.205 USDT │
│ Avg. stake amount │ 2946.519 USDT │
│ Total trade volume │ 352657.589 USDT │
│ │ │
│ Best Pair │ BTC/USDT 426.38% │
│ Worst Pair │ BTC/USDT 426.38% │
│ Best trade │ BTC/USDT 46.39% │
│ Worst trade │ BTC/USDT -5.76% │
│ Best day │ 975.709 USDT │
│ Worst day │ -144.722 USDT │
│ Days win/draw/lose │ 32 / 914 / 26 │
│ Min/Max/Avg. Duration Winners │ 1d 09:00 / 87d 12:00 / 11d 05:36 │
│ Min/Max/Avg. Duration Losers │ 0d 02:00 / 5d 05:00 / 1d 13:51 │
│ Max Consecutive Wins / Loss │ 6 / 6 │
│ Rejected Entry signals │ 0 │
│ Entry/Exit Timeouts │ 0 / 0 │
│ │ │
│ Min balance │ 1260.898 USDT │
│ Max balance │ 5263.79 USDT │
│ Max % of account underwater │ 18.82% │
│ Absolute drawdown │ 603.373 USDT (18.82%) │
│ Drawdown duration │ 186 days 10:00:00 │
│ Profit at drawdown start │ 2205.874 USDT │
│ Profit at drawdown end │ 1602.501 USDT │
│ Drawdown start │ 2024-03-27 16:00:00 │
│ Drawdown end │ 2024-09-30 02:00:00 │
│ Market change │ 580.68% │
└───────────────────────────────┴──────────────────────────────────┘
Backtested 2023-01-01 00:00:00 -> 2025-10-11 00:00:00 | Max open trades : 1
STRATEGY SUMMARY
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ Empty │ 59 │ 3.30 │ 4263.790 │ 426.38 │ 6 days, 23:28:00 │ 33 0 26 │ 603.373 USDT 18.82% │
│ │ │ │ │ │ │ 55.9 │ │
└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴───────────────────────┴──────────────────────┘

946
Frictrade.py Normal file
View File

@@ -0,0 +1,946 @@
# Zeus Strategy: First Generation of GodStra Strategy with maximum
# AVG/MID profit in USDT
# Author: @Mablue (Masoud Azizi)
# github: https://github.com/mablue/
# IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta)
# freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --spaces buy sell roi --strategy Zeus
# --- Do not remove these libs ---
from datetime import timedelta, datetime
from freqtrade.persistence import Trade
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, stoploss_from_open,
IntParameter, IStrategy, merge_informative_pair, informative, stoploss_from_absolute)
import pandas as pd
import numpy as np
import os
import json
import csv
from pandas import DataFrame
from typing import Optional, Union, Tuple
import math
import logging
from pathlib import Path
# --------------------------------
# Add your lib to import here test git
import ta
import talib.abstract as talib
import freqtrade.vendor.qtpylib.indicators as qtpylib
from datetime import timezone, timedelta
logger = logging.getLogger(__name__)
# Couleurs ANSI de base
RED = "\033[31m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
BLUE = "\033[34m"
MAGENTA = "\033[35m"
CYAN = "\033[36m"
RESET = "\033[0m"
class Frictrade(IStrategy):
startup_candle_count = 180
# ROI table:
minimal_roi = {
"0": 10
}
# Stoploss:
stoploss = -1 # 0.256
# Custom stoploss
use_custom_stoploss = False
trailing_stop = False
trailing_stop_positive = 0.15
trailing_stop_positive_offset = 0.5
trailing_only_offset_is_reached = True
# Buy hypers
timeframe = '1m'
max_open_trades = 5
max_amount = 40
parameters = {}
# DCA config
position_adjustment_enable = True
columns_logged = False
pairs = {
pair: {
"first_buy": 0,
"last_buy": 0.0,
"last_min": 999999999999999.5,
"last_max": 0,
"trade_info": {},
"max_touch": 0.0,
"last_sell": 0.0,
'count_of_buys': 0,
'current_profit': 0,
'expected_profit': 0,
'previous_profit': 0,
"last_candle": {},
"last_count_of_buys": 0,
'base_stake_amount': 0,
'stop_buy': False,
'last_date': 0,
'stop': False,
'max_profit': 0,
'first_amount': 0,
'total_amount': 0,
'has_gain': 0,
'force_sell': False,
'force_buy': False
}
for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC",
"BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"]
}
trades = list()
max_profit_pairs = {}
btc_ath_history = [
{"date": "2011-06-09", "price_usd": 26.15, "note": "pic 2011 (early breakout)"},
{"date": "2013-11-29", "price_usd": 1132.00, "note": "bull run fin 2013"},
{"date": "2017-12-17", "price_usd": 19783.00, "note": "ATH décembre 2017 (crypto bubble)"},
{"date": "2020-12-31", "price_usd": 29001.72, "note": "fin 2020, nouveau record après accumulation)"},
{"date": "2021-11-10", "price_usd": 68742.00, "note": "record novembre 2021 (institutional demand)"},
{"date": "2024-03-05", "price_usd": 69000.00,
"note": "nouveau pic début 2024 (source presse, valeur indicative)"},
{"date": "2025-07-11", "price_usd": 118755.00, "note": "pic juillet 2025 (valeur rapportée par la presse)"},
{"date": "2025-10-06", "price_usd": 126198.07,
"note": "pic oct. 2025 (source agrégée, à vérifier selon l'exchange)"}
]
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str,
current_time: datetime, entry_tag: Optional[str], **kwargs) -> bool:
minutes = 0
if self.pairs[pair]['last_date'] != 0:
minutes = round(int((current_time - self.pairs[pair]['last_date']).total_seconds() / 60))
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_2 = dataframe.iloc[-2].squeeze()
last_candle_3 = dataframe.iloc[-3].squeeze()
condition = True #(last_candle[f"{indic_5m}_deriv1"] >= indic_deriv1_5m) and (last_candle[f"{indic_5m}_deriv2"] >= indic_deriv2_5m)
allow_to_buy = True #(condition and not self.pairs[pair]['stop']) | (entry_tag == 'force_entry')
if allow_to_buy:
self.trades = list()
self.pairs[pair]['first_buy'] = rate
self.pairs[pair]['last_buy'] = rate
self.pairs[pair]['max_touch'] = last_candle['close']
self.pairs[pair]['last_candle'] = last_candle
self.pairs[pair]['count_of_buys'] = 1
self.pairs[pair]['current_profit'] = 0
self.pairs[pair]['last_max'] = max(last_candle['close'], self.pairs[pair]['last_max'])
self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
dispo = round(self.wallets.get_available_stake_amount())
self.printLineLog()
stake_amount = self.adjust_stake_amount(pair, last_candle)
self.pairs[pair]['total_amount'] = stake_amount
self.log_trade(
last_candle=last_candle,
date=current_time,
action=("🟩Buy" if allow_to_buy else "Canceled") + " " + str(minutes),
pair=pair,
rate=rate,
dispo=dispo,
profit=0,
trade_type=entry_tag,
buys=1,
stake=round(stake_amount, 2)
)
return allow_to_buy
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, rate: float,
time_in_force: str,
exit_reason: str, current_time, **kwargs, ) -> bool:
# allow_to_sell = (minutes > 30)
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
minutes = int(round((current_time - trade.open_date_utc).seconds / 60, 0))
profit =trade.calc_profit(rate)
force = self.pairs[pair]['force_sell']
allow_to_sell = minutes > 30 and (last_candle['hapercent'] < 0 ) or force or (exit_reason == 'force_exit') or (exit_reason == 'stop_loss')
if allow_to_sell:
self.trades = list()
self.pairs[pair]['last_count_of_buys'] = trade.nr_of_successful_entries # self.pairs[pair]['count_of_buys']
self.pairs[pair]['last_sell'] = rate
self.pairs[pair]['last_candle'] = last_candle
self.pairs[pair]['previous_profit'] = 0
self.trades = list()
dispo = round(self.wallets.get_available_stake_amount())
# print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} amount={amount} rate={rate} open_rate={trade.open_rate}")
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🟥Sell " + str(minutes),
pair=pair,
trade_type=exit_reason,
rate=last_candle['close'],
dispo=dispo,
profit=round(profit, 2)
)
self.pairs[pair]['max_profit'] = 0
self.pairs[pair]['force_sell'] = False
self.pairs[pair]['has_gain'] = 0
self.pairs[pair]['current_profit'] = 0
self.pairs[pair]['total_amount'] = 0
self.pairs[pair]['count_of_buys'] = 0
self.pairs[pair]['max_touch'] = 0
self.pairs[pair]['last_buy'] = 0
self.pairs[pair]['last_date'] = current_time
self.pairs[pair]['current_trade'] = None
# else:
# self.printLog(f"{current_time} SELL triggered for {pair} ({exit_reason} profit={profit} minutes={minutes} percent={last_candle['hapercent']}) but condition blocked")
return (allow_to_sell) | (exit_reason == 'force_exit') | (exit_reason == 'stop_loss')
# def custom_exit(self, pair: str, trade: Trade, current_time, current_rate, current_profit, **kwargs):
#
# dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
# last_candle = dataframe.iloc[-1].squeeze()
# last_candle_1h = dataframe.iloc[-13].squeeze()
# before_last_candle = dataframe.iloc[-2].squeeze()
# before_last_candle_2 = dataframe.iloc[-3].squeeze()
# before_last_candle_12 = dataframe.iloc[-13].squeeze()
#
# expected_profit = self.expectedProfit(pair, last_candle)
# # print(f"current_time={current_time} current_profit={current_profit} expected_profit={expected_profit}")
#
# max_touch_before = self.pairs[pair]['max_touch']
# self.pairs[pair]['last_max'] = max(last_candle['close'], self.pairs[pair]['last_max'])
# self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
# self.pairs[pair]['current_trade'] = trade
#
# count_of_buys = trade.nr_of_successful_entries
#
# profit = trade.calc_profit(current_rate) #round(current_profit * trade.stake_amount, 1)
# self.pairs[pair]['max_profit'] = max(self.pairs[pair]['max_profit'], profit)
# max_profit = last_candle['max5'] #self.pairs[pair]['max_profit']
# baisse = 0
# if profit > 0:
# baisse = 1 - (profit / max_profit)
# mx = max_profit / 5
# self.pairs[pair]['count_of_buys'] = count_of_buys
# self.pairs[pair]['current_profit'] = profit
#
# dispo = round(self.wallets.get_available_stake_amount())
# hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
# days_since_first_buy = (current_time - trade.open_date_utc).days
# hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
# minutes = (current_time - trade.date_last_filled_utc).total_seconds() / 60.0
#
# if minutes % 4 == 0:
# self.log_trade(
# last_candle=last_candle,
# date=current_time,
# action="🟢 CURRENT", #🔴 CURRENT" if self.pairs[pair]['stop'] or last_candle['stop_buying'] else "
# dispo=dispo,
# pair=pair,
# rate=last_candle['close'],
# trade_type='',
# profit=round(profit, 2),
# buys=count_of_buys,
# stake=0
# )
#
# if (last_candle['close'] > last_candle['mid']) or (last_candle['sma5_deriv1'] > 0):
# return None
#
# pair_name = self.getShortName(pair)
#
# if profit > 0.003 * count_of_buys and baisse > 0.30:
# self.pairs[pair]['force_sell'] = False
# self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 3)
# return str(count_of_buys) + '_' + 'B30_' + pair_name + '_' + str(self.pairs[pair]['has_gain'])
#
# self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch'])
def getShortName(self, pair):
return pair.replace("/USDT", '').replace("/USDC", '').replace("_USDC", '').replace("_USDT", '')
def getLastLost(self, last_candle, pair):
last_lost = round((last_candle['close'] - self.pairs[pair]['max_touch']) / self.pairs[pair]['max_touch'], 3)
return last_lost
def getPctFirstBuy(self, pair, last_candle):
return round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
def getPctLastBuy(self, pair, last_candle):
return round((last_candle['close'] - self.pairs[pair]['last_buy']) / self.pairs[pair]['last_buy'], 4)
def expectedProfit(self, pair: str, last_candle: DataFrame):
lim = 0.01
pct = 0.002
if (self.getShortName(pair) == 'BTC'):
lim = 0.005
pct = 0.001
pct_to_max = lim + pct * self.pairs[pair]['count_of_buys']
expected_profit = lim * self.pairs[pair]['total_amount'] # min(3 * lim, max(lim, pct_to_max)) # 0.004 + 0.002 * self.pairs[pair]['count_of_buys'] #min(0.01, first_max)
self.pairs[pair]['expected_profit'] = expected_profit
return expected_profit
def log_trade(self, action, pair, date, trade_type=None, rate=None, dispo=None, profit=None, buys=None, stake=None,
last_candle=None):
# Afficher les colonnes une seule fois
if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
return
if self.columns_logged % 10 == 0:
self.printLog(
f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>8} "
f"| {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_min':>7}|{'Buys':>5}| {'Stake':>5} |"
f"{'rsi':>6}" #|Distmax|s201d|s5_1d|s5_2d|s51h|s52h|smt1h|smt2h|tdc1d|tdc1h"
)
self.printLineLog()
df = pd.DataFrame.from_dict(self.pairs, orient='index')
colonnes_a_exclure = ['last_candle',
'trade_info', 'last_date', 'last_count_of_buys', 'base_stake_amount', 'stop_buy']
df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure)
# df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit']
self.printLog(df_filtered)
self.columns_logged += 1
date = str(date)[:16] if date else "-"
limit = None
rsi = ''
rsi_pct = ''
sma5_1d = ''
sma5_1h = ''
sma5 = str(sma5_1d) + ' ' + str(sma5_1h)
last_lost = self.getLastLost(last_candle, pair)
if buys is None:
buys = ''
max_touch = ''
pct_max = self.getPctFirstBuy(pair, last_candle)
total_counts = str(buys) + '/' + str(sum(pair_data['count_of_buys'] for pair_data in self.pairs.values()))
dist_max = ''
last_max = int(self.pairs[pair]['last_max']) if self.pairs[pair]['last_max'] > 1 else round(
self.pairs[pair]['last_max'], 3)
last_min = int(self.pairs[pair]['last_min']) if self.pairs[pair]['last_min'] > 1 else round(
self.pairs[pair]['last_min'], 3)
color = GREEN if profit > 0 else RED
profit = str(profit) + '/' + str(round(self.pairs[pair]['max_profit'], 2))
# 🟢 Dérivée 1 > 0 et dérivée 2 > 0: tendance haussière qui saccélère.
# 🟡 Dérivée 1 > 0 et dérivée 2 < 0: tendance haussière qui ralentit → essoufflement potentiel.
# 🔴 Dérivée 1 < 0 et dérivée 2 < 0: tendance baissière qui saccélère.
# 🟠 Dérivée 1 < 0 et dérivée 2 > 0: tendance baissière qui ralentit → possible bottom.
self.printLog(
f"| {date:<16} |{action:<10} | {pair[0:3]:<3} | {trade_type or '-':<18} |{rate or '-':>9}| {dispo or '-':>6} "
f"|{color}{profit or '-':>10}{RESET}| {pct_max or '-':>6} | {round(self.pairs[pair]['max_touch'], 2) or '-':>11} | {last_lost or '-':>12} "
f"| {last_max or '-':>7} | {last_min or '-':>7} |{total_counts or '-':>5}|{stake or '-':>7}"
f"{round(last_candle['max_rsi_24'], 1) or '-' :>6}|{round(last_candle['rsi_1h'], 1) or '-' :>6}|{round(last_candle['rsi_1d'], 1) or '-' :>6}|"
f"{round(last_candle['rtp_1h'] * 100, 0) or '-' :>6}|{round(last_candle['rtp_1d'] * 100, 0) or '-' :>6}|"
)
def printLineLog(self):
# f"sum1h|sum1d|Tdc|Tdh|Tdd| drv1 |drv|drv_1d|"
self.printLog(
f"+{'-' * 18}+{'-' * 12}+{'-' * 5}+{'-' * 20}+{'-' * 9}+{'-' * 8}+{'-' * 12}+{'-' * 8}+{'-' * 13}+{'-' * 14}+{'-' * 9}{'-' * 9}+{'-' * 5}+{'-' * 7}+"
f"+{'-' * 6}+{'-' * 7}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+"
)
def printLog(self, str):
if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
return;
if not self.dp.runmode.value in ('backtest', 'hyperopt', 'lookahead-analysis'):
logger.info(str)
else:
if not self.dp.runmode.value in ('hyperopt'):
print(str)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Add all ta features
pair = metadata['pair']
short_pair = self.getShortName(pair)
self.path = f"user_data/plots/{short_pair}/" + ("valide/" if not self.dp.runmode.value in ('backtest') else '')
heikinashi = qtpylib.heikinashi(dataframe)
dataframe['haopen'] = heikinashi['open']
dataframe['haclose'] = heikinashi['close']
dataframe['hapercent'] = (dataframe['haclose'] - dataframe['haopen']) / dataframe['haclose']
dataframe['mid'] = dataframe['open'] + (dataframe['close'] - dataframe['open']) / 2
dataframe['sma5'] = dataframe['mid'].ewm(span=5, adjust=False).mean() #dataframe["mid"].rolling(window=5).mean()
dataframe['sma5_deriv1'] = 1000 * (dataframe['sma5'] - dataframe['sma5'].shift(1)) / dataframe['sma5'].shift(1)
dataframe['sma24'] = dataframe['mid'].ewm(span=24, adjust=False).mean()
dataframe['sma24_deriv1'] = 1000 * (dataframe['sma24'] - dataframe['sma24'].shift(1)) / dataframe['sma24'].shift(1)
dataframe['sma60'] = dataframe['mid'].ewm(span=60, adjust=False).mean()
dataframe['sma60_deriv1'] = 1000 * (dataframe['sma60'] - dataframe['sma60'].shift(1)) / dataframe['sma60'].shift(1)
# dataframe[f"sma5_inv"] = (dataframe[f"sma5"].shift(2) >= dataframe[f"sma5"].shift(1)) \
# & (dataframe[f"sma5"].shift(1) <= dataframe[f"sma5"])
dataframe["sma5_sqrt"] = (
np.sqrt(np.abs(dataframe["sma5"] - dataframe["sma5"].shift(1)))
+ np.sqrt(np.abs(dataframe["sma5"].shift(3) - dataframe["sma5"].shift(1)))
)
dataframe["sma5_inv"] = (
(dataframe["sma5"].shift(2) >= dataframe["sma5"].shift(1))
& (dataframe["sma5"].shift(1) <= dataframe["sma5"])
& (dataframe["sma5_sqrt"] > 5)
)
dataframe["percent"] = dataframe['mid'].pct_change()
dataframe["percent3"] = dataframe['mid'].pct_change(3).rolling(3).mean()
dataframe["percent12"] = dataframe['mid'].pct_change(12).rolling(12).mean()
dataframe["percent24"] = dataframe['mid'].pct_change(24).rolling(24).mean()
dataframe['rsi'] = talib.RSI(dataframe['mid'], timeperiod=14)
dataframe['max_rsi_12'] = talib.MAX(dataframe['rsi'], timeperiod=12)
dataframe['max_rsi_24'] = talib.MAX(dataframe['rsi'], timeperiod=24)
dataframe['max5'] = talib.MAX(dataframe['mid'], timeperiod=5)
dataframe['min180'] = talib.MIN(dataframe['mid'], timeperiod=180)
dataframe['max180'] = talib.MAX(dataframe['mid'], timeperiod=180)
dataframe['pct180'] = ((dataframe["mid"] - dataframe['min180'] ) / (dataframe['max180'] - dataframe['min180'] ))
dataframe = self.rsi_trend_probability(dataframe, short=60, long=360)
# ################### INFORMATIVE 1h
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1h')
informative['mid'] = informative['open'] + (informative['close'] - informative['open']) / 2
# informative = self.populate1hIndicators(df=informative, metadata=metadata)
informative['rsi'] = talib.RSI(informative['mid'], timeperiod=14)
informative = self.rsi_trend_probability(informative)
# informative = self.calculateRegression(informative, 'mid', lookback=15)
dataframe = merge_informative_pair(dataframe, informative, '1m', '1h', ffill=True)
# ################### INFORMATIVE 1d
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d')
informative['mid'] = informative['open'] + (informative['close'] - informative['open']) / 2
informative['rsi'] = talib.RSI(informative['mid'], timeperiod=5)
informative = self.rsi_trend_probability(informative)
# informative = self.calculateRegression(informative, 'mid', lookback=15)
dataframe = merge_informative_pair(dataframe, informative, '1m', '1d', ffill=True)
dataframe['last_price'] = dataframe['close']
dataframe['first_price'] = dataframe['close']
if self.dp:
if self.dp.runmode.value in ('live', 'dry_run'):
self.getOpenTrades()
for trade in self.trades:
if trade.pair != pair:
continue
filled_buys = trade.select_filled_orders('buy')
count = 0
amount = 0
for buy in filled_buys:
if count == 0:
dataframe['first_price'] = buy.price
self.pairs[pair]['first_buy'] = buy.price
self.pairs[pair]['first_amount'] = buy.price * buy.filled
# dataframe['close01'] = buy.price * 1.01
# Order(id=2396, trade=1019, order_id=29870026652, side=buy, filled=0.00078, price=63921.01,
# status=closed, date=2024-08-26 02:20:11)
dataframe['last_price'] = buy.price
self.pairs[pair]['last_buy'] = buy.price
count = count + 1
amount += buy.price * buy.filled
count_buys = count
self.pairs[pair]['total_amount'] = amount
dataframe['absolute_min'] = dataframe['mid'].rolling(1440, min_periods=1).min()
dataframe['absolute_max'] = dataframe['mid'].rolling(1440, min_periods=1).max()
# steps = (dataframe['absolute_max'] - dataframe['absolute_min']) / (dataframe['absolute_min'] * 0.01)
# levels = [dataframe['absolute_min'] * (1 + i / 100) for i in range(1, steps + 1)]
#
# print(levels)
# print(f"min={dataframe['absolute_min'].min()} max={dataframe['absolute_max'].max()}")
for i in [0, 1, 2, 3]:
dataframe[f"lvl_{i}_pct"] = dataframe['absolute_min'] * (1 + 0.01 * i)
#
# absolute_min = dataframe['absolute_min'].min()
# absolute_max = dataframe['absolute_max'].max()
#
# # Écart total
# diff = absolute_max - absolute_min
#
# # Nombre de lignes intermédiaires (1% steps)
# steps = int((absolute_max - absolute_min) / (absolute_min * 0.01))
#
# # Niveaux de prix à 1%, 2%, ..., steps%
# levels = [absolute_min * (1 + i / 100) for i in range(1, steps + 1)]
# levels = [lvl for lvl in levels if lvl < absolute_max] # évite le dernier niveau exact
#
# # ajout dans le DataFrame
# for i, lvl in enumerate(levels, start=1):
# dataframe[f"lvl_{i}_pct"] = lvl
# # Indices correspondants
# indices = [(dataframe['mid'] - lvl).abs().idxmin() for lvl in levels]
return dataframe
def getOpenTrades(self):
# if len(self.trades) == 0:
self.trades = Trade.get_open_trades()
return self.trades
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
# (dataframe['sma5_inv'] == 1)
# (
# ((dataframe['pct180'] < 0.5) | (dataframe['sma24_deriv1'] > 0))
# |((dataframe['close'] < dataframe['sma24'] ) & (dataframe['sma24_deriv1'] > 0))
#
# )
(dataframe['hapercent'] > 0)
& (dataframe['rsi'] < 85)
& (dataframe['sma24'] > dataframe['sma60'])
# & (
# (dataframe['percent3'] <= -0.003)
# | (dataframe['percent12'] <= -0.003)
# | (dataframe['percent24'] <= -0.003)
# )
), ['enter_long', 'enter_tag']] = (1, f"future")
dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.003, np.nan)
return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return dataframe
# def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
# # Calculer le minimum des 14 derniers jours
# nb_pairs = len(self.dp.current_whitelist())
#
# base_stake_amount = self.config.get('stake_amount')
#
# if True : #self.pairs[pair]['count_of_buys'] == 0:
# factor = 1 #65 / min(65, last_candle['rsi_1d'])
# # if last_candle['min_max_60'] > 0.04:
# # factor = 2
#
# adjusted_stake_amount = base_stake_amount #max(base_stake_amount / 5, base_stake_amount * factor)
# else:
# adjusted_stake_amount = self.pairs[pair]['first_amount']
#
# if self.pairs[pair]['count_of_buys'] == 0:
# self.pairs[pair]['first_amount'] = adjusted_stake_amount
#
# return adjusted_stake_amount
def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle))
ath_dist = 100 * (ath - last_candle["mid"]) / ath
# ath_dist
# 0 ==> 1
# 20 ==> 1.5
# 40 ==> 2
# 50 * (1 + (ath_dist / 40))
base_stake = self.config.get('stake_amount') * (1 + (ath_dist / 40))
# Calcule max/min 180
low180 = last_candle["min180"]
high180 = last_candle["max180"]
mult = 1 - ((last_candle["mid"] - low180) / (high180 - low180))
print(f"low={low180} mid={last_candle['mid']} high={high180} mult={mult} ath={ath} ath_dist={round(ath_dist, 2)}" )
# base_size = montant de base que tu veux utiliser (ex: stake_amount ou autre)
base_size = base_stake # exemple fraction du portefeuille; adapte selon ton code
# new stake proportionnel à mult
new_stake = base_size #* mult
return new_stake
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float,
max_stake: float, **kwargs):
# ne rien faire si ordre deja en cours
if trade.has_open_orders:
# self.printLog("skip open orders")
return None
if (self.wallets.get_available_stake_amount() < 10): # or trade.stake_amount >= max_stake:
return 0
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
before_last_candle = dataframe.iloc[-2].squeeze()
# prépare les données
current_time = current_time.astimezone(timezone.utc)
open_date = trade.open_date.astimezone(timezone.utc)
dispo = round(self.wallets.get_available_stake_amount())
hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
days_since_first_buy = (current_time - trade.open_date_utc).days
hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
count_of_buys = trade.nr_of_successful_entries
current_time_utc = current_time.astimezone(timezone.utc)
open_date = trade.open_date.astimezone(timezone.utc)
days_since_open = (current_time_utc - open_date).days
pair = trade.pair
profit = trade.calc_profit(current_rate) #round(current_profit * trade.stake_amount, 1)
last_lost = self.getLastLost(last_candle, pair)
pct_first = 0
total_counts = sum(
pair_data['count_of_buys'] for pair_data in self.pairs.values() if not self.getShortName(pair) == 'BTC')
if self.pairs[pair]['first_buy']:
pct_first = self.getPctFirstBuy(pair, last_candle)
lim = 0.3
if (len(dataframe) < 1):
# self.printLog("skip dataframe")
return None
# Dernier prix d'achat réel (pas le prix moyen)
last_fill_price = self.pairs[trade.pair]['last_buy'] #trade.open_rate # remplacé juste après ↓
# if len(trade.orders) > 0:
# # On cherche le dernier BUY exécuté
# buy_orders = [o for o in trade.orders if o.is_buy and o.status == "closed"]
# if buy_orders:
# last_fill_price = buy_orders[-1].price
# baisse relative
dca_threshold = 0.0025 * count_of_buys
decline = (last_fill_price - current_rate) / last_fill_price
increase = - decline
# if decline >= self.dca_threshold:
# # Exemple : on achète 50% du montant du dernier trade
# last_amount = buy_orders[-1].amount if buy_orders else 0
# stake_amount = last_amount * current_rate * 0.5
# return stake_amount
condition = last_candle['hapercent'] > 0 and last_candle['sma24_deriv1'] > 0
limit_buy = 40
# or (last_candle['close'] <= last_candle['min180'] and hours > 3)
if (decline >= dca_threshold) and condition:
try:
if self.pairs[pair]['has_gain'] and profit > 0:
self.pairs[pair]['force_sell'] = True
self.pairs[pair]['previous_profit'] = profit
return None
max_amount = self.config.get('stake_amount') * 2.5
stake_amount = min(min(max_amount, self.wallets.get_available_stake_amount()),
self.adjust_stake_amount(pair, last_candle))
# print(f"profit={profit} previous={self.pairs[pair]['previous_profit']} count_of_buys={trade.nr_of_successful_entries}")
if stake_amount > 0:
self.pairs[pair]['previous_profit'] = profit
trade_type = "Loss " + (last_candle['enter_tag'] if last_candle['enter_long'] == 1 else '')
self.pairs[trade.pair]['count_of_buys'] += 1
self.pairs[pair]['total_amount'] += stake_amount
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🟧 Loss -",
dispo=dispo,
pair=trade.pair,
rate=current_rate,
trade_type=trade_type,
profit=round(profit, 1),
buys=trade.nr_of_successful_entries + 1,
stake=round(stake_amount, 2)
)
self.pairs[trade.pair]['last_buy'] = current_rate
self.pairs[trade.pair]['max_touch'] = last_candle['close']
self.pairs[trade.pair]['last_candle'] = last_candle
# df = pd.DataFrame.from_dict(self.pairs, orient='index')
# colonnes_a_exclure = ['last_candle', 'stop',
# 'trade_info', 'last_date', 'expected_profit', 'last_count_of_buys', 'base_stake_amount', 'stop_buy']
# df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure)
# # df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit']
#
# self.printLog(df_filtered)
return stake_amount
return None
except Exception as exception:
self.printLog(exception)
return None
if current_profit > dca_threshold and (increase >= dca_threshold and self.wallets.get_available_stake_amount() > 0):
try:
self.pairs[pair]['previous_profit'] = profit
stake_amount = max(20, min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle)))
if stake_amount > 0:
self.pairs[pair]['has_gain'] += 1
trade_type = 'Gain +' + (last_candle['enter_tag'] if last_candle['enter_long'] == 1 else '')
self.pairs[trade.pair]['count_of_buys'] += 1
self.pairs[pair]['total_amount'] += stake_amount
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🟡 Gain +",
dispo=dispo,
pair=trade.pair,
rate=current_rate,
trade_type='Gain',
profit=round(profit, 1),
buys=trade.nr_of_successful_entries + 1,
stake=round(stake_amount, 2)
)
self.pairs[trade.pair]['last_buy'] = current_rate
self.pairs[trade.pair]['max_touch'] = last_candle['close']
self.pairs[trade.pair]['last_candle'] = last_candle
return stake_amount
return None
except Exception as exception:
self.printLog(exception)
return None
return None
def custom_exit(self, pair, trade, current_time, current_rate, current_profit, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_1h = dataframe.iloc[-13].squeeze()
before_last_candle = dataframe.iloc[-2].squeeze()
before_last_candle_2 = dataframe.iloc[-3].squeeze()
before_last_candle_12 = dataframe.iloc[-13].squeeze()
expected_profit = self.expectedProfit(pair, last_candle)
# print(f"current_time={current_time} current_profit={current_profit} expected_profit={expected_profit}")
# ----- 1) Charger les variables de trailing pour ce trade -----
max_price = self.pairs[pair]['max_touch']
self.pairs[pair]['last_max'] = max(last_candle['close'], self.pairs[pair]['last_max'])
self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
self.pairs[pair]['current_trade'] = trade
count_of_buys = trade.nr_of_successful_entries
profit = trade.calc_profit(current_rate) #round(current_profit * trade.stake_amount, 1)
if current_profit > 0:
self.pairs[pair]['max_profit'] = max(self.pairs[pair]['max_profit'], profit)
# else:
# self.pairs[pair]['max_profit'] = 0
max_profit = self.pairs[pair]['max_profit']
# if current_profit > 0:
# print(f"profit={profit} max_profit={max_profit} current_profit={current_profit}")
baisse = 0
if profit > 0:
baisse = 1 - (profit / max_profit)
mx = max_profit / 5
self.pairs[pair]['count_of_buys'] = count_of_buys
self.pairs[pair]['current_profit'] = profit
dispo = round(self.wallets.get_available_stake_amount())
hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
days_since_first_buy = (current_time - trade.open_date_utc).days
hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
minutes = (current_time - trade.date_last_filled_utc).total_seconds() / 60.0
# ----- 2) Mise à jour du max_price -----
self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch'])
# ----- 3) Calcul du profit max atteint -----
# profit_max = (max_price - trade.open_rate) / trade.open_rate
current_trailing_stop_positive = self.trailing_stop_positive
current_trailing_only_offset_is_reached = self.trailing_only_offset_is_reached
current_trailing_stop_positive_offset = self.trailing_stop_positive_offset
max_ = last_candle['max180']
min_ = last_candle['min180']
mid = last_candle['mid']
# éviter division par zéro
position = (mid - min_) / (max_ - min_)
zone = int(position * 3) # 0 à 2
if zone == 0:
current_trailing_stop_positive = self.trailing_stop_positive
current_trailing_stop_positive_offset = self.trailing_stop_positive_offset * 2
if minutes > 1440:
current_trailing_only_offset_is_reached = False
current_trailing_stop_positive_offset = self.trailing_stop_positive_offset
# if zone == 1:
# ----- 5) Calcul du trailing stop dynamique -----
# Exemple : offset=0.321 => stop à +24.8%
trailing_stop = max_profit * (1.0 - current_trailing_stop_positive)
baisse = 0
if max_profit:
baisse = (max_profit - profit) / max_profit
if minutes % 12 == 0:
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🟢 CURRENT", #🔴 CURRENT" if self.pairs[pair]['stop'] or last_candle['stop_buying'] else "
dispo=dispo,
pair=pair,
rate=last_candle['close'],
trade_type=f"{round(profit, 2)} {round(max_profit, 2)} {round(trailing_stop,2)} {minutes}",
profit=round(profit, 2),
buys=count_of_buys,
stake=0
)
# if last_candle['sma24_deriv1'] > 0 : #and minutes < 180 and baisse < 30: # and last_candle['sma5_deriv1'] > -0.15:
# if (minutes < 180):
# return None
# if (minutes > 1440 and last_candle['sma60_deriv1'] > 0) :
# return None
# ----- 4) OFFSET : faut-il attendre de dépasser trailing_stop_positive_offset ? -----
if current_trailing_only_offset_is_reached:
# Max profit pas atteint ET perte < 2 * current_trailing_stop_positive
if max_profit < min(2, current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain']))\
and (max_profit > current_trailing_stop_positive_offset): #2 * current_trailing_stop_positive:
return None # ne pas activer le trailing encore
# Sinon : trailing actif dès le début
# ----- 6) Condition de vente -----
if 0 < profit <= trailing_stop and last_candle['mid'] < last_candle['sma5']:
return f"stop_{count_of_buys}_{self.pairs[pair]['has_gain']}"
return None
def informative_pairs(self):
# get access to all pairs available in whitelist.
pairs = self.dp.current_whitelist()
informative_pairs = [(pair, '1h') for pair in pairs]
informative_pairs += [(pair, '1d') for pair in pairs]
return informative_pairs
def populate1hIndicators(self, df: pd.DataFrame, metadata: dict) -> pd.DataFrame:
# --- WEEKLY LEVELS ---
# semaine précédente = semaine ISO différente
df["week"] = df.index.isocalendar().week
df["year"] = df.index.year
df["weekly_low"] = (
df.groupby(["year", "week"])["low"]
.transform("min")
.shift(1) # décalé -> pas regarder la semaine en cours
)
df["weekly_high"] = (
df.groupby(["year", "week"])["high"]
.transform("max")
.shift(1)
)
# Définition simple d'une zone de demande hebdo :
# bas + 25% de la bougie => modifiable
df["weekly_demand_zone_low"] = df["weekly_low"]
df["weekly_demand_zone_high"] = df["weekly_low"] * 1.025
# --- MONTHLY LEVELS ---
df["month"] = df.index.month
df["monthly_low"] = (
df.groupby(["year", "month"])["low"]
.transform("min")
.shift(1) # mois précédent uniquement
)
df["monthly_high"] = (
df.groupby(["year", "month"])["high"]
.transform("max")
.shift(1)
)
df["monthly_demand_zone_low"] = df["monthly_low"]
df["monthly_demand_zone_high"] = df["monthly_low"] * 1.03
return df
# ----- SIGNALS SIMPLES POUR EXEMPLE -----
# def populate_buy_trend(self, df: pd.DataFrame, metadata: dict) -> pd.DataFrame:
# df["buy"] = 0
#
# # Exemple : acheter si le prix tape la zone de demande hebdomadaire
# df.loc[
# (df["close"] <= df["weekly_demand_zone_high"]) &
# (df["close"] >= df["weekly_demand_zone_low"]),
# "buy"
# ] = 1
#
# return df
#
# def populate_sell_trend(self, df: pd.DataFrame, metadata: dict) -> pd.DataFrame:
# df["sell"] = 0
#
# # Exemple : vendre sur retour au weekly_high précédent
# df.loc[df["close"] >= df["weekly_high"], "sell"] = 1
#
# return df
def rsi_trend_probability(self, dataframe, short=6, long=12):
dataframe = dataframe.copy()
dataframe['rsi_short'] = talib.RSI(dataframe['mid'], short)
dataframe['rsi_long'] = talib.RSI(dataframe['mid'], long)
dataframe['cross_soft'] = np.tanh((dataframe['rsi_short'] - dataframe['rsi_long']) / 7)
dataframe['gap'] = (dataframe['rsi_short'] - dataframe['rsi_long']) / 100
dataframe['trend'] = (dataframe['rsi_long'] - 50) / 50
dataframe['rtp'] = (
0.6 * dataframe['cross_soft'] +
0.25 * dataframe['gap'] +
0.15 * dataframe['trend']
).clip(-1, 1)
return dataframe
import pandas as pd
def to_utc_ts(self, x):
return pd.to_datetime(x, utc=True)
# suppose self.btc_ath_history exists (liste de dict)
def get_last_ath_before_candle(self, last_candle):
candle_date = self.to_utc_ts(last_candle['date']) # ou to_utc_ts(last_candle.name)
best = None
for a in self.btc_ath_history: #getattr(self, "btc_ath_history", []):
ath_date = self.to_utc_ts(a["date"])
if ath_date <= candle_date:
if best is None or ath_date > best[0]:
best = (ath_date, a["price_usd"])
return best[1] if best is not None else None

35
FrictradeLearning.json Normal file
View File

@@ -0,0 +1,35 @@
{
"strategy_name": "FrictradeLearning",
"params": {
"roi": {
"0": 10
},
"stoploss": {
"stoploss": -1.0
},
"trailing": {
"trailing_stop": false,
"trailing_stop_positive": 0.15,
"trailing_stop_positive_offset": 1,
"trailing_only_offset_is_reached": true
},
"max_open_trades": {
"max_open_trades": 20
},
"protection": {
"allow_decrease_rate": 0.4,
"first_adjust_param": 0.005,
"max_steps": 30
},
"buy": {
"hours_force": 44,
"indic_1h_force_buy": "sma5_deriv1_1h"
},
"sell": {
"offset_max": 6,
"offset_min": 27
}
},
"ft_stratparam_v": 1,
"export_time": "2025-12-15 19:03:21.177158+00:00"
}

2635
FrictradeLearning.py Normal file

File diff suppressed because it is too large Load Diff

25
Genetic.json Normal file
View File

@@ -0,0 +1,25 @@
{
"strategy_name": "Genetic",
"params": {
"roi": {
"0": 0.21029,
"11": 0.05876,
"57": 0.02191,
"281": 0
},
"stoploss": {
"stoploss": -1.0
},
"max_open_trades": {
"max_open_trades": 80
},
"trailing": {
"trailing_stop": true,
"trailing_stop_positive": 0.028,
"trailing_stop_positive_offset": 0.105,
"trailing_only_offset_is_reached": true
}
},
"ft_stratparam_v": 1,
"export_time": "2025-12-04 23:58:24.045587+00:00"
}

View File

@@ -160,7 +160,7 @@ class Genetic(IStrategy):
}
# Stoploss:
stoploss = -0.07693
stoploss = -1
# Optimal ticker interval for the strategy
ticker_interval = '2h'
@@ -359,4 +359,5 @@ class Genetic(IStrategy):
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return dataframe
return dataframe

View File

@@ -11,8 +11,13 @@
# --- Do not remove these libs ---
from freqtrade.strategy.interface import IStrategy
from datetime import timedelta, datetime
from freqtrade.persistence import Trade
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, stoploss_from_open,
IntParameter, IStrategy, merge_informative_pair, informative, stoploss_from_absolute)
from pandas import DataFrame
# --------------------------------
from datetime import timezone, timedelta
# Add your lib to import here
# import talib.abstract as ta
@@ -24,6 +29,38 @@ import numpy as np
class GodStra(IStrategy):
position_adjustment_enable = True
columns_logged = False
pairs = {
pair: {
"first_buy": 0,
"last_buy": 0.0,
"last_min": 999999999999999.5,
"last_max": 0,
"trade_info": {},
"max_touch": 0.0,
"last_sell": 0.0,
'count_of_buys': 0,
'current_profit': 0,
'expected_profit': 0,
'previous_profit': 0,
"last_candle": {},
"last_count_of_buys": 0,
'base_stake_amount': 0,
'stop_buy': False,
'last_date': 0,
'stop': False,
'max_profit': 0,
'first_amount': 0,
'total_amount': 0,
'has_gain': 0,
'force_sell': False,
'force_buy': False
}
for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC",
"BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"]
}
# 5/66: 9 trades. 8/0/1 Wins/Draws/Losses. Avg profit 21.83%. Median profit 35.52%. Total profit 1060.11476586 USDT ( 196.50Σ%). Avg duration 3440.0 min. Objective: -7.06960
# +--------+---------+----------+------------------+--------------+-------------------------------+----------------+-------------+
# | Best | Epoch | Trades | Win Draw Loss | Avg profit | Profit | Avg duration | Objective |
@@ -67,7 +104,7 @@ class GodStra(IStrategy):
trailing_stop_positive_offset = 0.2684
trailing_only_offset_is_reached = True
# Buy hypers
timeframe = '12h'
timeframe = '1m'
print('Add {\n\t"method": "AgeFilter",\n\t"min_days_listed": 30\n},\n to your pairlists in config (Under StaticPairList)')
def dna_size(self, dct: dict):
@@ -169,3 +206,150 @@ class GodStra(IStrategy):
'sell'] = 1
return dataframe
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float,
max_stake: float, **kwargs):
# ne rien faire si ordre deja en cours
print('ici')
if trade.has_open_orders:
# self.printLog("skip open orders")
return None
if (self.wallets.get_available_stake_amount() < 10): # or trade.stake_amount >= max_stake:
return 0
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
before_last_candle = dataframe.iloc[-2].squeeze()
# prépare les données
current_time = current_time.astimezone(timezone.utc)
open_date = trade.open_date.astimezone(timezone.utc)
dispo = round(self.wallets.get_available_stake_amount())
hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
days_since_first_buy = (current_time - trade.open_date_utc).days
hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
count_of_buys = trade.nr_of_successful_entries
current_time_utc = current_time.astimezone(timezone.utc)
open_date = trade.open_date.astimezone(timezone.utc)
days_since_open = (current_time_utc - open_date).days
pair = trade.pair
profit = trade.calc_profit(current_rate) #round(current_profit * trade.stake_amount, 1)
last_lost = self.getLastLost(last_candle, pair)
pct_first = 0
total_counts = sum(
pair_data['count_of_buys'] for pair_data in self.pairs.values() if not self.getShortName(pair) == 'BTC')
if self.pairs[pair]['first_buy']:
pct_first = self.getPctFirstBuy(pair, last_candle)
lim = 0.3
if (len(dataframe) < 1):
# self.printLog("skip dataframe")
return None
# Dernier prix d'achat réel (pas le prix moyen)
last_fill_price = self.pairs[trade.pair]['last_buy'] #trade.open_rate # remplacé juste après ↓
# if len(trade.orders) > 0:
# # On cherche le dernier BUY exécuté
# buy_orders = [o for o in trade.orders if o.is_buy and o.status == "closed"]
# if buy_orders:
# last_fill_price = buy_orders[-1].price
# baisse relative
dca_threshold = 0.0025 * count_of_buys
decline = (last_fill_price - current_rate) / last_fill_price
increase = - decline
# if decline >= self.dca_threshold:
# # Exemple : on achète 50% du montant du dernier trade
# last_amount = buy_orders[-1].amount if buy_orders else 0
# stake_amount = last_amount * current_rate * 0.5
# return stake_amount
condition = last_candle['percent'] > 0 #and last_candle['sma24_deriv1'] > 0
limit_buy = 40
# or (last_candle['close'] <= last_candle['min180'] and hours > 3)
if (decline >= dca_threshold) and condition:
print('decline')
try:
if self.pairs[pair]['has_gain'] and profit > 0:
self.pairs[pair]['force_sell'] = True
self.pairs[pair]['previous_profit'] = profit
return None
max_amount = self.config.get('stake_amount') * 2.5
stake_amount = min(min(max_amount, self.wallets.get_available_stake_amount()),
self.adjust_stake_amount(pair, last_candle))
# print(f"profit={profit} previous={self.pairs[pair]['previous_profit']} count_of_buys={trade.nr_of_successful_entries}")
if stake_amount > 0:
self.pairs[pair]['previous_profit'] = profit
trade_type = "Loss " + (last_candle['enter_tag'] if last_candle['enter_long'] == 1 else '')
self.pairs[trade.pair]['count_of_buys'] += 1
self.pairs[pair]['total_amount'] += stake_amount
# self.log_trade(
# last_candle=last_candle,
# date=current_time,
# action="🟧 Loss -",
# dispo=dispo,
# pair=trade.pair,
# rate=current_rate,
# trade_type=trade_type,
# profit=round(profit, 1),
# buys=trade.nr_of_successful_entries + 1,
# stake=round(stake_amount, 2)
# )
self.pairs[trade.pair]['last_buy'] = current_rate
self.pairs[trade.pair]['max_touch'] = last_candle['close']
self.pairs[trade.pair]['last_candle'] = last_candle
# df = pd.DataFrame.from_dict(self.pairs, orient='index')
# colonnes_a_exclure = ['last_candle', 'stop',
# 'trade_info', 'last_date', 'expected_profit', 'last_count_of_buys', 'base_stake_amount', 'stop_buy']
# df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure)
# # df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit']
#
# self.printLog(df_filtered)
return stake_amount
return None
except Exception as exception:
self.printLog(exception)
return None
if current_profit > dca_threshold and (increase >= dca_threshold and self.wallets.get_available_stake_amount() > 0):
print('increase')
try:
self.pairs[pair]['previous_profit'] = profit
stake_amount = max(20, min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle)))
if stake_amount > 0:
self.pairs[pair]['has_gain'] += 1
trade_type = 'Gain +' + (last_candle['enter_tag'] if last_candle['enter_long'] == 1 else '')
self.pairs[trade.pair]['count_of_buys'] += 1
self.pairs[pair]['total_amount'] += stake_amount
# self.log_trade(
# last_candle=last_candle,
# date=current_time,
# action="🟡 Gain +",
# dispo=dispo,
# pair=trade.pair,
# rate=current_rate,
# trade_type='Gain',
# profit=round(profit, 1),
# buys=trade.nr_of_successful_entries + 1,
# stake=round(stake_amount, 2)
# )
self.pairs[trade.pair]['last_buy'] = current_rate
self.pairs[trade.pair]['max_touch'] = last_candle['close']
self.pairs[trade.pair]['last_candle'] = last_candle
return stake_amount
return None
except Exception as exception:
self.printLog(exception)
return None
return None

View File

@@ -14,7 +14,10 @@ import pandas as pd # noqa
from pandas import DataFrame
from skopt.space import Categorical, Dimension, Integer, Real # noqa
from freqtrade.optimize.hyperopt_interface import IHyperOpt
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, stoploss_from_open,
IntParameter, IStrategy, merge_informative_pair, informative, stoploss_from_absolute)
# from freqtrade.optimize.hyperopt_interface import IHyperOpt
# --------------------------------
# Add your lib to import here
@@ -52,7 +55,7 @@ GodGenes = ["open", "high", "low", "close", "volume", "volume_adi", "volume_obv"
"others_dr", "others_dlr", "others_cr"]
class GodStraHo(IHyperOpt):
class GodStraHo(IStrategy):
@staticmethod
def indicator_space() -> List[Dimension]:

53
GodStraJD.json Normal file
View File

@@ -0,0 +1,53 @@
{
"strategy_name": "GodStraJD",
"params": {
"roi": {
"0": 0.598,
"644": 0.166,
"3269": 0.115,
"7289": 0
},
"max_open_trades": {
"max_open_trades": 80
},
"buy": {
"buy_crossed_indicator0": "WMA-100",
"buy_crossed_indicator1": "KAMA-110",
"buy_crossed_indicator2": "CDLKICKING-55",
"buy_indicator0": "MACD-0-50",
"buy_indicator1": "SAREXT-15",
"buy_indicator2": "DEMA-12",
"buy_operator0": "<R",
"buy_operator1": "C",
"buy_operator2": "D",
"buy_real_num0": 0.7,
"buy_real_num1": 0.7,
"buy_real_num2": 0.7
},
"sell": {
"sell_crossed_indicator0": "CDLDARKCLOUDCOVER-15",
"sell_crossed_indicator1": "CDLHANGINGMAN-6",
"sell_crossed_indicator2": "CDLMATHOLD-55",
"sell_indicator0": "MEDPRICE-15",
"sell_indicator1": "T3-100",
"sell_indicator2": "CDLDOJISTAR-12",
"sell_operator0": "=R",
"sell_operator1": "DT",
"sell_operator2": "CA",
"sell_real_num0": 0.7,
"sell_real_num1": 0.7,
"sell_real_num2": 0.6
},
"stoploss": {
"stoploss": -0.122
},
"trailing": {
"trailing_stop": true,
"trailing_stop_positive": 0.058,
"trailing_stop_positive_offset": 0.097,
"trailing_only_offset_is_reached": true
}
},
"ft_stratparam_v": 1,
"export_time": "2025-12-04 23:29:46.366351+00:00"
}

View File

@@ -470,7 +470,7 @@ class GodStraJD(IStrategy):
# Stoploss:
stoploss = -0.128
# Buy hypers
timeframe = '4h'
timeframe = '1m'
# Trailing stoploss
trailing_stop = True

View File

@@ -474,7 +474,7 @@ class GodStraJD3_1(IStrategy):
# Stoploss:
stoploss = -1
# Buy hypers
timeframe = '4h'
timeframe = '1m'
# Trailing stoploss
trailing_stop = True

View File

@@ -10,7 +10,7 @@ from freqtrade.persistence import Trade
from freqtrade.strategy.parameters import CategoricalParameter, DecimalParameter
from numpy.lib import math
from freqtrade.strategy.interface import IStrategy, SellCheckTuple
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
# --------------------------------

View File

@@ -668,8 +668,7 @@ class GodStraJD3_4(IStrategy):
# # Use default stake amount.
# return proposed_stake
def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float,
current_profit: float, **kwargs):
def custom_exit(self, pair, trade, current_time, current_rate, current_profit, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
previous_last_candle = dataframe.iloc[-2].squeeze()
@@ -971,8 +970,6 @@ class GodStraJD3_4(IStrategy):
if conditions:
dataframe.loc[
(reduce(lambda x, y: x & y, conditions)
# & (dataframe['percent_4h'] > 0)
& (dataframe['percent3_4h'] <= 0)
),
'buy']=1
# print(len(dataframe.keys()))

View File

@@ -10,7 +10,7 @@ from freqtrade.persistence import Trade
from freqtrade.strategy.parameters import CategoricalParameter, DecimalParameter, IntParameter
from numpy.lib import math
from freqtrade.strategy.interface import IStrategy, SellCheckTuple
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
# --------------------------------

View File

@@ -10,7 +10,7 @@ from freqtrade.persistence import Trade
from freqtrade.strategy.parameters import CategoricalParameter, DecimalParameter, IntParameter
from numpy.lib import math
from freqtrade.strategy.interface import IStrategy, SellCheckTuple
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
# --------------------------------

View File

@@ -27,7 +27,7 @@ import numpy as np
from random import shuffle
# TODO: this gene is removed 'MAVP' cuz or error on periods
import user_data.strategies.custom_indicators as csa
# import user_data.strategies.custom_indicators as csa
all_god_genes = {
'Overlap Studies': {

View File

@@ -86,7 +86,7 @@ class HammerReversalStrategy(IStrategy):
}
stoploss = -1
timeframe = '1h'
timeframe = '1m'
position_adjustment_enable = True
columns_logged = False
max_entry_position_adjustment = 20

View File

@@ -220,10 +220,10 @@ class Ishimoku_6(IStrategy):
def bot_loop_start(self, **kwargs) -> None:
inf_tf = '5m'
pairs = self.dp.current_whitelist()
print("Calcul des pairs informatives")
# print("Calcul des pairs informatives")
for pairname in pairs:
self.stop_buying[pairname] = True
print("Fin Calcul des pairs informatives")
# print("Fin Calcul des pairs informatives")
# def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
# proposed_stake: float, min_stake: float, max_stake: float,

265
Simple.py Normal file
View File

@@ -0,0 +1,265 @@
# Zeus Strategy: First Generation of GodStra Strategy with maximum
# AVG/MID profit in USDT
# Author: @Mablue (Masoud Azizi)
# github: https://github.com/mablue/
# IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta)
# freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --spaces buy sell roi --strategy Zeus
# --- Do not remove these libs ---
from datetime import timedelta, datetime
from freqtrade.persistence import Trade
from freqtrade.strategy import (BooleanParameter, CategoricalParameter, DecimalParameter, stoploss_from_open,
IntParameter, IStrategy, merge_informative_pair, informative, stoploss_from_absolute)
import pandas as pd
import numpy as np
from pandas import DataFrame
from typing import Optional, Union, Tuple
from typing import List
import logging
import configparser
from technical import pivots_points
# --------------------------------
# Add your lib to import here test git
import ta
import talib.abstract as talib
import freqtrade.vendor.qtpylib.indicators as qtpylib
import requests
from datetime import timezone, timedelta
from scipy.signal import savgol_filter
from ta.trend import SMAIndicator, EMAIndicator, MACD, ADXIndicator
from collections import Counter
logger = logging.getLogger(__name__)
from tabulate import tabulate
# Couleurs ANSI de base
RED = "\033[31m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
BLUE = "\033[34m"
MAGENTA = "\033[35m"
CYAN = "\033[36m"
RESET = "\033[0m"
def pprint_df(dframe):
print(tabulate(dframe, headers='keys', tablefmt='psql', showindex=False))
def normalize(df):
df = (df - df.min()) / (df.max() - df.min())
return df
"""
SMA z-score derivative strategy with trailing exit (large).
- timeframe: 1h
- sma5, relative derivatives, z-score normalization (rolling z over z_window)
- smoothing: ewm(span=5) on z-scores
- entry: z_d1_smooth > entry_z1 AND z_d2_smooth > entry_z2
- exit: inversion (z_d1_smooth < 0) AND retrace from highest since entry >= trailing_stop
"""
class Simple(IStrategy):
levels = [1, 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
startup_candle_count = 12 * 24 * 2
# ROI table:
minimal_roi = {
"0": 10
}
stakes = 40
# Stoploss:
stoploss = -1 # 0.256
# Custom stoploss
use_custom_stoploss = True
# Buy hypers
timeframe = '1h'
max_open_trades = 5
max_amount = 40
# DCA config
position_adjustment_enable = True
# Parameters (tweakable)
z_window = 50 # window for rolling mean/std to compute zscore
entry_z1 = 0.1 # threshold on z-score of first derivative
entry_z2 = 0.1 # threshold on z-score of second derivative
min_volume = 0.0 # minimal volume to accept an entry
min_relative_d1 = 1e-6 # clip tiny d1 relative values to reduce noise
# Trailing parameters for "large" trailing requested
trailing_stop_pct = 0.05 # 5% retracement from highest since entry
# Smoothing for z-scores
ewm_span = 5
# Plot config: price + sma5 + markers + slope/accel subplots
plot_config = {
"main_plot": {
"close": {"color": "blue"},
"sma5": {"color": "orange"},
},
"subplots": {
"slope_and_accel": {
"z_d1": {"color": "green"},
"z_d2": {"color": "red"},
}
},
# Markers (Freqtrade charting supports markers via these keys)
"markers": [
# buy marker: '^' green when enter_long==1
{"type": "buy", "column": "enter_long", "marker": "^", "color": "green", "markersize": 10},
# sell marker: 'v' red when exit_long==1
{"type": "sell", "column": "exit_long", "marker": "v", "color": "red", "markersize": 10},
],
}
def informative_pairs(self):
return []
def _zscore(self, series: pd.Series, window: int) -> pd.Series:
mean = series.rolling(window=window, min_periods=3).mean()
std = series.rolling(window=window, min_periods=3).std(ddof=0)
z = (series - mean) / std
z = z.replace([np.inf, -np.inf], np.nan)
return z
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe
# SMA(5)
df['sma5'] = df['close'].rolling(5, min_periods=1).mean()
# Absolute derivatives
df['sma5_d1'] = df['sma5'].diff().rolling(5).mean()
df['sma5_d2'] = df['sma5_d1'].diff().rolling(5).mean()
# Relative derivatives (percentage-like)
eps = 1e-9
df['sma5_d1_rel'] = df['sma5_d1'] / (df['sma5'].shift(1).replace(0, np.nan) + eps)
df['sma5_d2_rel'] = df['sma5_d2'] / (df['sma5'].shift(2).replace(0, np.nan) + eps)
# Clip micro-noise
df.loc[df['sma5_d1_rel'].abs() < self.min_relative_d1, 'sma5_d1_rel'] = 0.0
df.loc[df['sma5_d2_rel'].abs() < self.min_relative_d1, 'sma5_d2_rel'] = 0.0
# Z-scores on relative derivatives
df['z_d1'] = self._zscore(df['sma5_d1_rel'], self.z_window)
df['z_d2'] = self._zscore(df['sma5_d2_rel'], self.z_window)
# Smoothing z-scores with EWM to reduce jitter
df['z_d1_smooth'] = df['z_d1'].ewm(span=self.ewm_span, adjust=False).mean()
df['z_d2_smooth'] = df['z_d2'].ewm(span=self.ewm_span, adjust=False).mean()
# Prepare marker columns (for plots). They will be filled in populate_entry_trend/populate_exit_trend
df['enter_long'] = 0
df['exit_long'] = 0
return df
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
# Use last closed candle for signals -> shift(1)
cond_entry = (
(df['z_d1'] > self.entry_z1) &
(df['z_d2'] > self.entry_z2) &
(df['volume'].shift(1) > self.min_volume)
)
df.loc[cond_entry, 'enter_long'] = 1
# Ensure others are explicitly zero (for clean plotting)
df.loc[~cond_entry, 'enter_long'] = 0
return df
def custom_exit(self, pair: str, trade: Trade, current_time, current_rate, current_profit, **kwargs) -> \
Optional[str]:
"""
Exit policy (mode C - trailing large):
- Must detect inversion: z_d1_smooth < 0 on last closed candle
- Compute highest close since trade entry (inclusive)
- If price has retraced >= trailing_stop_pct from that highest point and we're in inversion -> exit
"""
df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last = df.iloc[-1].squeeze()
z1 = last.get('z_d1_smooth', None)
if z1 is None:
return None
# Only consider exits when inversion detected (z1 < 0)
inversion = (z1 < 0)
if not inversion:
return None
# If we don't have profit info, be conservative
if current_profit is None:
return None
# Determine highest close since entry
highest_since_entry = None
try:
# trade.open_date_utc is available: find rows after that timestamp
# df.index is expected to be pd.DatetimeIndex in UTC or local; convert safely
if hasattr(trade, 'open_date_utc') and trade.open_date_utc:
# pandas comparison: ensure same tz awareness
entry_time = pd.to_datetime(trade.open_date_utc)
# select rows with index >= entry_time
mask = df.index >= entry_time
if mask.any():
highest_since_entry = df.loc[mask, 'close'].max()
# fallback: use trade.open_rate or the max over full df
except Exception as e:
logger.debug(f"Couldn't compute highest_since_entry from open_date_utc: {e}")
if highest_since_entry is None:
# fallback: use the maximum close in the entire provided dataframe slice
highest_since_entry = df['close'].max() if not df['close'].empty else current_rate
# Calculate retracement ratio from the highest
if highest_since_entry and highest_since_entry > 0:
retrace = 1.0 - (current_rate / highest_since_entry)
else:
retrace = 0.0
# Exit if:
# - currently in profit AND
# - retracement >= trailing_stop_pct (i.e. price has fallen enough from top since entry) AND
# - inversion detected (z1 < 0)
if (current_profit > 0) and (retrace >= self.trailing_stop_pct):
# Mark the dataframe for plotting (if possible)
# Note: freqtrade expects strategies to set exit flags in populate_exit_trend,
# but we set exit via custom_exit return reason; plotting will read exit_long if populated.
return "zscore"
# Otherwise, do not exit yet
return None
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
For plotting only: mark exit points where our logic would trigger.
This is approximate: we mark an exit when z_d1_smooth < 0 and the price has retraced >= trailing_stop_pct
based on the available dataframe window (best-effort).
"""
df = dataframe
# df['exit_long'] = 0
#
# # compute highest close since each possible entry (best-effort: use rolling max up to current index)
# rolling_max = df['close'].cummax()
#
# # retracement relative to rolling max
# retrace = 1.0 - (df['close'] / rolling_max.replace(0, np.nan))
#
# # mark exits where inversion and retrace >= threshold
# cond_exit = (df['z_d1_smooth'] < 0) & (retrace >= self.trailing_stop_pct)
# # shift by 0: we mark the candle where the exit condition appears
# df.loc[cond_exit, 'exit_long'] = 1
return df

633
Simple_01.py Normal file
View File

@@ -0,0 +1,633 @@
# sma_zscore_trailing_dca.py
from freqtrade.strategy.interface import IStrategy
from freqtrade.persistence import Trade
from pandas import DataFrame
import pandas as pd
import numpy as np
from typing import Optional
import logging
from datetime import timedelta, datetime
import talib.abstract as talib
logger = logging.getLogger(__name__)
class Simple_01(IStrategy):
"""
SMA z-score derivative strategy with trailing exit and intelligent DCA (large pullback).
- timeframe: 1h
- sma5, relative derivatives, z-score normalization (rolling z over z_window)
- smoothing: ewm(span=5) on z-scores
- entry: z_d1_smooth > entry_z1 AND z_d2_smooth > entry_z2
- exit: inversion (z_d1_smooth < 0) AND retrace from highest since entry >= trailing_stop_pct
- adjust_trade_position: add to position on controlled pullback (large = 4-6%)
"""
timeframe = "1h"
startup_candle_count = 24
# Risk mgmt (we handle exit in custom_exit)
minimal_roi = {"0": 0.99}
stoploss = -0.99
use_custom_exit = True
position_adjustment_enable = True
columns_logged = False
# Parameters
z_window = 10 # window for rolling mean/std to compute zscore
entry_z1 = 0.1 # threshold on z-score of first derivative
entry_z2 = 0 # threshold on z-score of second derivative
min_volume = 0.0 # minimal volume to accept an entry
min_relative_d1 = 1e-6 # clip tiny d1 relative values to reduce noise
# Trailing parameters for "large" trailing (exit)
trailing_stop_pct = 0.01 # 5% retracement from highest since entry
# Smoothing for z-scores
ewm_span = 5
# DCA intelligent (adjust_trade_position) parameters for "large" pullback
dca_enabled = True
# Pullback bounds (large): allow adding when retrace is between 4% and 6%
dca_pullback_min = 0.01
dca_pullback_max = 0.02
# Maximum number of adds per trade (to avoid infinite pyramiding)
dca_max_adds = 8
# Percentage of base position to add on each reinforcement (50% of original size by default)
dca_add_ratio = 0.5
# Require momentum still positive to add
dca_require_z1_positive = True
dca_require_z2_positive = True
# Do not add if current_profit < min_profit_to_add (avoid averaging down when deep in loss)
min_profit_to_add = -0.02 # allow small loss but not big drawdown
pairs = {
pair: {
"first_buy": 0,
"last_buy": 0.0,
"first_amount": 0.0,
"last_min": 999999999999999.5,
"last_max": 0,
"trade_info": {},
"max_touch": 0.0,
"last_sell": 0.0,
'count_of_buys': 0,
'current_profit': 0,
'expected_profit': 0,
"last_candle": {},
"last_trade": None,
"last_count_of_buys": 0,
'base_stake_amount': 0,
'stop_buy': False,
'last_date': 0,
'stop': False,
'max_profit': 0,
'last_palier_index': -1,
'total_amount': 0,
'has_gain': 0,
'force_sell': False,
'force_buy': False
}
for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC",
"BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"]
}
# Plot config
plot_config = {
"main_plot": {
"close": {"color": "blue"},
"sma5": {"color": "orange"},
},
"subplots": {
"slope_and_accel": {
"z_d1_smooth": {"color": "green"},
"z_d2_smooth": {"color": "red"},
},
"sma_deriv": {
"sma5_deriv1_rel": {"color": "green"},
"sma5_deriv2_rel": {"color": "red"},
},
"rsi": {
"rsi": {"color": "blue"}
}
},
"markers": [
{"type": "buy", "column": "enter_long", "marker": "^", "color": "green", "markersize": 10},
{"type": "sell", "column": "exit_long", "marker": "v", "color": "red", "markersize": 10},
],
}
def informative_pairs(self):
return []
def _zscore(self, series: pd.Series, window: int) -> pd.Series:
mean = series.rolling(window=window, min_periods=3).mean()
std = series.rolling(window=window, min_periods=3).std(ddof=0)
z = (series - mean) / std
z = z.replace([np.inf, -np.inf], np.nan)
return z
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe
# SMA(5)
df['sma5'] = df['close'].rolling(5, min_periods=1).mean()
# Absolute derivatives
df['sma5_deriv1'] = df['sma5'].diff()
df['sma5_deriv2'] = df['sma5_deriv1'].diff()
# Relative derivatives (percentage-like)
eps = 1e-9
df['sma5_deriv1_rel'] = df['sma5_deriv1'] / (df['sma5'].shift(1).replace(0, np.nan) + eps)
df['sma5_deriv2_rel'] = df['sma5_deriv2'] / (df['sma5'].shift(2).replace(0, np.nan) + eps)
# Clip micro-noise
df.loc[df['sma5_deriv1_rel'].abs() < self.min_relative_d1, 'sma5_deriv1_rel'] = 0.0
df.loc[df['sma5_deriv2_rel'].abs() < self.min_relative_d1, 'sma5_deriv2_rel'] = 0.0
# Z-scores on relative derivatives
df['z_d1'] = self._zscore(df['sma5_deriv1_rel'], self.z_window)
df['z_d2'] = self._zscore(df['sma5_deriv2_rel'], self.z_window)
# Smoothing z-scores with EWM to reduce jitter
df['z_d1_smooth'] = df['z_d1'].ewm(span=self.ewm_span, adjust=False).mean()
df['z_d2_smooth'] = df['z_d2'].ewm(span=self.ewm_span, adjust=False).mean()
# Prepare marker columns (for plots)
df['enter_long'] = 0
df['exit_long'] = 0
df['rsi'] = talib.RSI(df['close'], timeperiod=14)
df['max_rsi_12'] = talib.MAX(df['rsi'], timeperiod=12)
df['min_rsi_12'] = talib.MIN(df['rsi'], timeperiod=12)
# self.calculeDerivees(df, 'rsi', horizon=12)
return df
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe
# Use last closed candle for signals -> shift(1)
cond_entry = (
(df['z_d1_smooth'] > self.entry_z1) &
(df['z_d2_smooth'] > self.entry_z2) &
(df['max_rsi_12'] < 70) &
(df['volume'] > self.min_volume)
)
df.loc[cond_entry, 'enter_long'] = 1
df.loc[~cond_entry, 'enter_long'] = 0
return df
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe
# df['exit_long'] = 0
#
# # compute rolling max (best-effort for plotting)
# rolling_max = df['close'].cummax()
# retrace = 1.0 - (df['close'] / rolling_max.replace(0, np.nan))
#
# cond_exit = (df['z_d1_smooth'] < 0) & (retrace >= self.trailing_stop_pct)
# df.loc[cond_exit, 'exit_long'] = 1
return df
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, rate: float,
time_in_force: str,
exit_reason: str, current_time, **kwargs, ) -> bool:
# allow_to_sell = (minutes > 30)
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
force = self.pairs[pair]['force_sell']
allow_to_sell = True #(last_candle['percent'] < 0) #or force
minutes = int(round((current_time - trade.date_last_filled_utc).total_seconds() / 60, 0))
if allow_to_sell:
self.trades = list()
self.pairs[pair]['last_count_of_buys'] = trade.nr_of_successful_entries # self.pairs[pair]['count_of_buys']
self.pairs[pair]['last_sell'] = rate
self.pairs[pair]['last_trade'] = trade
self.pairs[pair]['last_candle'] = last_candle
self.trades = list()
dispo = round(self.wallets.get_available_stake_amount())
print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} amount={amount} rate={rate} open_rate={trade.open_rate}")
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🟥Sell " + str(minutes),
pair=pair,
trade_type=exit_reason,
rate=last_candle['close'],
dispo=dispo,
profit=round(trade.calc_profit(rate, amount), 2)
)
self.pairs[pair]['max_profit'] = 0
self.pairs[pair]['force_sell'] = False
self.pairs[pair]['has_gain'] = 0
self.pairs[pair]['current_profit'] = 0
self.pairs[pair]['total_amount'] = 0
self.pairs[pair]['count_of_buys'] = 0
self.pairs[pair]['max_touch'] = 0
self.pairs[pair]['last_buy'] = 0
self.pairs[pair]['last_date'] = current_time
self.pairs[pair]['last_palier_index'] = -1
self.pairs[pair]['last_trade'] = trade
self.pairs[pair]['current_trade'] = None
return (allow_to_sell) | (exit_reason == 'force_exit')
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str,
current_time: datetime, entry_tag: Optional[str], **kwargs) -> bool:
minutes = 0
if self.pairs[pair]['last_date'] != 0:
minutes = round(int((current_time - self.pairs[pair]['last_date']).total_seconds() / 60))
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_2 = dataframe.iloc[-2].squeeze()
last_candle_3 = dataframe.iloc[-3].squeeze()
# val = self.getProbaHausse144(last_candle)
# allow_to_buy = True #(not self.stop_all) #& (not self.all_down)
allow_to_buy = not self.pairs[pair]['stop'] # and val > self.buy_val.value #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry')
# force = self.pairs[pair]['force_buy']
# if self.pairs[pair]['force_buy']:
# self.pairs[pair]['force_buy'] = False
# allow_to_buy = True
# else:
# if not self.should_enter_trade(pair, last_candle, current_time):
# allow_to_buy = False
if allow_to_buy:
self.trades = list()
self.pairs[pair]['first_buy'] = rate
self.pairs[pair]['last_buy'] = rate
self.pairs[pair]['max_touch'] = last_candle['close']
self.pairs[pair]['last_candle'] = last_candle
self.pairs[pair]['count_of_buys'] = 1
self.pairs[pair]['current_profit'] = 0
self.pairs[pair]['last_palier_index'] = -1
self.pairs[pair]['last_max'] = max(last_candle['close'], self.pairs[pair]['last_max'])
self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
dispo = round(self.wallets.get_available_stake_amount())
self.printLineLog()
stake_amount = self.adjust_stake_amount(pair, last_candle)
self.pairs[pair]['total_amount'] = stake_amount
self.log_trade(
last_candle=last_candle,
date=current_time,
action=("🟩Buy" if allow_to_buy else "Canceled") + " " + str(minutes),
pair=pair,
rate=rate,
dispo=dispo,
profit=0,
trade_type=entry_tag,
buys=1,
stake=round(stake_amount, 2)
)
return allow_to_buy
def custom_exit(self, pair: str, trade: Trade, current_time, current_rate, current_profit, **kwargs) -> Optional[str]:
df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = df.iloc[-1].squeeze()
self.pairs[pair]['last_max'] = max(last_candle['close'], self.pairs[pair]['last_max'])
self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
self.pairs[pair]['current_trade'] = trade
count_of_buys = trade.nr_of_successful_entries
profit = round(current_profit * trade.stake_amount, 1)
self.pairs[pair]['max_profit'] = max(self.pairs[pair]['max_profit'], profit)
max_profit = self.pairs[pair]['max_profit']
baisse = 0
if profit > 0:
baisse = 100 * abs(max_profit - profit) / max_profit
mx = max_profit / 5
self.pairs[pair]['count_of_buys'] = count_of_buys
self.pairs[pair]['current_profit'] = profit
dispo = round(self.wallets.get_available_stake_amount())
hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
days_since_first_buy = (current_time - trade.open_date_utc).days
hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
if hours % 4 == 0:
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🔴 CURRENT" if self.pairs[pair]['stop'] else "🟢 CURRENT",
dispo=dispo,
pair=pair,
rate=last_candle['close'],
trade_type='',
profit=profit,
buys='',
stake=0
)
z1 = last_candle.get('z_d1_smooth', None)
if z1 is None:
return None
if z1 >= 0:
return None
if current_profit is None:
return None
# highest close since entry
highest_since_entry = self.pairs[trade.pair]['max_touch']
# try:
# if hasattr(trade, 'open_date_utc') and trade.open_date_utc:
# entry_time = pd.to_datetime(trade.open_date_utc)
# mask = df.index >= entry_time
# if mask.any():
# highest_since_entry = df.loc[mask, 'close'].max()
# except Exception as e:
# logger.debug(f"Couldn't compute highest_since_entry: {e}")
#
# if highest_since_entry is None:
# highest_since_entry = df['close'].max() if not df['close'].empty else current_rate
if highest_since_entry and highest_since_entry > 0:
retrace = 1.0 - (current_rate / highest_since_entry)
else:
retrace = 0.0
z1 = last_candle.get('z_d1_smooth', None)
z2 = last_candle.get('z_d2_smooth', None)
if (current_profit > 0) and (current_profit >= self.trailing_stop_pct) and last_candle['sma5_deriv1'] < -0.002:
return str(count_of_buys) + '_' + "zscore"
self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch'])
return None
def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
# Calculer le minimum des 14 derniers jours
return self.config.get('stake_amount')
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float,
max_stake: float, **kwargs):
"""
DCA intelligent (mode C - 'large'):
- Only add if:
* DCA is enabled
* number of adds done so far < dca_max_adds
* retracement since highest_since_entry is between dca_pullback_min and dca_pullback_max
* momentum still positive (z_d1_smooth, z_d2_smooth) if required
* current_profit >= min_profit_to_add (avoid averaging down into large loss)
- Returns a dict describing the desired order for Freqtrade to place (common format).
Example returned dict: {'type': 'market', 'amount': 0.01}
"""
if not self.dca_enabled:
return None
pair = trade.pair
# Basic guards
if current_profit is None:
current_profit = 0.0
# Do not add if we're already deeply in loss
if current_profit < self.min_profit_to_add:
return None
df, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
last_candle = df.iloc[-1].squeeze()
# Compute highest close since entry
highest_since_entry = self.pairs[trade.pair]['last_buy']
last = df.iloc[-1]
z1 = last.get('z_d1_smooth', None)
z2 = last.get('z_d2_smooth', None)
# Count how many adds have been done for this trade.
# Trade.extra might contain meta; otherwise try trade.tags or use trade.open_rate/amount heuristics.
adds_done = trade.nr_of_successful_entries
# Calculate retracement since the highest
retrace = 0.0
if highest_since_entry and highest_since_entry > 0:
retrace = (last['close'] - highest_since_entry) / highest_since_entry
# logger.info(f"{pair} {current_rate} {current_time} {highest_since_entry} add: retrace={retrace:.4f}, adds_done={adds_done} z1={z1} z2={z2}")
# Enforce momentum requirements if requested
if self.dca_require_z1_positive and (z1 is None or z1 <= 0):
return None
if self.dca_require_z2_positive and (z2 is None or z2 <= 0):
return None
#
# try:
# meta = getattr(trade, 'meta', None) or {}
# adds_done = int(meta.get('adds_done', 0))
# except Exception:
# adds_done = 0
if adds_done >= self.dca_max_adds:
return None
# try:
# if hasattr(trade, 'open_date_utc') and trade.open_date_utc:
# entry_time = pd.to_datetime(trade.open_date_utc)
# mask = df.index >= entry_time
# if mask.any():
# highest_since_entry = df.loc[mask, 'close'].max()
# except Exception as e:
# logger.debug(f"adjust_trade_position: couldn't compute highest_since_entry: {e}")
#
# if highest_since_entry is None:
# highest_since_entry = df['close'].max() if not df['close'].empty else current_rate
# Check if retrace is inside the allowed DCA window (large)
if ((retrace >= self.dca_pullback_min) and (retrace <= self.dca_pullback_max)):
# Determine amount to add: a fraction of the original trade amount
# Try to get trade.amount (base asset amount). If not available, fall back to stake percentage
add_amount = None
try:
base_amount = self.config.get('stake_amount')
if base_amount:
add_amount = base_amount * self.dca_add_ratio
else:
# Fallback: attempt to compute amount from trade.open_rate and desired quote stake
# We'll propose to use a fraction of current rate worth (this is best-effort)
add_amount = None
except Exception:
add_amount = None
# If we couldn't compute an absolute amount, propose a relative size via a suggested stake (user must map)
if add_amount is None:
# Return a suggested instruction; adapt according to your freqtrade version.
suggested = {
'type': 'market',
'amount': None, # caller should compute actual amount from stake management
'note': f'suggest_add_ratio={self.dca_add_ratio}'
}
# logger.info(f"{pair} {current_rate} DCA suggestion (no absolute amount): retrace={retrace:.4f}, adds_done={adds_done}")
return None
dispo = round(self.wallets.get_available_stake_amount())
trade_type = last_candle['enter_tag'] if last_candle['enter_long'] == 1 else 'pct48'
self.pairs[trade.pair]['count_of_buys'] += 1
self.pairs[pair]['total_amount'] += add_amount
self.log_trade(
last_candle=last_candle,
date=current_time,
action="🟧 Loss -",
dispo=dispo,
pair=trade.pair,
rate=current_rate,
trade_type=trade_type,
profit=round(current_profit * trade.stake_amount, 1),
buys=trade.nr_of_successful_entries + 1,
stake=round(add_amount, 2)
)
self.pairs[trade.pair]['last_buy'] = current_rate
self.pairs[trade.pair]['max_touch'] = last_candle['close']
self.pairs[trade.pair]['last_candle'] = last_candle
# All checks passed -> create market order instruction
# logger.info(f"{pair} {current_rate} {current_time} {highest_since_entry} add: retrace={retrace:.4f}, adds_done={adds_done}, add_amount={add_amount:.8f}")
return add_amount
# Not in allowed retrace window -> no action
return None
def getPctFirstBuy(self, pair, last_candle):
return round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
def getPctLastBuy(self, pair, last_candle):
return round((last_candle['close'] - self.pairs[pair]['last_buy']) / self.pairs[pair]['last_buy'], 4)
def getPct60D(self, pair, last_candle):
return round((last_candle['max60'] - last_candle['min60']) / last_candle['max60'], 4)
def getPctClose60D(self, pair, last_candle):
if last_candle['close'] > last_candle['max12']:
return 1
if last_candle['close'] < last_candle['min12']:
return 0
return round(
(last_candle['close'] - last_candle['min12']) / (last_candle['max12'] - last_candle['min12']), 4)
def printLineLog(self):
self.printLog(
f"+{'-' * 18}+{'-' * 12}+{'-' * 5}+{'-' * 20}+{'-' * 9}+{'-' * 8}+{'-' * 12}+{'-' * 8}+{'-' * 13}+{'-' * 14}+{'-' * 9}{'-' * 9}+{'-' * 5}+{'-' * 7}+"
f"{'-' * 3}"
# "+{'-' * 3}+{'-' * 3}
f"+{'-' * 6}+{'-' * 7}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+{'-' * 5}+"
)
def printLog(self, str):
if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
return
if not self.dp.runmode.value in ('backtest', 'hyperopt', 'lookahead-analysis'):
logger.info(str)
else:
if not self.dp.runmode.value in ('hyperopt'):
print(str)
def log_trade(self, action, pair, date, trade_type=None, rate=None, dispo=None, profit=None, buys=None,
stake=None,
last_candle=None):
# Couleurs ANSI de base
RED = "\033[31m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
BLUE = "\033[34m"
MAGENTA = "\033[35m"
CYAN = "\033[36m"
RESET = "\033[0m"
# Afficher les colonnes une seule fois
if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
return
if self.columns_logged % 10 == 0:
self.printLog(
f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>8} | {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_max':>7}|{'Buys':>5}| {'Stake':>5} |"
f"Tdc|{'val':>6}| RSI |s201d|s5_1d|s5_2d|s51h|s52h"
)
self.printLineLog()
df = pd.DataFrame.from_dict(self.pairs, orient='index')
colonnes_a_exclure = ['last_candle', 'last_trade', 'last_palier_index',
'trade_info', 'last_date', 'expected_profit', 'last_count_of_buys',
'base_stake_amount', 'stop_buy']
df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure)
# df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit']
print(df_filtered)
self.columns_logged += 1
date = str(date)[:16] if date else "-"
limit = None
# if buys is not None:
# limit = round(last_rate * (1 - self.fibo[buys] / 100), 4)
rsi = ''
rsi_pct = ''
sma5_1d = ''
sma5_1h = ''
sma5 = str(sma5_1d) + ' ' + str(sma5_1h)
last_lost = '' #self.getLastLost(last_candle, pair)
if buys is None:
buys = ''
max_touch = '' # round(last_candle['max12'], 1) #round(self.pairs[pair]['max_touch'], 1)
pct_max = '' #self.getPctFirstBuy(pair, last_candle)
total_counts = str(buys) + '/' + str(
sum(pair_data['count_of_buys'] for pair_data in self.pairs.values()))
dist_max = '' #self.getDistMax(last_candle, pair)
val = 0 #self.getProbaHausseSma5d(last_candle)
pct60 = 0 #round(100 * self.getPct60D(pair, last_candle), 2)
color = GREEN if profit > 0 else RED
# color_sma20 = GREEN if last_candle['sma20_deriv1'] > 0 else RED
# color_sma5 = GREEN if last_candle['mid_smooth_5_deriv1'] > 0 else RED
# color_sma5_2 = GREEN if last_candle['mid_smooth_5_deriv2'] > 0 else RED
# color_sma5_1h = GREEN if last_candle['sma5_deriveriv1'] > 0 else RED
# color_sma5_2h = GREEN if last_candle['sma5_deriveriv2'] > 0 else RED
last_max = int(self.pairs[pair]['last_max']) if self.pairs[pair]['last_max'] > 1 else round(
self.pairs[pair]['last_max'], 3)
last_min = int(self.pairs[pair]['last_min']) if self.pairs[pair]['last_min'] > 1 else round(
self.pairs[pair]['last_min'], 3)
profit = str(profit) + '/' + str(round(self.pairs[pair]['max_profit'], 2))
# 🟢 Dérivée 1 > 0 et dérivée 2 > 0: tendance haussière qui saccélère.
# 🟡 Dérivée 1 > 0 et dérivée 2 < 0: tendance haussière qui ralentit → essoufflement potentiel.
# 🔴 Dérivée 1 < 0 et dérivée 2 < 0: tendance baissière qui saccélère.
# 🟠 Dérivée 1 < 0 et dérivée 2 > 0: tendance baissière qui ralentit → possible bottom.
# tdc last_candle['tendency_12']
self.printLog(
f"| {date:<16} |{action:<10} | {pair[0:3]:<3} | {trade_type or '-':<18} |{rate or '-':>9}| {dispo or '-':>6} "
f"|{color}{profit or '-':>10}{RESET}| {pct_max or '-':>6} | {round(self.pairs[pair]['max_touch'], 2) or '-':>11} | {last_lost or '-':>12} "
f"| {last_max or '-':>7} | {last_min or '-':>7} |{total_counts or '-':>5}|{stake or '-':>7}"
f"|{'-':>3}|"
f"{round(val, 1) or '-' :>6}|"
# f"{round(last_candle['rsi'], 0):>7}|{color_sma20}{round(last_candle['sma20_deriv1'], 2):>5}{RESET}"
# f"|{color_sma5}{round(last_candle['mid_smooth_5_deriv1'], 2):>5}{RESET}|{color_sma5_2}{round(last_candle['mid_smooth_5_deriv2'], 2):>5}{RESET}"
# f"|{color_sma5_1h}{round(last_candle['sma5_deriveriv1'], 2):>5}{RESET}|{color_sma5_2h}{round(last_candle['sma5_deriveriv2'], 2):>5}{RESET}"
# f"|{last_candle['min60']}|{last_candle['max60']}"
)

View File

@@ -1,7 +1,7 @@
import numpy as np
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import arrow
# import arrow
from freqtrade.strategy import (IStrategy, merge_informative_pair, stoploss_from_open,
IntParameter, DecimalParameter, CategoricalParameter)
@@ -162,7 +162,7 @@ def SSLChannels(dataframe, length=10, mode='sma'):
df['smaLow'] = df['low'].rolling(length).mean()
df['hlv'] = np.where(df['close'] > df['smaHigh'], 1,
np.where(df['close'] < df['smaLow'], -1, np.NAN))
np.where(df['close'] < df['smaLow'], -1, np.nan))
df['hlv'] = df['hlv'].ffill()
df['sslDown'] = np.where(df['hlv'] < 0, df['smaHigh'], df['smaLow'])
@@ -180,7 +180,7 @@ def SSLChannels_ATR(dataframe, length=7):
df['ATR'] = ta.ATR(df, timeperiod=14)
df['smaHigh'] = df['high'].rolling(length).mean() + df['ATR']
df['smaLow'] = df['low'].rolling(length).mean() - df['ATR']
df['hlv'] = np.where(df['close'] > df['smaHigh'], 1, np.where(df['close'] < df['smaLow'], -1, np.NAN))
df['hlv'] = np.where(df['close'] > df['smaHigh'], 1, np.where(df['close'] < df['smaLow'], -1, np.nan))
df['hlv'] = df['hlv'].ffill()
df['sslDown'] = np.where(df['hlv'] < 0, df['smaHigh'], df['smaLow'])
df['sslUp'] = np.where(df['hlv'] < 0, df['smaLow'], df['smaHigh'])

View File

@@ -164,7 +164,7 @@ class Supertrend(IStrategy):
df['final_lb'].iat[i] if df[st].iat[i - 1] == df['final_lb'].iat[i - 1] and df['close'].iat[i] >= df['final_lb'].iat[i] else \
df['final_ub'].iat[i] if df[st].iat[i - 1] == df['final_lb'].iat[i - 1] and df['close'].iat[i] < df['final_lb'].iat[i] else 0.00
# Mark the trend direction up/down
df[stx] = np.where((df[st] > 0.00), np.where((df['close'] < df[st]), 'down', 'up'), np.NaN)
df[stx] = np.where((df[st] > 0.00), np.where((df['close'] < df[st]), 'down', 'up'), np.nan)
# Remove basic and final bands from the columns
df.drop(['basic_ub', 'basic_lb', 'final_ub', 'final_lb'], inplace=True, axis=1)

View File

@@ -487,10 +487,10 @@ class Zeus_5_1(IStrategy):
def bot_loop_start(self, **kwargs) -> None:
inf_tf = '5m'
pairs = self.dp.current_whitelist()
print("Calcul des pairs informatives")
# print("Calcul des pairs informatives")
for pairname in pairs:
self.stop_buying[pairname] = True
print("Fin Calcul des pairs informatives")
# print("Fin Calcul des pairs informatives")
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str,
current_time: datetime, entry_tag: Optional[str], **kwargs) -> bool:

View File

@@ -491,10 +491,10 @@ class Zeus_5_2(IStrategy):
def bot_loop_start(self, **kwargs) -> None:
inf_tf = '5m'
pairs = self.dp.current_whitelist()
print("Calcul des pairs informatives")
# print("Calcul des pairs informatives")
for pairname in pairs:
self.stop_buying[pairname] = True
print("Fin Calcul des pairs informatives")
# print("Fin Calcul des pairs informatives")
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str,
current_time: datetime, entry_tag: Optional[str], **kwargs) -> bool:

View File

@@ -487,10 +487,10 @@ class Zeus_6(IStrategy):
def bot_loop_start(self, **kwargs) -> None:
inf_tf = '5m'
pairs = self.dp.current_whitelist()
print("Calcul des pairs informatives")
# print("Calcul des pairs informatives")
for pairname in pairs:
self.stop_buying[pairname] = True
print("Fin Calcul des pairs informatives")
# print("Fin Calcul des pairs informatives")
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str,
current_time: datetime, entry_tag: Optional[str], **kwargs) -> bool:

1610
Zeus_8_1d.py Normal file

File diff suppressed because it is too large Load Diff

376
Zeus_8_1d_Bilan.txt Normal file
View File

@@ -0,0 +1,376 @@
BACKTESTING REPORT
┏━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ DOGE/USDT │ 20 │ 6.58 │ 234.716 │ 7.82 │ 12 days, 21:54:00 │ 20 0 0 100 │
│ XRP/USDT │ 29 │ 4.96 │ 198.511 │ 6.62 │ 8 days, 17:43:00 │ 28 0 1 96.6 │
│ SOL/USDT │ 23 │ 4.96 │ 159.580 │ 5.32 │ 11 days, 1:29:00 │ 22 0 1 95.7 │
│ ETH/USDT │ 26 │ 4.12 │ 155.679 │ 5.19 │ 9 days, 20:48:00 │ 26 0 0 100 │
│ BTC/USDT │ 23 │ 2.57 │ 76.047 │ 2.53 │ 10 days, 23:47:00 │ 22 0 1 95.7 │
│ TOTAL │ 121 │ 4.59 │ 824.533 │ 27.48 │ 10 days, 12:59:00 │ 118 0 3 97.5 │
└───────────┴────────┴──────────────┴─────────────────┴──────────────┴───────────────────┴────────────────────────┘
LEFT OPEN TRADES REPORT
┏━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Pair ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ ETH/USDT │ 1 │ 3.07 │ 1.533 │ 0.05 │ 2 days, 6:00:00 │ 1 0 0 100 │
│ DOGE/USDT │ 1 │ 0.47 │ 0.741 │ 0.02 │ 2 days, 5:00:00 │ 1 0 0 100 │
│ BTC/USDT │ 1 │ -0.13 │ -0.065 │ -0.0 │ 2 days, 7:00:00 │ 0 0 1 0 │
│ SOL/USDT │ 1 │ -1.47 │ -0.917 │ -0.03 │ 19:00:00 │ 0 0 1 0 │
│ XRP/USDT │ 1 │ -4.64 │ -11.192 │ -0.37 │ 54 days, 8:00:00 │ 0 0 1 0 │
│ TOTAL │ 5 │ -0.54 │ -9.899 │ -0.33 │ 12 days, 9:00:00 │ 2 0 3 40.0 │
└───────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┘
ENTER TAG STATS
┏━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Enter Tag ┃ Entries ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ smth_12 │ 121 │ 4.59 │ 824.533 │ 27.48 │ 10 days, 12:59:00 │ 118 0 3 97.5 │
│ TOTAL │ 121 │ 4.59 │ 824.533 │ 27.48 │ 10 days, 12:59:00 │ 118 0 3 97.5 │
└───────────┴─────────┴──────────────┴─────────────────┴──────────────┴───────────────────┴────────────────────────┘
EXIT REASON STATS
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Exit Reason ┃ Exits ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ RSI_XRP_5_0_28.43 │ 1 │ 15.15 │ 71.078 │ 2.37 │ 15 days, 4:00:00 │ 1 0 0 100 │
│ Drv3_ETH_8_0_34.72 │ 1 │ 6.36 │ 53.262 │ 1.78 │ 125 days, 19:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_6_0_46.32 │ 1 │ 10.45 │ 52.528 │ 1.75 │ 47 days, 13:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_3_0_26.01 │ 1 │ 21.51 │ 34.730 │ 1.16 │ 6 days, 1:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_3_0_39.61 │ 1 │ 14.32 │ 34.062 │ 1.14 │ 11 days, 21:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_14.24 │ 1 │ 15.48 │ 26.538 │ 0.88 │ 11 days, 17:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_9.03 │ 1 │ 17.25 │ 26.223 │ 0.87 │ 8 days, 1:00:00 │ 1 0 0 100 │
│ Drv3_XRP_4_0_19.78 │ 1 │ 9.64 │ 21.919 │ 0.73 │ 9 days, 10:00:00 │ 1 0 0 100 │
│ Drv3_SOL_3_0_31.46 │ 1 │ 10.39 │ 20.674 │ 0.69 │ 8 days, 13:00:00 │ 1 0 0 100 │
│ Drv3_SOL_4_0_24.35 │ 1 │ 6.46 │ 20.553 │ 0.69 │ 13 days, 8:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_4_0_29.59 │ 1 │ 6.68 │ 18.794 │ 0.63 │ 16 days, 21:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_2_0_23.33 │ 1 │ 17.89 │ 18.435 │ 0.61 │ 3 days, 20:00:00 │ 1 0 0 100 │
│ Drv3_XRP_4_0_34.21 │ 1 │ 7.03 │ 17.503 │ 0.58 │ 12 days, 1:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_18.45 │ 1 │ 10.19 │ 16.852 │ 0.56 │ 7 days, 0:00:00 │ 1 0 0 100 │
│ Drv3_BTC_8_0_37.83 │ 1 │ 3.12 │ 16.616 │ 0.55 │ 79 days, 11:00:00 │ 1 0 0 100 │
│ Drv3_BTC_4_0_12.14 │ 1 │ 6.86 │ 15.212 │ 0.51 │ 16 days, 15:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_19.08 │ 1 │ 18.77 │ 14.063 │ 0.47 │ 4 days, 11:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_20.83 │ 1 │ 26.55 │ 13.279 │ 0.44 │ 3 days, 16:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_19.63 │ 1 │ 7.04 │ 13.133 │ 0.44 │ 14 days, 0:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_3_0_25.43 │ 1 │ 6.43 │ 12.901 │ 0.43 │ 12 days, 17:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_27.27 │ 1 │ 12.06 │ 12.054 │ 0.4 │ 2 days, 6:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_67.31 │ 1 │ 11.51 │ 11.807 │ 0.39 │ 3 days, 13:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_43.54 │ 1 │ 5.33 │ 11.803 │ 0.39 │ 46 days, 10:00:00 │ 1 0 0 100 │
│ Drv3_SOL_1_0_11.11 │ 1 │ 12.28 │ 11.253 │ 0.38 │ 3 days, 16:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_4_0_54.81 │ 1 │ 4.36 │ 10.812 │ 0.36 │ 13 days, 15:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_34.78 │ 1 │ 16.81 │ 10.484 │ 0.35 │ 2 days, 20:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_3_0_26.24 │ 1 │ 6.2 │ 10.401 │ 0.35 │ 7 days, 23:00:00 │ 1 0 0 100 │
│ RSI_ETH_1_0_8.93 │ 1 │ 20.52 │ 10.253 │ 0.34 │ 4 days, 22:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_32.89 │ 1 │ 6.37 │ 10.247 │ 0.34 │ 6 days, 18:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_28.89 │ 1 │ 9.34 │ 9.561 │ 0.32 │ 5 days, 14:00:00 │ 1 0 0 100 │
│ RSI_SOL_4_0_40.62 │ 1 │ 2.98 │ 9.471 │ 0.32 │ 10 days, 23:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_69.84 │ 1 │ 2.64 │ 9.241 │ 0.31 │ 3 days, 14:00:00 │ 1 0 0 100 │
│ Drv3_SOL_3_0_60.36 │ 1 │ 4.38 │ 8.823 │ 0.29 │ 7 days, 10:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_47.83 │ 1 │ 8.04 │ 8.420 │ 0.28 │ 3 days, 23:00:00 │ 1 0 0 100 │
│ RSI_XRP_1_0_9.78 │ 1 │ 13.26 │ 8.291 │ 0.28 │ 1 day, 10:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_33.33 │ 1 │ 15.27 │ 7.630 │ 0.25 │ 3 days, 20:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_12.35 │ 1 │ 14.27 │ 7.136 │ 0.24 │ 3 days, 22:00:00 │ 1 0 0 100 │
│ Drv3_SOL_1_0_39.42 │ 1 │ 10.17 │ 6.354 │ 0.21 │ 3 days, 15:00:00 │ 1 0 0 100 │
│ Drv3_BTC_4_0_17.57 │ 1 │ 2.59 │ 6.081 │ 0.2 │ 15 days, 18:00:00 │ 1 0 0 100 │
│ Drv3_BTC_2_0_18.06 │ 1 │ 5.89 │ 5.956 │ 0.2 │ 9 days, 11:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_17.14 │ 1 │ 9.45 │ 5.834 │ 0.19 │ 8 days, 2:00:00 │ 1 0 0 100 │
│ Drv3_SOL_8_0_81.16 │ 1 │ 0.73 │ 5.508 │ 0.18 │ 107 days, 19:00:00 │ 1 0 0 100 │
│ RSI_BTC_5_0_31.25 │ 1 │ 1.93 │ 5.464 │ 0.18 │ 17 days, 20:00:00 │ 1 0 0 100 │
│ Drv3_BTC_6_0_30.26 │ 1 │ 1.51 │ 5.343 │ 0.18 │ 31 days, 22:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_4_0_83.45 │ 1 │ 1.65 │ 4.730 │ 0.16 │ 11 days, 6:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_26.98 │ 1 │ 9.3 │ 4.588 │ 0.15 │ 4 days, 12:00:00 │ 1 0 0 100 │
│ Drv3_SOL_1_0_25.0 │ 1 │ 7.26 │ 4.538 │ 0.15 │ 3 days, 7:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_20.0 │ 1 │ 8.86 │ 4.432 │ 0.15 │ 5 days, 22:00:00 │ 1 0 0 100 │
│ Drv3_XRP_5_0_68.35 │ 1 │ 1.23 │ 4.368 │ 0.15 │ 55 days, 19:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_10.64 │ 1 │ 8.42 │ 4.189 │ 0.14 │ 6 days, 23:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_60.19 │ 1 │ 2.61 │ 4.110 │ 0.14 │ 4 days, 3:00:00 │ 1 0 0 100 │
│ RSI_ETH_3_0_38.98 │ 1 │ 2.1 │ 3.591 │ 0.12 │ 12 days, 8:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_27.66 │ 1 │ 5.48 │ 3.425 │ 0.11 │ 2 days, 16:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_43.86 │ 1 │ 2.49 │ 3.220 │ 0.11 │ 4 days, 1:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_40.74 │ 1 │ 5.16 │ 3.215 │ 0.11 │ 2 days, 2:00:00 │ 1 0 0 100 │
│ Drv3_SOL_1_0_50.77 │ 1 │ 5.12 │ 3.201 │ 0.11 │ 2 days, 12:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_7_0_96.68 │ 1 │ 0.29 │ 3.008 │ 0.1 │ 110 days, 6:00:00 │ 1 0 0 100 │
│ Drv3_SOL_5_0_82.93 │ 1 │ 0.66 │ 2.808 │ 0.09 │ 38 days, 21:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_74.07 │ 1 │ 1.13 │ 2.788 │ 0.09 │ 6 days, 14:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_77.5 │ 1 │ 1.35 │ 2.745 │ 0.09 │ 2 days, 16:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_57.63 │ 1 │ 2.33 │ 2.489 │ 0.08 │ 5 days, 9:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_46.67 │ 1 │ 1.18 │ 2.404 │ 0.08 │ 4 days, 10:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_54.0 │ 1 │ 4.34 │ 2.338 │ 0.08 │ 3 days, 3:00:00 │ 1 0 0 100 │
│ Drv3_SOL_4_0_76.04 │ 1 │ 0.96 │ 2.254 │ 0.08 │ 13 days, 17:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_56.0 │ 1 │ 3.55 │ 2.217 │ 0.07 │ 6 days, 15:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_45.95 │ 1 │ 3.99 │ 1.993 │ 0.07 │ 1 day, 5:00:00 │ 1 0 0 100 │
│ RSI_ETH_1_0_16.67 │ 1 │ 3.97 │ 1.977 │ 0.07 │ 14:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_26.09 │ 1 │ 2.8 │ 1.746 │ 0.06 │ 2 days, 10:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_71.93 │ 1 │ 1.52 │ 1.583 │ 0.05 │ 2 days, 11:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_11.11 │ 1 │ 3.14 │ 1.565 │ 0.05 │ 2 days, 8:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_3_0_27.27 │ 1 │ 0.85 │ 1.557 │ 0.05 │ 12:00:00 │ 1 0 0 100 │
│ Drv3_ETH_4_0_79.73 │ 1 │ 0.65 │ 1.509 │ 0.05 │ 6 days, 20:00:00 │ 1 0 0 100 │
│ Drv3_ETH_2_0_76.56 │ 1 │ 1.15 │ 1.466 │ 0.05 │ 3 days, 6:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_75.0 │ 1 │ 1.75 │ 1.314 │ 0.04 │ 3 days, 14:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_73.47 │ 1 │ 0.76 │ 1.289 │ 0.04 │ 20 days, 8:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_27.78 │ 1 │ 1.27 │ 1.268 │ 0.04 │ 6:00:00 │ 1 0 0 100 │
│ Drv3_XRP_2_0_33.33 │ 1 │ 0.95 │ 1.203 │ 0.04 │ 1 day, 1:00:00 │ 1 0 0 100 │
│ Drv3_XRP_2_0_83.58 │ 1 │ 1.12 │ 1.148 │ 0.04 │ 1 day, 16:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_54.17 │ 1 │ 2.19 │ 1.097 │ 0.04 │ 1 day, 15:00:00 │ 1 0 0 100 │
│ Drv3_BTC_2_0_44.44 │ 1 │ 0.79 │ 1.033 │ 0.03 │ 9 days, 6:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_77.78 │ 1 │ 2.0 │ 0.999 │ 0.03 │ 1 day, 16:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_41.18 │ 1 │ 1.93 │ 0.964 │ 0.03 │ 5 days, 6:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_85.94 │ 1 │ 0.48 │ 0.944 │ 0.03 │ 14 days, 16:00:00 │ 1 0 0 100 │
│ Drv3_XRP_3_0_12.5 │ 1 │ 0.45 │ 0.712 │ 0.02 │ 1 day, 1:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_81.58 │ 1 │ 1.12 │ 0.697 │ 0.02 │ 2 days, 7:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_30.0 │ 1 │ 1.1 │ 0.688 │ 0.02 │ 10:00:00 │ 1 0 0 100 │
│ Drv3_ETH_3_0_30.0 │ 1 │ 0.42 │ 0.669 │ 0.02 │ 1 day, 6:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_0.0 │ 1 │ 1.07 │ 0.666 │ 0.02 │ 4:00:00 │ 1 0 0 100 │
│ Drv3_ETH_2_0_72.73 │ 1 │ 0.62 │ 0.631 │ 0.02 │ 1 day, 20:00:00 │ 1 0 0 100 │
│ Drv3_XRP_2_0_25.0 │ 1 │ 0.6 │ 0.614 │ 0.02 │ 13:00:00 │ 1 0 0 100 │
│ Drv3_ETH_2_0_66.67 │ 1 │ 0.59 │ 0.607 │ 0.02 │ 4 days, 22:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_57.14 │ 2 │ 0.38 │ 0.590 │ 0.02 │ 8:00:00 │ 2 0 0 100 │
│ Drv3_SOL_2_0_64.71 │ 1 │ 0.57 │ 0.588 │ 0.02 │ 1 day, 12:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_94.95 │ 1 │ 0.36 │ 0.548 │ 0.02 │ 2 days, 5:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_28.57 │ 1 │ 0.87 │ 0.545 │ 0.02 │ 3:00:00 │ 1 0 0 100 │
│ Drv3_SOL_2_0_28.57 │ 1 │ 0.49 │ 0.506 │ 0.02 │ 1 day, 5:00:00 │ 1 0 0 100 │
│ Drv3_BTC_2_0_37.5 │ 1 │ 0.45 │ 0.489 │ 0.02 │ 3 days, 2:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_73.68 │ 1 │ 0.94 │ 0.466 │ 0.02 │ 2 days, 18:00:00 │ 1 0 0 100 │
│ Drv3_BTC_2_0_76.47 │ 1 │ 0.38 │ 0.397 │ 0.01 │ 15 days, 3:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_72.73 │ 1 │ 0.7 │ 0.347 │ 0.01 │ 1 day, 23:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_57.14 │ 1 │ 0.64 │ 0.318 │ 0.01 │ 1 day, 14:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_85.0 │ 1 │ 0.48 │ 0.298 │ 0.01 │ 2 days, 7:00:00 │ 1 0 0 100 │
│ Drv3_ETH_1_0_76.92 │ 1 │ 0.58 │ 0.290 │ 0.01 │ 2 days, 1:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_75.0 │ 1 │ 0.45 │ 0.223 │ 0.01 │ 1 day, 15:00:00 │ 1 0 0 100 │
│ Drv3_DOGE_1_0_87.5 │ 1 │ 0.32 │ 0.198 │ 0.01 │ 1 day, 11:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_80.0 │ 1 │ 0.32 │ 0.196 │ 0.01 │ 1 day, 14:00:00 │ 1 0 0 100 │
│ Drv3_BTC_2_0_94.59 │ 1 │ 0.19 │ 0.188 │ 0.01 │ 6 days, 10:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_92.0 │ 1 │ 0.35 │ 0.173 │ 0.01 │ 3 days, 2:00:00 │ 1 0 0 100 │
│ Drv3_XRP_1_0_92.86 │ 1 │ 0.29 │ 0.147 │ 0.0 │ 1 day, 18:00:00 │ 1 0 0 100 │
│ Drv3_ETH_2_0_97.62 │ 1 │ 0.14 │ 0.145 │ 0.0 │ 1 day, 14:00:00 │ 1 0 0 100 │
│ Drv3_ETH_2_0_91.67 │ 1 │ 0.14 │ 0.143 │ 0.0 │ 1 day, 0:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_85.71 │ 1 │ 0.27 │ 0.133 │ 0.0 │ 2 days, 11:00:00 │ 1 0 0 100 │
│ Drv3_SOL_1_0_80.0 │ 1 │ 0.23 │ 0.114 │ 0.0 │ 2 days, 0:00:00 │ 1 0 0 100 │
│ Drv3_BTC_2_0_66.67 │ 1 │ 0.11 │ 0.107 │ 0.0 │ 1 day, 0:00:00 │ 1 0 0 100 │
│ Drv3_BTC_1_0_90.0 │ 1 │ 0.21 │ 0.104 │ 0.0 │ 1 day, 9:00:00 │ 1 0 0 100 │
│ force_exit │ 5 │ -0.54 │ -9.899 │ -0.33 │ 12 days, 9:00:00 │ 2 0 3 40.0 │
│ TOTAL │ 121 │ 4.59 │ 824.533 │ 27.48 │ 10 days, 12:59:00 │ 118 0 3 97.5 │
└─────────────────────┴───────┴──────────────┴─────────────────┴──────────────┴────────────────────┴────────────────────────┘
MIXED TAG STATS
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Enter Tag ┃ Exit Reason ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ ('smth_12', 'RSI_XRP_5_0_28.43') │ │ 1 │ 15.15 │ 71.078 │ 2.37 │ 15 days, 4:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_8_0_34.72') │ │ 1 │ 6.36 │ 53.262 │ 1.78 │ 125 days, 19:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_6_0_46.32') │ │ 1 │ 10.45 │ 52.528 │ 1.75 │ 47 days, 13:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_3_0_26.01') │ │ 1 │ 21.51 │ 34.730 │ 1.16 │ 6 days, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_3_0_39.61') │ │ 1 │ 14.32 │ 34.062 │ 1.14 │ 11 days, 21:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_14.24') │ │ 1 │ 15.48 │ 26.538 │ 0.88 │ 11 days, 17:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_9.03') │ │ 1 │ 17.25 │ 26.223 │ 0.87 │ 8 days, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_4_0_19.78') │ │ 1 │ 9.64 │ 21.919 │ 0.73 │ 9 days, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_3_0_31.46') │ │ 1 │ 10.39 │ 20.674 │ 0.69 │ 8 days, 13:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_4_0_24.35') │ │ 1 │ 6.46 │ 20.553 │ 0.69 │ 13 days, 8:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_4_0_29.59') │ │ 1 │ 6.68 │ 18.794 │ 0.63 │ 16 days, 21:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_2_0_23.33') │ │ 1 │ 17.89 │ 18.435 │ 0.61 │ 3 days, 20:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_4_0_34.21') │ │ 1 │ 7.03 │ 17.503 │ 0.58 │ 12 days, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_18.45') │ │ 1 │ 10.19 │ 16.852 │ 0.56 │ 7 days, 0:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_8_0_37.83') │ │ 1 │ 3.12 │ 16.616 │ 0.55 │ 79 days, 11:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_4_0_12.14') │ │ 1 │ 6.86 │ 15.212 │ 0.51 │ 16 days, 15:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_19.08') │ │ 1 │ 18.77 │ 14.063 │ 0.47 │ 4 days, 11:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_20.83') │ │ 1 │ 26.55 │ 13.279 │ 0.44 │ 3 days, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_19.63') │ │ 1 │ 7.04 │ 13.133 │ 0.44 │ 14 days, 0:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_3_0_25.43') │ │ 1 │ 6.43 │ 12.901 │ 0.43 │ 12 days, 17:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_27.27') │ │ 1 │ 12.06 │ 12.054 │ 0.4 │ 2 days, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_67.31') │ │ 1 │ 11.51 │ 11.807 │ 0.39 │ 3 days, 13:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_43.54') │ │ 1 │ 5.33 │ 11.803 │ 0.39 │ 46 days, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_1_0_11.11') │ │ 1 │ 12.28 │ 11.253 │ 0.38 │ 3 days, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_4_0_54.81') │ │ 1 │ 4.36 │ 10.812 │ 0.36 │ 13 days, 15:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_34.78') │ │ 1 │ 16.81 │ 10.484 │ 0.35 │ 2 days, 20:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_3_0_26.24') │ │ 1 │ 6.2 │ 10.401 │ 0.35 │ 7 days, 23:00:00 │ 1 0 0 100 │
│ ('smth_12', 'RSI_ETH_1_0_8.93') │ │ 1 │ 20.52 │ 10.253 │ 0.34 │ 4 days, 22:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_32.89') │ │ 1 │ 6.37 │ 10.247 │ 0.34 │ 6 days, 18:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_28.89') │ │ 1 │ 9.34 │ 9.561 │ 0.32 │ 5 days, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'RSI_SOL_4_0_40.62') │ │ 1 │ 2.98 │ 9.471 │ 0.32 │ 10 days, 23:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_69.84') │ │ 1 │ 2.64 │ 9.241 │ 0.31 │ 3 days, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_3_0_60.36') │ │ 1 │ 4.38 │ 8.823 │ 0.29 │ 7 days, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_47.83') │ │ 1 │ 8.04 │ 8.420 │ 0.28 │ 3 days, 23:00:00 │ 1 0 0 100 │
│ ('smth_12', 'RSI_XRP_1_0_9.78') │ │ 1 │ 13.26 │ 8.291 │ 0.28 │ 1 day, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_33.33') │ │ 1 │ 15.27 │ 7.630 │ 0.25 │ 3 days, 20:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_12.35') │ │ 1 │ 14.27 │ 7.136 │ 0.24 │ 3 days, 22:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_1_0_39.42') │ │ 1 │ 10.17 │ 6.354 │ 0.21 │ 3 days, 15:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_4_0_17.57') │ │ 1 │ 2.59 │ 6.081 │ 0.2 │ 15 days, 18:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_2_0_18.06') │ │ 1 │ 5.89 │ 5.956 │ 0.2 │ 9 days, 11:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_17.14') │ │ 1 │ 9.45 │ 5.834 │ 0.19 │ 8 days, 2:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_8_0_81.16') │ │ 1 │ 0.73 │ 5.508 │ 0.18 │ 107 days, 19:00:00 │ 1 0 0 100 │
│ ('smth_12', 'RSI_BTC_5_0_31.25') │ │ 1 │ 1.93 │ 5.464 │ 0.18 │ 17 days, 20:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_6_0_30.26') │ │ 1 │ 1.51 │ 5.343 │ 0.18 │ 31 days, 22:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_4_0_83.45') │ │ 1 │ 1.65 │ 4.730 │ 0.16 │ 11 days, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_26.98') │ │ 1 │ 9.3 │ 4.588 │ 0.15 │ 4 days, 12:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_1_0_25.0') │ │ 1 │ 7.26 │ 4.538 │ 0.15 │ 3 days, 7:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_20.0') │ │ 1 │ 8.86 │ 4.432 │ 0.15 │ 5 days, 22:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_5_0_68.35') │ │ 1 │ 1.23 │ 4.368 │ 0.15 │ 55 days, 19:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_10.64') │ │ 1 │ 8.42 │ 4.189 │ 0.14 │ 6 days, 23:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_60.19') │ │ 1 │ 2.61 │ 4.110 │ 0.14 │ 4 days, 3:00:00 │ 1 0 0 100 │
│ ('smth_12', 'RSI_ETH_3_0_38.98') │ │ 1 │ 2.1 │ 3.591 │ 0.12 │ 12 days, 8:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_27.66') │ │ 1 │ 5.48 │ 3.425 │ 0.11 │ 2 days, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_43.86') │ │ 1 │ 2.49 │ 3.220 │ 0.11 │ 4 days, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_40.74') │ │ 1 │ 5.16 │ 3.215 │ 0.11 │ 2 days, 2:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_1_0_50.77') │ │ 1 │ 5.12 │ 3.201 │ 0.11 │ 2 days, 12:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_7_0_96.68') │ │ 1 │ 0.29 │ 3.008 │ 0.1 │ 110 days, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_5_0_82.93') │ │ 1 │ 0.66 │ 2.808 │ 0.09 │ 38 days, 21:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_74.07') │ │ 1 │ 1.13 │ 2.788 │ 0.09 │ 6 days, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_77.5') │ │ 1 │ 1.35 │ 2.745 │ 0.09 │ 2 days, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_57.63') │ │ 1 │ 2.33 │ 2.489 │ 0.08 │ 5 days, 9:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_46.67') │ │ 1 │ 1.18 │ 2.404 │ 0.08 │ 4 days, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_54.0') │ │ 1 │ 4.34 │ 2.338 │ 0.08 │ 3 days, 3:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_4_0_76.04') │ │ 1 │ 0.96 │ 2.254 │ 0.08 │ 13 days, 17:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_56.0') │ │ 1 │ 3.55 │ 2.217 │ 0.07 │ 6 days, 15:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_45.95') │ │ 1 │ 3.99 │ 1.993 │ 0.07 │ 1 day, 5:00:00 │ 1 0 0 100 │
│ ('smth_12', 'RSI_ETH_1_0_16.67') │ │ 1 │ 3.97 │ 1.977 │ 0.07 │ 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_26.09') │ │ 1 │ 2.8 │ 1.746 │ 0.06 │ 2 days, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_71.93') │ │ 1 │ 1.52 │ 1.583 │ 0.05 │ 2 days, 11:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_11.11') │ │ 1 │ 3.14 │ 1.565 │ 0.05 │ 2 days, 8:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_3_0_27.27') │ │ 1 │ 0.85 │ 1.557 │ 0.05 │ 12:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_4_0_79.73') │ │ 1 │ 0.65 │ 1.509 │ 0.05 │ 6 days, 20:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_2_0_76.56') │ │ 1 │ 1.15 │ 1.466 │ 0.05 │ 3 days, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_75.0') │ │ 1 │ 1.75 │ 1.314 │ 0.04 │ 3 days, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_73.47') │ │ 1 │ 0.76 │ 1.289 │ 0.04 │ 20 days, 8:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_27.78') │ │ 1 │ 1.27 │ 1.268 │ 0.04 │ 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_2_0_33.33') │ │ 1 │ 0.95 │ 1.203 │ 0.04 │ 1 day, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_2_0_83.58') │ │ 1 │ 1.12 │ 1.148 │ 0.04 │ 1 day, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_54.17') │ │ 1 │ 2.19 │ 1.097 │ 0.04 │ 1 day, 15:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_2_0_44.44') │ │ 1 │ 0.79 │ 1.033 │ 0.03 │ 9 days, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_77.78') │ │ 1 │ 2.0 │ 0.999 │ 0.03 │ 1 day, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_41.18') │ │ 1 │ 1.93 │ 0.964 │ 0.03 │ 5 days, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_85.94') │ │ 1 │ 0.48 │ 0.944 │ 0.03 │ 14 days, 16:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_3_0_12.5') │ │ 1 │ 0.45 │ 0.712 │ 0.02 │ 1 day, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_81.58') │ │ 1 │ 1.12 │ 0.697 │ 0.02 │ 2 days, 7:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_30.0') │ │ 1 │ 1.1 │ 0.688 │ 0.02 │ 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_3_0_30.0') │ │ 1 │ 0.42 │ 0.669 │ 0.02 │ 1 day, 6:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_0.0') │ │ 1 │ 1.07 │ 0.666 │ 0.02 │ 4:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_2_0_72.73') │ │ 1 │ 0.62 │ 0.631 │ 0.02 │ 1 day, 20:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_2_0_25.0') │ │ 1 │ 0.6 │ 0.614 │ 0.02 │ 13:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_2_0_66.67') │ │ 1 │ 0.59 │ 0.607 │ 0.02 │ 4 days, 22:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_57.14') │ │ 2 │ 0.38 │ 0.590 │ 0.02 │ 8:00:00 │ 2 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_64.71') │ │ 1 │ 0.57 │ 0.588 │ 0.02 │ 1 day, 12:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_94.95') │ │ 1 │ 0.36 │ 0.548 │ 0.02 │ 2 days, 5:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_28.57') │ │ 1 │ 0.87 │ 0.545 │ 0.02 │ 3:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_2_0_28.57') │ │ 1 │ 0.49 │ 0.506 │ 0.02 │ 1 day, 5:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_2_0_37.5') │ │ 1 │ 0.45 │ 0.489 │ 0.02 │ 3 days, 2:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_73.68') │ │ 1 │ 0.94 │ 0.466 │ 0.02 │ 2 days, 18:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_2_0_76.47') │ │ 1 │ 0.38 │ 0.397 │ 0.01 │ 15 days, 3:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_72.73') │ │ 1 │ 0.7 │ 0.347 │ 0.01 │ 1 day, 23:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_57.14') │ │ 1 │ 0.64 │ 0.318 │ 0.01 │ 1 day, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_85.0') │ │ 1 │ 0.48 │ 0.298 │ 0.01 │ 2 days, 7:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_1_0_76.92') │ │ 1 │ 0.58 │ 0.290 │ 0.01 │ 2 days, 1:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_75.0') │ │ 1 │ 0.45 │ 0.223 │ 0.01 │ 1 day, 15:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_DOGE_1_0_87.5') │ │ 1 │ 0.32 │ 0.198 │ 0.01 │ 1 day, 11:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_80.0') │ │ 1 │ 0.32 │ 0.196 │ 0.01 │ 1 day, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_2_0_94.59') │ │ 1 │ 0.19 │ 0.188 │ 0.01 │ 6 days, 10:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_92.0') │ │ 1 │ 0.35 │ 0.173 │ 0.01 │ 3 days, 2:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_XRP_1_0_92.86') │ │ 1 │ 0.29 │ 0.147 │ 0.0 │ 1 day, 18:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_2_0_97.62') │ │ 1 │ 0.14 │ 0.145 │ 0.0 │ 1 day, 14:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_ETH_2_0_91.67') │ │ 1 │ 0.14 │ 0.143 │ 0.0 │ 1 day, 0:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_85.71') │ │ 1 │ 0.27 │ 0.133 │ 0.0 │ 2 days, 11:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_SOL_1_0_80.0') │ │ 1 │ 0.23 │ 0.114 │ 0.0 │ 2 days, 0:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_2_0_66.67') │ │ 1 │ 0.11 │ 0.107 │ 0.0 │ 1 day, 0:00:00 │ 1 0 0 100 │
│ ('smth_12', 'Drv3_BTC_1_0_90.0') │ │ 1 │ 0.21 │ 0.104 │ 0.0 │ 1 day, 9:00:00 │ 1 0 0 100 │
│ ('smth_12', 'force_exit') │ │ 5 │ -0.54 │ -9.899 │ -0.33 │ 12 days, 9:00:00 │ 2 0 3 40.0 │
│ TOTAL │ │ 121 │ 4.59 │ 824.533 │ 27.48 │ 10 days, 12:59:00 │ 118 0 3 97.5 │
└────────────────────────────────────┴─────────────┴────────┴──────────────┴─────────────────┴──────────────┴────────────────────┴────────────────────────┘
WEEK BREAKDOWN
┏━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━┳━━━━━━━━┓
┃ Week ┃ Tot Profit USDT ┃ Wins ┃ Draws ┃ Losses ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━╇━━━━━━━━┩
│ 06/01/2025 │ 37.217 │ 6 │ 0 │ 0 │
│ 13/01/2025 │ 12.464 │ 2 │ 0 │ 0 │
│ 20/01/2025 │ 76.722 │ 7 │ 0 │ 0 │
│ 27/01/2025 │ 4.684 │ 4 │ 0 │ 0 │
│ 03/02/2025 │ 3.577 │ 4 │ 0 │ 0 │
│ 10/02/2025 │ 0 │ 0 │ 0 │ 0 │
│ 17/02/2025 │ 17.503 │ 1 │ 0 │ 0 │
│ 24/02/2025 │ 0 │ 0 │ 0 │ 0 │
│ 03/03/2025 │ 71.078 │ 1 │ 0 │ 0 │
│ 10/03/2025 │ 9.241 │ 1 │ 0 │ 0 │
│ 17/03/2025 │ 4.588 │ 1 │ 0 │ 0 │
│ 24/03/2025 │ 2.338 │ 1 │ 0 │ 0 │
│ 31/03/2025 │ 0.147 │ 1 │ 0 │ 0 │
│ 07/04/2025 │ 0 │ 0 │ 0 │ 0 │
│ 14/04/2025 │ 0 │ 0 │ 0 │ 0 │
│ 21/04/2025 │ 0 │ 0 │ 0 │ 0 │
│ 28/04/2025 │ 16.839 │ 2 │ 0 │ 0 │
│ 05/05/2025 │ 0.964 │ 1 │ 0 │ 0 │
│ 12/05/2025 │ 78.013 │ 5 │ 0 │ 0 │
│ 19/05/2025 │ 6.222 │ 4 │ 0 │ 0 │
│ 26/05/2025 │ 19.509 │ 3 │ 0 │ 0 │
│ 02/06/2025 │ 0.944 │ 1 │ 0 │ 0 │
│ 09/06/2025 │ 0 │ 0 │ 0 │ 0 │
│ 16/06/2025 │ 9.2 │ 3 │ 0 │ 0 │
│ 23/06/2025 │ 2.131 │ 2 │ 0 │ 0 │
│ 30/06/2025 │ 7.723 │ 3 │ 0 │ 0 │
│ 07/07/2025 │ 5.149 │ 5 │ 0 │ 0 │
│ 14/07/2025 │ 81.049 │ 8 │ 0 │ 0 │
│ 21/07/2025 │ 66.176 │ 5 │ 0 │ 0 │
│ 28/07/2025 │ 27.276 │ 10 │ 0 │ 0 │
│ 04/08/2025 │ 0.788 │ 2 │ 0 │ 0 │
│ 11/08/2025 │ 62.555 │ 5 │ 0 │ 0 │
│ 18/08/2025 │ 15.647 │ 6 │ 0 │ 0 │
│ 25/08/2025 │ 47.927 │ 3 │ 0 │ 0 │
│ 01/09/2025 │ 3.201 │ 1 │ 0 │ 0 │
│ 08/09/2025 │ 3.22 │ 1 │ 0 │ 0 │
│ 15/09/2025 │ 70.772 │ 6 │ 0 │ 0 │
│ 22/09/2025 │ 6.969 │ 5 │ 0 │ 0 │
│ 29/09/2025 │ 0 │ 0 │ 0 │ 0 │
│ 06/10/2025 │ 62.599 │ 6 │ 0 │ 0 │
│ 13/10/2025 │ -9.899 │ 2 │ 0 │ 3 │
└────────────┴─────────────────┴──────┴───────┴────────┘
SUMMARY METRICS
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩
│ Backtesting from │ 2025-01-01 00:00:00 │
│ Backtesting to │ 2025-10-07 10:00:00 │
│ Trading Mode │ Spot │
│ Max open trades │ 5 │
│ │ │
│ Total/Daily Avg Trades │ 121 / 0.43 │
│ Starting balance │ 3000 USDT │
│ Final balance │ 3824.533 USDT │
│ Absolute profit │ 824.533 USDT │
│ Total profit % │ 27.48% │
│ CAGR % │ 37.39% │
│ Sortino │ 11.17 │
│ Sharpe │ 5.08 │
│ Calmar │ 596.19 │
│ SQN │ 6.71 │
│ Profit factor │ 68.73 │
│ Expectancy (Ratio) │ 6.81 (1.68) │
│ Avg. daily profit % │ 0.10% │
│ Avg. stake amount │ 155.858 USDT │
│ Total trade volume │ 38619.369 USDT │
│ │ │
│ Best Pair │ XRP/USDT 6.62% │
│ Worst Pair │ BTC/USDT 2.53% │
│ Best trade │ XRP/USDT 26.55% │
│ Worst trade │ XRP/USDT -4.64% │
│ Best day │ 76.022 USDT │
│ Worst day │ -9.899 USDT │
│ Days win/draw/lose │ 75 / 203 / 1 │
│ Avg. Duration Winners │ 10 days, 7:44:00 │
│ Avg. Duration Loser │ 19 days, 3:20:00 │
│ Max Consecutive Wins / Loss │ 116 / 2 │
│ Rejected Entry signals │ 0 │
│ Entry/Exit Timeouts │ 0 / 0 │
│ │ │
│ Min balance │ 3008.291 USDT │
│ Max balance │ 3835.901 USDT │
│ Max % of account underwater │ 0.32% │
│ Absolute Drawdown (Account) │ 0.32% │
│ Absolute Drawdown │ 12.109 USDT │
│ Drawdown high │ 835.901 USDT │
│ Drawdown low │ 823.792 USDT │
│ Drawdown Start │ 2025-10-07 10:00:00 │
│ Drawdown End │ 2025-10-07 10:00:00 │
│ Market change │ 2.17% │
└─────────────────────────────┴─────────────────────┘
Backtested 2025-01-01 00:00:00 -> 2025-10-07 10:00:00 | Max open trades : 5
STRATEGY SUMMARY
┏━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┓
┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃
┡━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━┩
│ Zeus_8_1d │ 121 │ 4.59 │ 824.533 │ 27.48 │ 10 days, 12:59:00 │ 118 0 3 97.5 │ 12.109 USDT 0.32% │
└───────────┴────────┴──────────────┴─────────────────┴──────────────┴───────────────────┴────────────────────────┴────────────────────┘

View File

@@ -8,25 +8,25 @@
"stoploss": -1.0
},
"trailing": {
"trailing_stop": false,
"trailing_stop_positive": 0.254,
"trailing_stop_positive_offset": 0.323,
"trailing_stop": true,
"trailing_stop_positive": 0.148,
"trailing_stop_positive_offset": 0.218,
"trailing_only_offset_is_reached": false
},
"max_open_trades": {
"max_open_trades": 80
"max_open_trades": 20
},
"buy": {
"buy_horizon_predict_1h": 2
},
"sell": {
"sell_allow_decrease": 0.2
},
"protection": {
"protection_fibo": 9,
"protection_percent_buy_lost": 3
"mise_factor_buy": 0.01,
"pct": 0.029,
"pct_inc": 0.0027,
"buy_filter_indicator": "rsi5_deriv1_1d",
"buy_indicator0": "rsi60_inv_hau",
"buy_indicator1": "mid_smooth_48_inv_bas",
"buy_indicator2": "sma24_inv_bas_1h",
"buy_indicator3": "bb_lowerband3_inv_hau_1h"
}
},
"ft_stratparam_v": 1,
"export_time": "2025-05-24 18:29:22.477903+00:00"
"export_time": "2026-02-18 16:50:53.773582+00:00"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

35
Zeus_LGBMRegressor.json Normal file
View File

@@ -0,0 +1,35 @@
{
"strategy_name": "Zeus_LGBMRegressor",
"params": {
"roi": {
"0": 10
},
"stoploss": {
"stoploss": -1
},
"trailing": {
"trailing_stop": true,
"trailing_stop_positive": 0.15,
"trailing_stop_positive_offset": 0.2,
"trailing_only_offset_is_reached": true
},
"max_open_trades": {
"max_open_trades": 80
},
"buy": {
"mise_factor_buy": 0.02,
"mises": 2,
"ml_prob_buy": -0.25,
"pct": 0.012,
"pct_inc": 0.001
},
"sell": {
"ml_prob_sell": 0.07
},
"protection": {
}
},
"ft_stratparam_v": 1,
"export_time": "2025-11-14 21:34:28.681343+00:00"
}

106
Zeus_LGBMRegressor.md Normal file
View File

@@ -0,0 +1,106 @@
🌟 Paramètres principaux de LGBMRegressor
1⃣ objective='regression'
But : indique le type de problème à résoudre.
Ici, tu veux prédire une valeur continue (par ex. un rendement futur, un prix, etc.).
Autres valeurs possibles :
'binary' → pour classification 0/1
'multiclass' → pour plusieurs classes
'regression_l1' → pour des valeurs continues mais avec perte L1 (moins sensible aux outliers)
📘 En résumé : ici LightGBM cherche à minimiser lerreur entre la valeur prédite et la valeur réelle.
2⃣ metric='rmse'
But : indique la métrique utilisée pour évaluer la qualité du modèle.
'rmse' = Root Mean Squared Error (racine de la moyenne des carrés des erreurs)
→ pénalise fortement les grosses erreurs.
'mae' (Mean Absolute Error) est une alternative plus robuste (moins sensible aux outliers).
Tu peux aussi utiliser plusieurs métriques : metric=['rmse', 'mae'].
3⃣ n_estimators=300
But : nombre darbres de décision à construire.
Chaque arbre apprend à corriger les erreurs du précédent → cest le boosting.
Plus ce nombre est grand :
Meilleure précision potentielle
Mais risque de surapprentissage et de lenteur
Typiquement, on le combine avec un petit learning_rate (comme ici 0.05).
4⃣ learning_rate=0.05
But : contrôle lintensité avec laquelle chaque nouvel arbre corrige les erreurs.
Si learning_rate ↓, il faut plus darbres (n_estimators ↑) pour converger.
Typiquement :
0.1 = standard
0.05 = prudent (meilleur généralisation)
0.01 = très lent mais précis
⚖️ Ce paramètre agit comme un “frein” sur lapprentissage.
5⃣ max_depth=7
But : profondeur maximale des arbres.
Plus les arbres sont profonds :
→ plus le modèle capture des relations complexes
→ mais risque de surapprentissage
Valeurs typiques :
3 à 8 pour éviter le surapprentissage
-1 = pas de limite
6⃣ subsample=0.8
But : fraction de léchantillon dentraînement utilisée pour chaque arbre.
Exemple :
0.8 = chaque arbre est entraîné sur 80 % des lignes (tirées aléatoirement).
Permet :
de réduire le surapprentissage
daccélérer lentraînement
Si tu veux des résultats très stables → monte à 1.0
Si tu veux plus de diversité entre les arbres → garde entre 0.7 et 0.9.
7⃣ colsample_bytree=0.8
But : fraction de colonnes (features) utilisées pour chaque arbre.
Comme subsample, mais pour les variables.
Aide à la régularisation : chaque arbre ne voit pas toutes les colonnes → modèle plus robuste.
Typiquement entre 0.6 et 1.0.
8⃣ random_state=42
But : fixe la graine aléatoire.
Permet dobtenir de

2813
Zeus_LGBMRegressor.py Normal file

File diff suppressed because it is too large Load Diff

1859
Zeus_TensorFlow.py Normal file

File diff suppressed because it is too large Load Diff

2659
Zeus_TensorFlow_1h.py Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More