Skip to content

Commit bb84700

Browse files
committed
Fix report formatting
1 parent 532f5a8 commit bb84700

File tree

72 files changed

+7930
-1995
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+7930
-1995
lines changed

.flake8

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ exclude =
33
investing_algorithm_framework/app/reporting/
44
investing_algorithm_framework/infrastructure/database/sql_alchemy.py
55
examples
6-
investing_algorithm_framework/metrics
6+
investing_algorithm_framework/services/metrics

examples/backtest_example/run_backtest.ipynb

Lines changed: 175 additions & 437 deletions
Large diffs are not rendered by default.

examples/backtest_example/run_multiple_backtests.ipynb

Lines changed: 0 additions & 61 deletions
This file was deleted.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
1+
from investing_algorithm_framework import CCXTOHLCVMarketDataSource
2+
13
from .strategy_v1 import CrossOverStrategyV1
24

5+
6+
7+
def configure_strategy(
8+
time_unit,
9+
interval,
10+
assets,
11+
time_frame,
12+
fast,
13+
slow,
14+
trend,
15+
stop_loss_percentage,
16+
stop_loss_sell_size,
17+
take_profit_percentage,
18+
take_profit_sell_size
19+
):
20+
data_providers = []
21+
22+
for asset in assets:
23+
data_providers.append(
24+
CCXTOHLCVMarketDataSource(
25+
identifier=f"{asset}-ohlcv-{time_frame.value}",
26+
market="bitvavo",
27+
symbol=asset,
28+
time_frame=time_frame,
29+
window_size=200
30+
)
31+
)
32+
33+
strategy = CrossOverStrategyV1(
34+
time_unit=time_unit,
35+
interval=interval,
36+
symbol_pairs=assets,
37+
market_data_sources=data_providers,
38+
fast=fast,
39+
slow=slow,
40+
trend=trend,
41+
stop_loss_percentage=stop_loss_percentage,
42+
stop_loss_sell_size=stop_loss_sell_size,
43+
take_profit_percentage=take_profit_percentage,
44+
take_profit_sell_size=take_profit_sell_size
45+
)
46+
return strategy
47+
48+
349
__all__ = [
450
"CrossOverStrategyV1",
551
]

examples/backtest_example/strategies/strategy_v1/strategy_v1.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,34 @@ class CrossOverStrategyV1(TradingStrategy):
3333
take_profit_percentage = 8
3434
take_profit_sell_size = 50
3535

36+
def __init__(
37+
self,
38+
time_unit: TimeUnit = TimeUnit.HOUR,
39+
interval: int = 2,
40+
symbol_pairs: list[str] = None,
41+
market_data_sources=None,
42+
fast: int = 50,
43+
slow: int = 100,
44+
trend: int = 200,
45+
stop_loss_percentage: float = 2.0,
46+
stop_loss_sell_size: float = 50.0,
47+
take_profit_percentage: float = 8.0,
48+
take_profit_sell_size: float = 50.0
49+
):
50+
super().__init__(
51+
time_unit=time_unit,
52+
interval=interval,
53+
market_data_sources=market_data_sources or self.market_data_sources
54+
)
55+
self.symbol_pairs = symbol_pairs or self.symbol_pairs
56+
self.fast = fast
57+
self.slow = slow
58+
self.trend = trend
59+
self.stop_loss_percentage = stop_loss_percentage
60+
self.stop_loss_sell_size = stop_loss_sell_size
61+
self.take_profit_percentage = take_profit_percentage
62+
self.take_profit_sell_size = take_profit_sell_size
63+
3664
def apply_strategy(self, context: Context, market_data):
3765

3866
for pair in self.symbol_pairs:

investing_algorithm_framework/__init__.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from investing_algorithm_framework.app import App, Algorithm, \
22
TradingStrategy, StatelessAction, Task, AppHook, Context, \
3-
add_html_report, add_metrics, BacktestReport, \
4-
BacktestReportsEvaluation, pretty_print_trades, pretty_print_positions, \
3+
add_html_report, BacktestReport, \
4+
pretty_print_trades, pretty_print_positions, \
55
pretty_print_orders, pretty_print_backtest, select_backtest_date_ranges
66
from investing_algorithm_framework.domain import ApiException, \
77
TradingDataType, TradingTimeFrame, OrderType, OperationalException, \
@@ -12,7 +12,7 @@
1212
TickerMarketDataSource, MarketService, \
1313
RESERVED_BALANCES, APP_MODE, AppMode, DATETIME_FORMAT, \
1414
BacktestDateRange, convert_polars_to_pandas, \
15-
DateRange, DEFAULT_LOGGING_CONFIG, \
15+
DEFAULT_LOGGING_CONFIG, \
1616
BacktestResult, TradeStatus, MarketDataType, TradeRiskType, \
1717
APPLICATION_DIRECTORY, DataSource, OrderExecutor, PortfolioProvider, \
1818
SnapshotInterval, AWS_S3_STATE_BUCKET_NAME
@@ -61,7 +61,6 @@
6161
"MarketCredential",
6262
"MarketService",
6363
"OperationalException",
64-
"BacktestReportsEvaluation",
6564
"SYMBOLS",
6665
"RESERVED_BALANCES",
6766
"APP_MODE",
@@ -70,7 +69,6 @@
7069
"BacktestResult",
7170
"BacktestDateRange",
7271
"convert_polars_to_pandas",
73-
"DateRange",
7472
"AzureBlobStorageStateHandler",
7573
"DEFAULT_LOGGING_CONFIG",
7674
"BacktestReport",
@@ -89,7 +87,6 @@
8987
"PandasOHLCVBacktestMarketDataSource",
9088
"PandasOHLCVMarketDataSource",
9189
"SnapshotInterval",
92-
"add_metrics",
9390
"add_html_report",
9491
"AWSS3StorageStateHandler",
9592
"AWS_S3_STATE_BUCKET_NAME",

investing_algorithm_framework/app/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
from investing_algorithm_framework.app.web import create_flask_app
66
from .algorithm import Algorithm
77
from .context import Context
8-
from .reporting import add_html_report, add_metrics, \
9-
BacktestReport, pretty_print_backtest, BacktestReportsEvaluation, \
10-
pretty_print_trades, pretty_print_positions, pretty_print_orders
8+
from .reporting import add_html_report, \
9+
BacktestReport, pretty_print_backtest, pretty_print_trades, \
10+
pretty_print_positions, pretty_print_orders
1111
from .analysis import select_backtest_date_ranges
1212

1313

@@ -21,10 +21,8 @@
2121
"AppHook",
2222
"Context",
2323
"add_html_report",
24-
"add_metrics",
2524
"BacktestReport",
2625
"pretty_print_backtest",
27-
"BacktestReportsEvaluation",
2826
"pretty_print_trades",
2927
"pretty_print_positions",
3028
"pretty_print_orders",

investing_algorithm_framework/app/app.py

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
SQLALCHEMY_DATABASE_URI, OperationalException, StateHandler, \
1919
BACKTESTING_START_DATE, BACKTESTING_END_DATE, APP_MODE, MarketCredential, \
2020
AppMode, BacktestDateRange, DATABASE_DIRECTORY_NAME, \
21-
BACKTESTING_INITIAL_AMOUNT, SNAPSHOT_INTERVAL, \
21+
BACKTESTING_INITIAL_AMOUNT, SNAPSHOT_INTERVAL, Backtest, \
2222
MarketDataSource, PortfolioConfiguration, SnapshotInterval, \
2323
PortfolioProvider, OrderExecutor, ImproperlyConfigured
2424
from investing_algorithm_framework.infrastructure import setup_sqlalchemy, \
@@ -722,9 +722,9 @@ def run_backtest(
722722
save=True,
723723
snapshot_interval: SnapshotInterval = SnapshotInterval.TRADE_CLOSE,
724724
strategy_directory_path: Optional[str] = None,
725-
report_name: Optional[str] = None,
725+
backtest_directory_name: Optional[str] = None,
726726
risk_free_rate: Optional[float] = None
727-
) -> BacktestReport:
727+
) -> Backtest:
728728
"""
729729
Run a backtest for an algorithm.
730730
@@ -738,14 +738,13 @@ def run_backtest(
738738
portfolio will start with.
739739
strategy (TradingStrategy) (Optional): The strategy object
740740
that needs to be backtested.
741-
strategies (List[TradingStrategy) (Optional): List of strategy
741+
strategies (List[TradingStrategy]) (Optional): List of strategy
742742
objects that need to be backtested
743-
algorithm:
744-
output_directory: str - The directory to
745-
write the backtest report to
746-
save_strategy: bool - Whether to save the strategy
747-
as part of the backtest report. You can only save in-memory
748-
strategies when running multiple backtests. This is because
743+
algorithm (Algorithm) (Optional): The algorithm object that needs
744+
to be backtested. If this is provided, then the strategies
745+
and tasks of the algorithm will be used for the backtest.
746+
output_directory (str) (Optional): The directory to write
747+
the backtest report to
749748
snapshot_interval (SnapshotInterval): The snapshot
750749
interval to use for the backtest. This is used to determine
751750
how often the portfolio snapshot should be taken during the
@@ -756,7 +755,7 @@ def run_backtest(
756755
strategy if save_strategy is True. If not provided,
757756
the framework tries to determine the path via the
758757
algorithm or strategy object.
759-
report_name (Optional[str]): The name of the report. If not
758+
backtest_directory_name (Optional[str]): If not
760759
provided, the framework will generate a name based on the
761760
algorithm name and the backtest date range and the current
762761
date and time.
@@ -821,23 +820,13 @@ def run_backtest(
821820
portfolio_service = self.container.portfolio_service()
822821
portfolio_service.clear_observers()
823822
portfolio_service.add_observer(portfolio_snapshot_service)
824-
825-
# Run the backtest with the backtest_service and collect and
826-
# save the report
827-
results = backtest_service.run_backtest(
823+
backtest = backtest_service.run_backtest(
828824
algorithm=algorithm,
829825
context=context,
830826
strategy_orchestrator_service=strategy_orchestrator_service,
831827
initial_amount=initial_amount,
832-
backtest_date_range=backtest_date_range
833-
)
834-
market_data_source_service = \
835-
self.container.market_data_source_service()
836-
report = BacktestReport.create(
837-
results=results,
828+
backtest_date_range=backtest_date_range,
838829
risk_free_rate=risk_free_rate,
839-
data_files=market_data_source_service.get_data_files(),
840-
algorithm=algorithm,
841830
strategy_directory_path=strategy_directory_path
842831
)
843832

@@ -846,14 +835,18 @@ def run_backtest(
846835
config[RESOURCE_DIRECTORY], "backtest_reports"
847836
)
848837

849-
if report_name is None:
850-
report_name = BacktestService.create_report_directory_name(report)
838+
if backtest_directory_name is None:
839+
backtest_directory_name = BacktestService\
840+
.create_report_directory_name(backtest)
851841

852-
output_directory = os.path.join(output_directory, report_name)
842+
output_directory = os.path.join(
843+
output_directory, backtest_directory_name
844+
)
853845

854846
if save:
855-
report.save(path=output_directory)
856-
return report
847+
backtest.save(directory_path=output_directory)
848+
849+
return backtest
857850

858851
def run_backtests(
859852
self,

investing_algorithm_framework/app/reporting/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
from .generate import add_html_report, add_metrics
1+
from .generate import add_html_report
22
from .backtest_report import BacktestReport
33
from .ascii import pretty_print_backtest, pretty_print_positions, \
44
pretty_print_trades, pretty_print_orders
5-
from .evaluation import BacktestReportsEvaluation
65

76
__all__ = [
87
"add_html_report",
9-
"add_metrics",
108
"BacktestReport",
119
"pretty_print_backtest",
12-
"BacktestReportsEvaluation",
1310
"pretty_print_positions",
1411
"pretty_print_trades",
1512
"pretty_print_orders"

0 commit comments

Comments
 (0)