investing-algorithm-framework 7.16.10__py3-none-any.whl → 7.16.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of investing-algorithm-framework might be problematic. Click here for more details.
- investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py +193 -67
- investing_algorithm_framework/services/backtesting/backtest_service.py +5 -0
- {investing_algorithm_framework-7.16.10.dist-info → investing_algorithm_framework-7.16.11.dist-info}/METADATA +1 -1
- {investing_algorithm_framework-7.16.10.dist-info → investing_algorithm_framework-7.16.11.dist-info}/RECORD +7 -7
- {investing_algorithm_framework-7.16.10.dist-info → investing_algorithm_framework-7.16.11.dist-info}/LICENSE +0 -0
- {investing_algorithm_framework-7.16.10.dist-info → investing_algorithm_framework-7.16.11.dist-info}/WHEEL +0 -0
- {investing_algorithm_framework-7.16.10.dist-info → investing_algorithm_framework-7.16.11.dist-info}/entry_points.txt +0 -0
|
@@ -1,33 +1,79 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
default_weights = {
|
|
5
|
-
# Profitability
|
|
6
|
-
"total_net_gain": 3.0,
|
|
7
|
-
"gross_loss": 0.0,
|
|
8
|
-
"growth": 0.0,
|
|
9
|
-
"trades_average_return": 0.0,
|
|
10
|
-
|
|
11
|
-
# Risk-adjusted returns
|
|
12
|
-
"sharpe_ratio": 1.0,
|
|
13
|
-
"sortino_ratio": 1.0,
|
|
14
|
-
"profit_factor": 1.0,
|
|
15
|
-
|
|
16
|
-
# Risk
|
|
17
|
-
"max_drawdown": -2.0,
|
|
18
|
-
"max_drawdown_duration": -0.5,
|
|
19
|
-
|
|
20
|
-
# Trading activity
|
|
21
|
-
"number_of_trades": 2.0,
|
|
22
|
-
"win_rate": 3.0,
|
|
23
|
-
|
|
24
|
-
# Exposure
|
|
25
|
-
"cumulative_exposure": 0.5,
|
|
26
|
-
"exposure_ratio": 0.0,
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
4
|
class BacktestEvaluationFocus(Enum):
|
|
5
|
+
"""
|
|
6
|
+
Enumeration for backtest evaluation focus areas.
|
|
7
|
+
|
|
8
|
+
The available metrics are:
|
|
9
|
+
- backtest_start_date
|
|
10
|
+
- backtest_end_date
|
|
11
|
+
- equity_curve
|
|
12
|
+
- final_value
|
|
13
|
+
- total_growth
|
|
14
|
+
- total_growth_percentage
|
|
15
|
+
- total_net_gain
|
|
16
|
+
- total_net_gain_percentage
|
|
17
|
+
- total_loss
|
|
18
|
+
- total_loss_percentage
|
|
19
|
+
- cumulative_return
|
|
20
|
+
- cumulative_return_series
|
|
21
|
+
- cagr
|
|
22
|
+
- sharpe_ratio
|
|
23
|
+
- rolling_sharpe_ratio
|
|
24
|
+
- sortino_ratio
|
|
25
|
+
- calmar_ratio
|
|
26
|
+
- profit_factor
|
|
27
|
+
- annual_volatility
|
|
28
|
+
- monthly_returns
|
|
29
|
+
- yearly_returns
|
|
30
|
+
- drawdown_series
|
|
31
|
+
- max_drawdown
|
|
32
|
+
- max_drawdown_absolute
|
|
33
|
+
- max_daily_drawdown
|
|
34
|
+
- max_drawdown_duration
|
|
35
|
+
- trades_per_year
|
|
36
|
+
- trade_per_day
|
|
37
|
+
- exposure_ratio
|
|
38
|
+
- cumulative_exposure
|
|
39
|
+
- best_trade
|
|
40
|
+
- worst_trade
|
|
41
|
+
- number_of_positive_trades
|
|
42
|
+
- percentage_positive_trades
|
|
43
|
+
- number_of_negative_trades
|
|
44
|
+
- percentage_negative_trades
|
|
45
|
+
- average_trade_duration
|
|
46
|
+
- average_trade_size
|
|
47
|
+
- average_trade_loss
|
|
48
|
+
- average_trade_loss_percentage
|
|
49
|
+
- average_trade_gain
|
|
50
|
+
- average_trade_gain_percentage
|
|
51
|
+
- average_trade_return
|
|
52
|
+
- average_trade_return_percentage
|
|
53
|
+
- median_trade_return
|
|
54
|
+
- number_of_trades
|
|
55
|
+
- number_of_trades_closed
|
|
56
|
+
- number_of_trades_opened
|
|
57
|
+
- number_of_trades_open_at_end
|
|
58
|
+
- win_rate
|
|
59
|
+
- current_win_rate
|
|
60
|
+
- win_loss_ratio
|
|
61
|
+
- current_win_loss_ratio
|
|
62
|
+
- percentage_winning_months
|
|
63
|
+
- percentage_winning_years
|
|
64
|
+
- average_monthly_return
|
|
65
|
+
- average_monthly_return_losing_months
|
|
66
|
+
- average_monthly_return_winning_months
|
|
67
|
+
- best_month
|
|
68
|
+
- best_year
|
|
69
|
+
- worst_month
|
|
70
|
+
- worst_year
|
|
71
|
+
- total_number_of_days
|
|
72
|
+
- current_average_trade_gain
|
|
73
|
+
- current_average_trade_return
|
|
74
|
+
- current_average_trade_duration
|
|
75
|
+
- current_average_trade_loss
|
|
76
|
+
"""
|
|
31
77
|
BALANCED = "balanced"
|
|
32
78
|
PROFIT = "profit"
|
|
33
79
|
FREQUENCY = "frequency"
|
|
@@ -73,44 +119,124 @@ class BacktestEvaluationFocus(Enum):
|
|
|
73
119
|
return BacktestEvaluationFocus.from_string(other) == self
|
|
74
120
|
|
|
75
121
|
def get_weights(self):
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
"""
|
|
123
|
+
Get evaluation weights for different focus areas.
|
|
124
|
+
Returns a dictionary with metric weights where:
|
|
125
|
+
- Positive weights favor higher values
|
|
126
|
+
- Negative weights favor lower values (penalties)
|
|
127
|
+
- Zero weights ignore the metric
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
if self == BacktestEvaluationFocus.BALANCED:
|
|
131
|
+
return {
|
|
132
|
+
# Core profitability metrics (moderate weight)
|
|
133
|
+
"total_net_gain_percentage": 2.0,
|
|
134
|
+
"cagr": 1.5,
|
|
135
|
+
"average_trade_return_percentage": 1.0,
|
|
136
|
+
|
|
137
|
+
# Risk-adjusted returns (important for balance)
|
|
138
|
+
"sharpe_ratio": 2.0,
|
|
139
|
+
"sortino_ratio": 1.5,
|
|
140
|
+
"calmar_ratio": 1.0,
|
|
141
|
+
"profit_factor": 1.5,
|
|
142
|
+
|
|
143
|
+
# Risk management (penalties for bad metrics)
|
|
144
|
+
"max_drawdown": -1.5,
|
|
145
|
+
"max_drawdown_duration": -0.5,
|
|
146
|
+
"annual_volatility": -0.8,
|
|
147
|
+
|
|
148
|
+
# Trading consistency
|
|
149
|
+
"win_rate": 1.5,
|
|
150
|
+
"win_loss_ratio": 1.0,
|
|
151
|
+
"number_of_trades": 0.8, # Some activity needed
|
|
152
|
+
|
|
153
|
+
# Efficiency metrics
|
|
154
|
+
"exposure_ratio": 0.5,
|
|
155
|
+
"trades_per_year": 0.3,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
elif self == BacktestEvaluationFocus.PROFIT:
|
|
159
|
+
return {
|
|
160
|
+
# Maximize absolute and relative profits
|
|
161
|
+
"total_net_gain_percentage": 3.0,
|
|
162
|
+
"cagr": 2.5,
|
|
163
|
+
"total_net_gain": 2.0,
|
|
164
|
+
"average_trade_return_percentage": 1.5,
|
|
165
|
+
"best_trade": 1.0,
|
|
166
|
+
|
|
167
|
+
# Profit consistency
|
|
168
|
+
"win_rate": 2.0,
|
|
169
|
+
"profit_factor": 2.0,
|
|
170
|
+
"percentage_positive_trades": 1.0,
|
|
171
|
+
|
|
172
|
+
# Risk secondary (but still important)
|
|
173
|
+
"sharpe_ratio": 1.0,
|
|
174
|
+
"max_drawdown": -1.0,
|
|
175
|
+
|
|
176
|
+
# Activity level (need some trades)
|
|
177
|
+
"number_of_trades": 0.5,
|
|
178
|
+
|
|
179
|
+
# Monthly/yearly consistency
|
|
180
|
+
"percentage_winning_months": 0.8,
|
|
181
|
+
"average_monthly_return": 1.0,
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
elif self == BacktestEvaluationFocus.FREQUENCY:
|
|
185
|
+
return {
|
|
186
|
+
# High trading activity with good results
|
|
187
|
+
"number_of_trades": 3.0,
|
|
188
|
+
"trades_per_year": 2.5,
|
|
189
|
+
"exposure_ratio": 2.0,
|
|
190
|
+
|
|
191
|
+
# Profitability per trade (scaled for frequency)
|
|
192
|
+
"average_trade_return_percentage": 2.0,
|
|
193
|
+
"win_rate": 2.5,
|
|
194
|
+
"total_net_gain_percentage": 1.5,
|
|
195
|
+
|
|
196
|
+
# Consistency across many trades
|
|
197
|
+
"win_loss_ratio": 1.5,
|
|
198
|
+
"percentage_positive_trades": 1.0,
|
|
199
|
+
|
|
200
|
+
# Risk management for frequent trading
|
|
201
|
+
"max_drawdown": -1.5,
|
|
202
|
+
"sharpe_ratio": 1.0,
|
|
203
|
+
"profit_factor": 1.2,
|
|
204
|
+
|
|
205
|
+
# Duration efficiency
|
|
206
|
+
"average_trade_duration": -0.3, # Prefer shorter trades
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
elif self == BacktestEvaluationFocus.RISK_ADJUSTED:
|
|
210
|
+
return {
|
|
211
|
+
# Risk-adjusted performance metrics (highest priority)
|
|
212
|
+
"sharpe_ratio": 3.0,
|
|
213
|
+
"sortino_ratio": 2.5,
|
|
214
|
+
"calmar_ratio": 2.0,
|
|
215
|
+
|
|
216
|
+
# Risk management (strong penalties)
|
|
217
|
+
"max_drawdown": -3.0,
|
|
218
|
+
"max_drawdown_duration": -1.5,
|
|
219
|
+
"annual_volatility": -2.0,
|
|
220
|
+
"worst_trade": -1.0,
|
|
221
|
+
|
|
222
|
+
# Consistent performance
|
|
223
|
+
"win_rate": 2.0,
|
|
224
|
+
"win_loss_ratio": 1.5,
|
|
225
|
+
"percentage_winning_months": 1.5,
|
|
226
|
+
|
|
227
|
+
# Stable returns
|
|
228
|
+
"average_trade_return_percentage": 1.5,
|
|
229
|
+
"total_net_gain_percentage": 1.0,
|
|
230
|
+
"profit_factor": 1.8,
|
|
231
|
+
|
|
232
|
+
# Reasonable activity
|
|
233
|
+
"number_of_trades": 0.5,
|
|
234
|
+
|
|
235
|
+
# Downside protection
|
|
236
|
+
"average_trade_loss_percentage": -1.0,
|
|
237
|
+
"percentage_negative_trades": -1.0,
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Fallback to balanced if unknown focus
|
|
241
|
+
return self.get_weights() \
|
|
242
|
+
if self != BacktestEvaluationFocus.BALANCED else {}
|
|
@@ -268,6 +268,11 @@ class BacktestService:
|
|
|
268
268
|
# Trade generation
|
|
269
269
|
last_trade = None
|
|
270
270
|
|
|
271
|
+
# Align signals with most granular OHLCV data
|
|
272
|
+
close = df["Close"].reindex(index, method='ffill')
|
|
273
|
+
buy_signal = buy_signals[symbol].reindex(index, fill_value=False)
|
|
274
|
+
sell_signal = sell_signals[symbol].reindex(index, fill_value=False)
|
|
275
|
+
|
|
271
276
|
# Loop over all timestamps in the backtest
|
|
272
277
|
for i in range(len(index)):
|
|
273
278
|
|
|
@@ -86,7 +86,7 @@ investing_algorithm_framework/domain/__init__.py,sha256=PASQlRGcU_MDIwnLppanXGo-
|
|
|
86
86
|
investing_algorithm_framework/domain/backtesting/__init__.py,sha256=q-NejGHzE233w5jXPhSsuLpBZ_yl3m-qb2g6FnxZaps,699
|
|
87
87
|
investing_algorithm_framework/domain/backtesting/backtest.py,sha256=mS7JdPTXhw5AQrQ-krXWtpNsBbVVYkxc1lBSoPhCqoQ,15617
|
|
88
88
|
investing_algorithm_framework/domain/backtesting/backtest_date_range.py,sha256=e_V7HMdtln4uu87jwwa_Yr7ZesgrpFqsEqtr0e0DTto,3186
|
|
89
|
-
investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py,sha256=
|
|
89
|
+
investing_algorithm_framework/domain/backtesting/backtest_evaluation_focuss.py,sha256=D__3I_TSxDVnGtlddmWt4wHcqut8MGyYMf1IfQZXYJ0,7547
|
|
90
90
|
investing_algorithm_framework/domain/backtesting/backtest_metrics.py,sha256=HR0bEDT3xh-TQq50PLDcKhYggjtnE-JTRuY2TlXz54w,19552
|
|
91
91
|
investing_algorithm_framework/domain/backtesting/backtest_permutation_test.py,sha256=8JXdu3EgFh2f2Yc41OYwIBwlYtjFiumyAJUrN5kL078,6703
|
|
92
92
|
investing_algorithm_framework/domain/backtesting/backtest_run.py,sha256=ffQgilEkyixGrGvKeCZF670OPoY3ljixlgsXPajHpZY,14310
|
|
@@ -202,7 +202,7 @@ investing_algorithm_framework/infrastructure/services/azure/__init__.py,sha256=P
|
|
|
202
202
|
investing_algorithm_framework/infrastructure/services/azure/state_handler.py,sha256=EUk4PdVl6RQ19DuWdrC4DzgOhGcL3qiZKWgWh_obT4E,5240
|
|
203
203
|
investing_algorithm_framework/services/__init__.py,sha256=9p0Y2enp6UMOlU4qJgVoojHBRARLGefNzbPxgSCN0wI,4999
|
|
204
204
|
investing_algorithm_framework/services/backtesting/__init__.py,sha256=sD6JMQVuUT8NRKV77VC9jyGnHcGox0W2n9eA-4ydeHY,84
|
|
205
|
-
investing_algorithm_framework/services/backtesting/backtest_service.py,sha256=
|
|
205
|
+
investing_algorithm_framework/services/backtesting/backtest_service.py,sha256=jNd3s0qc9_PGMZAKnW0PB8kQ8Mub05n7UMcq2eB1s-8,23707
|
|
206
206
|
investing_algorithm_framework/services/configuration_service.py,sha256=BCgiBlrLjMjfU4afmjYaHu9gOWNmgaxhf6RBN2XJkw0,2853
|
|
207
207
|
investing_algorithm_framework/services/data_providers/__init__.py,sha256=OHVccpIYGc-1B2AkCI_2Nhsb9KMaAUrng4DHhIbFD8Y,96
|
|
208
208
|
investing_algorithm_framework/services/data_providers/data_provider_service.py,sha256=Tv5W38rshK7sG7XEhp7L-McdiNWAAlvU_1ScSdt1NCE,28420
|
|
@@ -252,8 +252,8 @@ investing_algorithm_framework/services/trade_order_evaluator/default_trade_order
|
|
|
252
252
|
investing_algorithm_framework/services/trade_order_evaluator/trade_order_evaluator.py,sha256=pNnmgaKMR9RY6Kxq7xS0nURKoaQDe2ehrP5GfElkkcI,1328
|
|
253
253
|
investing_algorithm_framework/services/trade_service/__init__.py,sha256=AcwPyJjDRdiREnl_MWMkDSc-V-ZjXtvpHD6eQT9mc1o,68
|
|
254
254
|
investing_algorithm_framework/services/trade_service/trade_service.py,sha256=OtzIS5EebByGcqDvV2AFeBjXSarvrgubMXDaVKg6Rbw,41193
|
|
255
|
-
investing_algorithm_framework-7.16.
|
|
256
|
-
investing_algorithm_framework-7.16.
|
|
257
|
-
investing_algorithm_framework-7.16.
|
|
258
|
-
investing_algorithm_framework-7.16.
|
|
259
|
-
investing_algorithm_framework-7.16.
|
|
255
|
+
investing_algorithm_framework-7.16.11.dist-info/LICENSE,sha256=wbVEDvoZiMPHufRY3sLEffvAr7GH5hOIngHF8y4HFQg,11343
|
|
256
|
+
investing_algorithm_framework-7.16.11.dist-info/METADATA,sha256=2zYYO7C5y7OYuUwcIVSOdmJVGIanjNbIohwd7c9cl4M,19636
|
|
257
|
+
investing_algorithm_framework-7.16.11.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
258
|
+
investing_algorithm_framework-7.16.11.dist-info/entry_points.txt,sha256=jrPF0YksDs27vYzEvj3tXLe3OGWU24EJA05z5xHqmq8,91
|
|
259
|
+
investing_algorithm_framework-7.16.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|