Overall Statistics
Total Orders
58
Average Win
5.30%
Average Loss
-2.86%
Compounding Annual Return
6.257%
Drawdown
18.800%
Expectancy
0.771
Start Equity
100000
End Equity
180540.51
Net Profit
80.541%
Sharpe Ratio
0.27
Sortino Ratio
0.221
Probabilistic Sharpe Ratio
4.266%
Loss Rate
38%
Win Rate
62%
Profit-Loss Ratio
1.85
Alpha
-0.001
Beta
0.326
Annual Standard Deviation
0.085
Annual Variance
0.007
Information Ratio
-0.421
Tracking Error
0.122
Treynor Ratio
0.071
Total Fees
$130.94
Estimated Strategy Capacity
$1700000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
1.63%
# region imports
from AlgorithmImports import *

from statsmodels.tsa.regime_switching.markov_regression import MarkovRegression
# endregion


class FearAndGreedExampleAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2015, 7, 12)
        self.set_end_date(2025, 4, 1)
        self.set_cash(100_000)
        self._index = self.add_data(FearGreedIndex, 'FG')
        self._index.history = self.history(self._index.symbol, datetime(2014, 7, 1), self.time).loc[self._index.symbol].qcindex
        self._equity = self.add_equity('SPY', Resolution.DAILY)
    
    def on_data(self, data: Slice) -> None:
        # Wait until the Fear and Greed dataset has new data.
        if self._index.symbol not in data:
            return
        self._index.history.loc[self.time] = self._index.close
        # Fit the HMM
        model = MarkovRegression(self._index.history, k_regimes=2).fit()
        # Detect the current regime.
        regimes = pd.Series(model.smoothed_marginal_probabilities.values.argmax(axis=1), index=self._index.history.index, name='regime')    

        # Ensure that regime 0=fear and 1=greed
        self.plot('Regimes Mean', 'Fear', self._index.history[regimes[regimes == 0].index].mean())
        self.plot('Regimes Mean', 'Greed', self._index.history[regimes[regimes == 1].index].mean())

        current_regime = regimes.iloc[-1]
        self.plot('Regime', 'Current', current_regime)
        
        # Hold during the greedy regime, flat during the fear regime.
        if current_regime == 1 and not self.portfolio.invested:
            self.set_holdings(self._equity.symbol, 1)
        elif current_regime == 0:
            self.liquidate()