From 5b80eac20713e4a705faa50d4cf4cb6de859538a Mon Sep 17 00:00:00 2001 From: Sam Fredrickson Date: Fri, 15 Nov 2024 10:22:12 -0800 Subject: [PATCH] Run projections and backtests in parallel. --- model.py | 111 ++++++++++++++++++++++++++++++----------------------- prices.csv | 2 +- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/model.py b/model.py index 67c0880..d58481e 100644 --- a/model.py +++ b/model.py @@ -5,6 +5,7 @@ import matplotlib.pyplot as plt import seaborn as sns from scipy.stats import norm from scipy.signal import savgol_filter +from multiprocessing import Process # Utility functions @@ -948,68 +949,80 @@ def create_backtest_plot( return historical_projections -if __name__ == "__main__": - analysis, df = analyze_bitcoin_prices("prices.csv") - # create_plots(df) # Full history - # create_plots(df, start='2022-01-01') # From 2022 onwards - # create_plots(df, start='2023-01-01', end='2023-12-31') # Just 2023 - # Create plots with different time ranges and projections - projections = create_plots(df, start="2011-01-01", project_days=365 * 4) +def run_projection(df): + projections = create_plots(df, start="2016-07-09", project_days=365 * 4) print("\nProjected Prices at Key Points:") print(projections.iloc[[29, 89, 179, 364]].round(2)) # 30, 90, 180, 365 days + +def run_backtest(params, df): + print( + f"\nRunning backtest from {params['start_date']} to {params['backtest_date']}" + ) + backtest_projections = create_backtest_plot(df, **params) + + # Print some key projection points vs actual prices + print("\nBacktest Results - Projected vs Actual Prices:") + validation_df = df[df["Date"] > params["backtest_date"]] + actual_prices = validation_df.set_index("Date")["Close"] + + for days in [30, 90, 180, 365]: + target_date = pd.to_datetime(params["backtest_date"]) + pd.Timedelta(days=days) + if ( + target_date in actual_prices.index + and target_date in backtest_projections.index + ): + projected = backtest_projections.loc[target_date] + actual = actual_prices.loc[target_date] + print(f"\n{days} days out ({target_date.strftime('%Y-%m-%d')}):") + print(f"Actual Price: ${actual:,.2f}") + print(f"Projected (Expected): ${projected['Expected_Trend']:,.2f}") + print( + f"Projected Range: ${projected['Lower_95']:,.2f} - ${projected['Upper_95']:,.2f}" + ) + + +if __name__ == "__main__": + analysis, df = analyze_bitcoin_prices("prices.csv") + procs = [] + + # Create main projection + proc = Process(target=run_projection, args=(df,)) + proc.start() + procs.append(proc) + # Create multiple backtests for different periods backtests = [ - # First to second halving + # First until fourth halving { - "start_date": "2012-11-28", # First halving - "backtest_date": "2016-07-09", # Second halving - "project_days": 1460, # 4 years + "start_date": "2012-11-28", + "backtest_date": "2024-04-19", + "project_days": 1460, }, - # Second to third halving + # First until third halving { - "start_date": "2016-07-09", # Second halving - "backtest_date": "2020-05-11", # Third halving - "project_days": 1460, # 4 years + "start_date": "2012-11-28", + "backtest_date": "2020-05-11", + "project_days": 1460, }, - # Third halving onwards + # Second until fourth halving { - "start_date": "2020-05-11", # Third halving - "backtest_date": "2024-04-19", # Fourth halving (projected) - "project_days": 1460, # 4 years - }, - { - "start_date": "2016-07-09", # Second halving - "backtest_date": "2024-04-19", # Fourth halving (projected) - "project_days": 1460, # 4 years + "start_date": "2016-07-09", + "backtest_date": "2024-04-19", + "project_days": 1460, }, ] # Run all backtests for params in backtests: - print( - f"\nRunning backtest from {params['start_date']} to {params['backtest_date']}" + proc = Process( + target=run_backtest, + args=( + params, + df, + ), ) - backtest_projections = create_backtest_plot(df, **params) - - # Print some key projection points vs actual prices - print("\nBacktest Results - Projected vs Actual Prices:") - validation_df = df[df["Date"] > params["backtest_date"]] - actual_prices = validation_df.set_index("Date")["Close"] - - for days in [30, 90, 180, 365]: - target_date = pd.to_datetime(params["backtest_date"]) + pd.Timedelta( - days=days - ) - if ( - target_date in actual_prices.index - and target_date in backtest_projections.index - ): - projected = backtest_projections.loc[target_date] - actual = actual_prices.loc[target_date] - print(f"\n{days} days out ({target_date.strftime('%Y-%m-%d')}):") - print(f"Actual Price: ${actual:,.2f}") - print(f"Projected (Expected): ${projected['Expected_Trend']:,.2f}") - print( - f"Projected Range: ${projected['Lower_95']:,.2f} - ${projected['Upper_95']:,.2f}" - ) + procs.append(proc) + proc.start() + for proc in procs: + proc.join() diff --git a/prices.csv b/prices.csv index e3aa638..324ff7c 100644 --- a/prices.csv +++ b/prices.csv @@ -1,5 +1,5 @@ "Date","Price","Open","High","Low","Vol.","Change %" -"11/15/2024","88,096.2","87,297.2","88,348.6","87,276.2","109.10K","0.92%" +"11/15/2024","89,481.8","87,297.2","90,670.6","87,118.8","159.36K","2.51%" "11/14/2024","87,294.0","90,424.8","91,726.7","86,740.2","153.34K","-3.46%" "11/13/2024","90,422.2","87,971.2","93,226.6","86,168.4","257.57K","2.82%" "11/12/2024","87,941.3","88,665.0","89,929.6","85,122.2","288.68K","-0.82%"