from data_loader.types import ForwardReturnSeries, XDataFrame, ySeries from utils.evaluate import discretize_threeway_threshold, evaluate_predictions from utils.helpers import equal_except_nan from .train_model import train_model import pandas as pd from models.base import Model from models.model_map import default_feature_selector_classification from typing import Optional from config.types import Config from .types import BetSizingWithMetaOutcome, ModelOverTime, TransformationsOverTime from training.walk_forward import walk_forward_process_transformations from transformations.scaler import get_scaler from transformations.rfe import RFETransformation from transformations.pca import PCATransformation def bet_sizing_with_meta_model( X: XDataFrame, input_predictions: pd.Series, y: ySeries, forward_returns: ForwardReturnSeries, model: Model, config: Config, model_suffix: str, from_index: Optional[pd.Timestamp], transformations_over_time: Optional[TransformationsOverTime] = None, preloaded_models: Optional[ModelOverTime] = None ) -> BetSizingWithMetaOutcome: input_predictions.name = "model_predictions" discretized_predictions = input_predictions.apply(discretize_threeway_threshold(0.33)) discretized_predictions.name = "model_discretized_predictions" meta_y: pd.Series = pd.concat([discretized_predictions, y], axis=1).apply(equal_except_nan, axis = 1) meta_X = pd.concat([X, input_predictions, discretized_predictions], axis = 1) if transformations_over_time is None: print("Preprocess transformations") transformations_over_time = walk_forward_process_transformations( X = meta_X, y = meta_y, forward_returns = forward_returns, expanding_window = config.expanding_window_meta, window_size = config.sliding_window_size_meta, retrain_every = config.retrain_every, from_index = from_index, transformations= [ get_scaler(config.scaler), PCATransformation(ratio_components_to_keep=0.5, sliding_window_size=config.sliding_window_size_meta), RFETransformation(n_feature_to_select=40, model=default_feature_selector_classification) ], ) meta_outcome = train_model( ticker_to_predict = "prediction_correct", X = meta_X, y = meta_y, forward_returns = forward_returns, model = model, expanding_window = config.expanding_window_meta, sliding_window_size = config.sliding_window_size_meta, retrain_every = config.retrain_every, from_index = from_index, no_of_classes = 'two', level = 'meta', output_stats = config.mode == 'training', transformations_over_time = transformations_over_time, model_over_time = preloaded_models, ) meta_predictions = meta_outcome.predictions bet_size = meta_outcome.probabilities.iloc[:,1] avg_predictions_with_sizing = input_predictions * meta_predictions * bet_size if config.mode == 'training': stats = evaluate_predictions( forward_returns = forward_returns, y_pred = avg_predictions_with_sizing, y_true = y, no_of_classes = 'three-balanced', discretize=False ) print(stats) else: stats = None model_id = "model_" + config.target_asset[1] + "_" + model_suffix return BetSizingWithMetaOutcome(model_id, meta_outcome, transformations_over_time, avg_predictions_with_sizing, stats)