|
22 | 22 | r"backtest-end-date_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}_" |
23 | 23 | r"created-at_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}\.json$" |
24 | 24 | ) |
| 25 | +BACKTEST_REPORT_DIRECTORY_PATTERN = ( |
| 26 | + r"^report_\w+_backtest-start-date_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}_" |
| 27 | + r"backtest-end-date_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}_" |
| 28 | + r"created-at_\d{4}-\d{2}-\d{2}:\d{2}:\d{2}$" |
| 29 | +) |
25 | 30 |
|
26 | 31 |
|
27 | 32 | def validate_algorithm_name(name, illegal_chars=r"[\/:*?\"<>|]"): |
@@ -690,7 +695,27 @@ def save_report( |
690 | 695 | algorithm, |
691 | 696 | output_directory: str |
692 | 697 | ) -> None: |
693 | | - output_directory = os.path.join(output_directory, algorithm.name) |
| 698 | + output_directory = self.create_report_directory( |
| 699 | + report, output_directory, algorithm.name |
| 700 | + ) |
| 701 | + |
| 702 | + |
| 703 | + if self.is_running_in_notebook(): |
| 704 | + strategys = algorithm.strategies |
| 705 | + |
| 706 | + for strategy in strategys: |
| 707 | + self.save_strategy(strategy, output_directory) |
| 708 | + else: |
| 709 | + # Copy over all files in the strategy directory |
| 710 | + # to the output directory |
| 711 | + strategy_directory = os.path.dirname( |
| 712 | + inspect.getfile(algorithm.__class__) |
| 713 | + ) |
| 714 | + strategy_files = os.listdir(strategy_directory) |
| 715 | + |
| 716 | + |
| 717 | + |
| 718 | + |
694 | 719 | collected_imports = set() |
695 | 720 | class_definitions = [] |
696 | 721 | self.write_report_to_json(report, output_directory) |
@@ -838,3 +863,44 @@ def create_report_file_path( |
838 | 863 | f"{backtest_end_date}_created-at_{created_at}{extension}" |
839 | 864 | ) |
840 | 865 | return file_path |
| 866 | + |
| 867 | + @staticmethod |
| 868 | + def create_report_directory( |
| 869 | + report, output_directory, algorithm_name |
| 870 | + ) -> str: |
| 871 | + """ |
| 872 | + Function to create a directory for a backtest report. |
| 873 | +
|
| 874 | + Args: |
| 875 | + report: BacktestReport - The backtest report to create a |
| 876 | + directory for. |
| 877 | + output_directory: str - The directory to store the backtest |
| 878 | + report file. |
| 879 | + algorithm_name: str - The name of the algorithm to |
| 880 | + create a directory for. |
| 881 | +
|
| 882 | + Returns: |
| 883 | + directory_path: str The directory path for the |
| 884 | + backtest report file. |
| 885 | + """ |
| 886 | + |
| 887 | + backtest_start_date = report.backtest_start_date \ |
| 888 | + .strftime(DATETIME_FORMAT_BACKTESTING) |
| 889 | + backtest_end_date = report.backtest_end_date \ |
| 890 | + .strftime(DATETIME_FORMAT_BACKTESTING) |
| 891 | + created_at = report.created_at.strftime(DATETIME_FORMAT_BACKTESTING) |
| 892 | + directory_path = os.path.join( |
| 893 | + output_directory, |
| 894 | + f"{algorithm_name}_backtest-start-date_" |
| 895 | + f"{backtest_start_date}_backtest-end-date_" |
| 896 | + f"{backtest_end_date}_created-at_{created_at}" |
| 897 | + ) |
| 898 | + return directory_path |
| 899 | + |
| 900 | + def is_running_in_notebook(): |
| 901 | + try: |
| 902 | + # Jupyter-specific modules |
| 903 | + from IPython import get_ipython |
| 904 | + return get_ipython() is not None |
| 905 | + except ImportError: |
| 906 | + return False |
0 commit comments