Overall Statistics
Total Orders
877
Average Win
0.01%
Average Loss
-0.01%
Compounding Annual Return
-39.011%
Drawdown
2.900%
Expectancy
-0.680
Start Equity
100000
End Equity
97376.38
Net Profit
-2.624%
Sharpe Ratio
-6.584
Sortino Ratio
-8.206
Probabilistic Sharpe Ratio
0.956%
Loss Rate
82%
Win Rate
18%
Profit-Loss Ratio
0.82
Alpha
-0.27
Beta
0.275
Annual Standard Deviation
0.053
Annual Variance
0.003
Information Ratio
-0.833
Tracking Error
0.084
Treynor Ratio
-1.26
Total Fees
$877.00
Estimated Strategy Capacity
$15000000.00
Lowest Capacity Asset
AMS R735QTJ8XC9X
Portfolio Turnover
7.75%
Drawdown Recovery
0
# region imports
from AlgorithmImports import *
# endregion


class PredictionUniverseAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2026, 2, 20)
        self.set_cash(100_000)
        self.settings.seed_initial_prices = True
        # Define some parameters.
        self._return_prediction_threshold = 0
        # Add the universe of custom data.
        PredictionUniverse.ALGORHTM = self
        self._universe = self.add_universe(PredictionUniverse, self._select_assets)
        # Add a Scheduled Event to rebalance the portfolio every day.
        self.schedule.on(self.date_rules.every_day('SPY'), self.time_rules.at(8, 0), self._rebalance)

    def _select_assets(self, data):
        self.plot('CustomData', 'len', len(data))

        # Select the assets with a return prediction above some threshold.
        symbols = []
        for d in data:
            for symbol, return_prediction in d.prediction_by_symbol.items():
                if return_prediction > self._return_prediction_threshold:
                    symbols.append(symbol)
        return symbols
    
    def _rebalance(self):
        # Form an equal-weighted portfolio with the assets in the universe.
        symbols = self._universe.selected
        if not symbols:
            return
        targets = [PortfolioTarget(symbol, 1/len(symbols)) for symbol in symbols]
        self.set_holdings(targets, True)


# Define a custom universe class that reads from the JSON file
# we created in the research notebook.
class PredictionUniverse(PythonData):

    def get_source(self, config, date, is_live_mode):
        return SubscriptionDataSource(
            'research-to-backtest-factors.json', 
            SubscriptionTransportMedium.OBJECT_STORE, 
            FileFormat.UNFOLDING_COLLECTION
        )

    def reader(self, config, line, date, is_live):
        objects = [self._convert(obj) for obj in json.loads(line)]
        return BaseDataCollection(objects[-1].end_time, config.symbol, objects)
    
    def _convert(self, obj):
        stocks = PredictionUniverse()
        stocks.time = datetime.strptime(obj["date"], "%Y-%m-%d")
        stocks.prediction_by_symbol = {
            PredictionUniverse.ALGORHTM.symbol(k): v 
            for k, v in obj['prediction_by_symbol'].items()
        }
        return stocks