Last active
April 25, 2022 16:29
-
-
Save marcosan93/7dda5998c7031225e488896e674cebda to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def parameterTuning(stock, n_days_lst, training_days_lst, mov_avg_lst, | |
forecast_period_lst, fbp_intervals, stop_early=True): | |
""" | |
Given a list of parameters for a specific stock. Iterates through | |
different combination of parameters until a successful backtest | |
performance is found. | |
Optional stop_early variable for stopping tuning immediately | |
when a positive backtest result is found | |
""" | |
# Tuning the stock with FB Prophet | |
print(f"Tuning FBP parameters for {stock}. . .") | |
# All combinations of the parameters | |
params = [n_days_lst, training_days_lst, mov_avg_lst, forecast_period_lst, fbp_intervals] | |
lst_params = list(itertools.product(*params)) | |
# Randomizing order of params | |
random.shuffle(lst_params) | |
# List of tested params | |
param_lst = [] | |
# Iterating through combos | |
for param in tqdm(lst_params): | |
# Retrieving prices with the given parameters | |
prices, price_history = getStockPrices( | |
stock, | |
n_days=param[0], | |
training_days=param[1], | |
mov_avg=param[2] | |
) | |
# Checking if the prices retrieved are empty | |
if prices.empty: | |
print(f"Not enough price history for {stock}; skipping backtest...") | |
continue | |
# Running Facebook Prophet with the set parameters | |
pred_df = runningFBP( | |
prices, | |
forecast_period=param[3], | |
training_days=param[1], | |
interval_width=param[4] | |
) | |
# Running backtest | |
backtest, performance = backtestStock( | |
stock, | |
pred_df, | |
prices, | |
price_history, | |
interval_width=param[4] | |
) | |
# Creating param dictionary to record results | |
res = { | |
"n_days": param[0], | |
"training_days": param[1], | |
"mov_avg": param[2], | |
"forecast_period": param[3], | |
"interval_width": param[4], | |
"backtestAnalysis": backtest, | |
"bt_performance": performance | |
} | |
# Appending the results | |
param_lst.append(res) | |
# Checking backtest result | |
if backtest['result']==True and stop_early==True: | |
return { | |
"optimumParamLst": param_lst, | |
"optimumResultFound": True | |
} | |
# Dictionary containing sorted parameter results list; best result is last | |
param_d = { | |
"optimumParamLst": sorted( | |
param_lst, | |
key=lambda x: ( | |
x['backtestAnalysis']['score'], | |
x['backtestAnalysis']['pValue']*-1, | |
x['backtestAnalysis']['endingBalance']['prophet'] | |
) | |
), | |
"optimumResultFound": True | |
} | |
# Returning parameter tuning results | |
if backtest['result']==True: | |
return param_d | |
else: | |
# Poor backtest performances | |
param_d['optimumResultFound'] = False | |
return param_d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment