Skip to content

Commit 8609b79

Browse files
committed
Fix backtesting reporting
1 parent a47add5 commit 8609b79

24 files changed

+252
-6837
lines changed

investing_algorithm_framework/app/algorithm.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,21 @@ def _validate_name(self, name):
9494
)
9595

9696
pattern = re.compile(r"^[a-zA-Z0-9]*$")
97+
9798
if not pattern.match(name):
9899
raise OperationalException(
99100
"The name of the algorithm can only contain" +
100101
" letters and numbers"
101102
)
102103

104+
illegal_chars = r"[\/:*?\"<>|]"
105+
106+
if re.search(illegal_chars, name):
107+
raise OperationalException(
108+
f"Illegal characters detected in algorithm: {name}. "
109+
f"Illegal characters: / \\ : * ? \" < > |"
110+
)
111+
103112
def initialize_services(
104113
self,
105114
configuration_service,
@@ -159,6 +168,11 @@ def start(self, number_of_iterations: int = None):
159168
def name(self):
160169
return self._name
161170

171+
@name.setter
172+
def name(self, name):
173+
self._validate_name(name)
174+
self._name = name
175+
162176
@property
163177
def data_sources(self):
164178
return self._data_sources

investing_algorithm_framework/app/app.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ def run_backtest(
773773
Run a backtest for an algorithm. This method should be called when
774774
running a backtest.
775775
776-
Parameters:
776+
Args:
777777
backtest_date_range: The date range to run the backtest for
778778
(instance of BacktestDateRange)
779779
initial_amount: The initial amount to start the backtest with.
@@ -812,8 +812,6 @@ def run_backtest(
812812
initial_amount=initial_amount,
813813
backtest_date_range=backtest_date_range
814814
)
815-
backtest_report_writer_service = self.container \
816-
.backtest_report_writer_service()
817815

818816
config = self.container.configuration_service().get_config()
819817

@@ -822,7 +820,7 @@ def run_backtest(
822820
config[RESOURCE_DIRECTORY], "backtest_reports"
823821
)
824822

825-
backtest_report_writer_service.write_report_to_json(
823+
backtest_service.write_report_to_json(
826824
report=report, output_directory=output_directory
827825
)
828826

@@ -840,7 +838,7 @@ def run_backtests(
840838
Run a backtest for a set algorithm. This method should be called when
841839
running a backtest.
842840
843-
Parameters:
841+
Args:
844842
Algorithms: List[Algorithm] - The algorithms to run backtests for
845843
date_ranges: List[BacktestDateRange] - The date ranges to run the
846844
backtests for
@@ -916,15 +914,12 @@ def run_backtests(
916914
if date_range.name is not None:
917915
report.date_range_name = date_range.name
918916

919-
backtest_report_writer_service = self.container \
920-
.backtest_report_writer_service()
921-
922917
if output_directory is None:
923918
output_directory = os.path.join(
924919
self.config[RESOURCE_DIRECTORY], "backtest_reports"
925920
)
926921

927-
backtest_report_writer_service.write_report_to_json(
922+
backtest_service.write_report_to_json(
928923
report=report, output_directory=output_directory
929924
)
930925
reports.append(report)

investing_algorithm_framework/dependency_container.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
PositionService, PortfolioService, StrategyOrchestratorService, \
1010
PortfolioConfigurationService, MarketDataSourceService, BacktestService, \
1111
ConfigurationService, PortfolioSnapshotService, PositionSnapshotService, \
12-
MarketCredentialService, TradeService, BacktestReportWriterService, \
13-
PortfolioSyncService
12+
MarketCredentialService, TradeService, PortfolioSyncService
1413

1514

1615
def setup_dependency_container(app, modules=None, packages=None):
@@ -132,9 +131,6 @@ class DependencyContainer(containers.DeclarativeContainer):
132131
market_data_source_service=market_data_source_service,
133132
portfolio_configuration_service=portfolio_configuration_service,
134133
)
135-
backtest_report_writer_service = providers.Factory(
136-
BacktestReportWriterService,
137-
)
138134
algorithm = providers.Factory(
139135
Algorithm,
140136
configuration_service=configuration_service,

investing_algorithm_framework/domain/services/market_data_sources.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ def _data_source_exists(self, file_path):
4949
5050
This function prevents the backtest datasource to download the data
5151
every time the backtest is run.
52+
53+
Args:
54+
file_path: str - the file path of the data storage file
55+
56+
Returns:
57+
bool - True if the file exists and the column names are correct,
5258
"""
5359
try:
5460
if os.path.isfile(file_path):
@@ -444,6 +450,15 @@ def get_date_ranges(
444450
Function to get the date ranges of the market data source based
445451
on the window size and the time_frame. The date ranges
446452
will be calculated based on the start date and the end date.
453+
454+
Args:
455+
start_date: datetime - The start date
456+
end_date: datetime - The end date
457+
window_size: int - The window size
458+
time_frame: str - The time frame
459+
460+
Returns:
461+
list - A list of tuples with the date ranges
447462
"""
448463

449464
if start_date > end_date:

investing_algorithm_framework/domain/services/market_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def get_market_credential(self, market):
140140

141141
for market_data_credentials in self.market_credentials:
142142

143-
if market_data_credentials.market.lower() == market.lower():
143+
if market_data_credentials.market.upper() == market.upper():
144144
return market_data_credentials
145145

146146
return None

investing_algorithm_framework/infrastructure/models/market_data_sources/ccxt.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ def prepare_data(
7474
7575
When downloading the data it will use the ccxt library.
7676
77-
Parameters:
78-
config: dict - the configuration of the data source
79-
backtest_start_date: datetime - the start date of the backtest
80-
backtest_end_date: datetime - the end date of the backtest
81-
time_frame: string - the time frame of the data
82-
window_size: int - the total amount of candle sticks that need to
77+
Args:
78+
config (dict): the configuration of the data source
79+
backtest_start_date (datetime): the start date of the backtest
80+
backtest_end_date (datetime): the end date of the backtest
81+
time_frame (string): the time frame of the data
82+
window_size (int): the total amount of candle sticks that need to
8383
be returned
8484
8585
Returns:
@@ -137,6 +137,14 @@ def prepare_data(
137137
to_timestamp=backtest_end_date,
138138
market=self.market
139139
)
140+
141+
if len(ohlcv) == 0:
142+
raise OperationalException(
143+
f"No data found for {self.symbol} " +
144+
f"for date range: {backtest_data_start_date} " +
145+
f"to {backtest_end_date}. Please make sure that " +
146+
"the market has data for this date range."
147+
)
140148
self.write_data_to_file_path(file_path, ohlcv)
141149

142150
self.load_data()

investing_algorithm_framework/services/__init__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from .backtesting import BacktestService, BacktestReportWriterService, \
2-
create_trade_exit_markers_chart, create_trade_entry_markers_chart
1+
from .backtesting import BacktestService
32
from .configuration_service import ConfigurationService
43
from .market_credential_service import MarketCredentialService
54
from .market_data_source_service import MarketDataSourceService, \
@@ -23,7 +22,6 @@
2322
"PortfolioConfigurationService",
2423
"MarketDataSourceService",
2524
"BacktestService",
26-
"BacktestReportWriterService",
2725
"OrderBacktestService",
2826
"ConfigurationService",
2927
"PortfolioSyncService",
@@ -33,6 +31,4 @@
3331
"BacktestMarketDataSourceService",
3432
"BacktestPortfolioService",
3533
"TradeService",
36-
"create_trade_entry_markers_chart",
37-
"create_trade_exit_markers_chart"
3834
]
Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
from .backtest_report_writer_service import BacktestReportWriterService
21
from .backtest_service import BacktestService
3-
from .graphs import create_trade_entry_markers_chart, \
4-
create_trade_exit_markers_chart
5-
62

73
__all__ = [
8-
"BacktestReportWriterService",
94
"BacktestService",
10-
"create_trade_entry_markers_chart",
11-
"create_trade_exit_markers_chart"
125
]

investing_algorithm_framework/services/backtesting/backtest_report_writer_service.py

Lines changed: 0 additions & 91 deletions
This file was deleted.

0 commit comments

Comments
 (0)