Overall Statistics
Total Trades
143
Average Win
2.81%
Average Loss
-1.04%
Compounding Annual Return
441.335%
Drawdown
70.700%
Expectancy
1.005
Net Profit
104.670%
Sharpe Ratio
9.733
Probabilistic Sharpe Ratio
68.316%
Loss Rate
46%
Win Rate
54%
Profit-Loss Ratio
2.71
Alpha
19.286
Beta
3.493
Annual Standard Deviation
2.065
Annual Variance
4.263
Information Ratio
9.719
Tracking Error
2.044
Treynor Ratio
5.753
Total Fees
$0.00
Estimated Strategy Capacity
$27000000.00
Lowest Capacity Asset
BTCUSDT 18N
Portfolio Turnover
45.25%
from AlgorithmImports import *
import talib
import numpy as np

class RetrospectiveYellowGreenAlligator(QCAlgorithm):

    def Initialize(self):
        # INITIALIZE
        self.SetStartDate(2023, 1, 18)
        self.SetEndDate(2023, 6, 19)
        self._cash = 100000
        self.SetCash(self._cash)

        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(CryptoCoarseFundamentalUniverse(Market.Binance, self.UniverseSettings, self.universe_filter))

        # SET BENCHMARK AND PREPARE COMPARATIVE PLOT
        self.reference_ticker = {}
        self._initialValue_ticker = {}

        # SET TECHNICAL INDICATORS
        self.Bolband = {}
        self.sto = {}

        # Risk management
        self.AddRiskManagement(TrailingStopRiskManagementModel(0.03))
        self.Debug("Stop loss hit")

    def universe_filter(self, crypto_coarse: List[CryptoCoarseFundamental]) -> List[Symbol]:
        return [cf.Symbol for cf in crypto_coarse if cf.VolumeInUsd is not None and cf.VolumeInUsd > 60000000]


    def OnData(self, data):
        for symbol in data.Keys:
            if symbol not in self.reference_ticker:
                self.reference_ticker[symbol] = self.History(symbol, 10, Resolution.Daily)['close']
                self._initialValue_ticker[symbol] = self.reference_ticker[symbol].iloc[0]
                self.Bolband[symbol] = self.BB(symbol, 10, 0.45, MovingAverageType.Simple, Resolution.Daily)
                self.sto[symbol] = self.STO(symbol, 8, 5, 5, Resolution.Daily)

            price = data[symbol].Close
            sto_value = self.sto[symbol].Current.Value

            if price > self.Bolband[symbol].UpperBand.Current.Value and sto_value > 80:
                self.SetHoldings(symbol, -1)
                self.Debug(f"Short position triggered for {symbol}")
            elif price > self.Bolband[symbol].MiddleBand.Current.Value and price < self.Bolband[symbol].UpperBand.Current.Value:
                self.SetHoldings(symbol, 0.5)
                self.Debug(f"Mid long triggered for {symbol}")
            elif price < self.Bolband[symbol].MiddleBand.Current.Value and price > self.Bolband[symbol].LowerBand.Current.Value and sto_value < 20:
                self.SetHoldings(symbol, 1)
                self.Debug(f"Long position triggered for {symbol}")
            elif self.Portfolio[symbol].UnrealizedProfitPercent > 0.1:
                self.Liquidate(symbol)
                self.Debug(f"Take profit triggered for {symbol}")
            else:
                self.SetHoldings(symbol, 1)

            self.Plot("Strategy Equity", str(symbol), self._cash * self.Securities[symbol].Close / self._initialValue_ticker[symbol])
            self.Plot("Strategy Equity", 'Portfolio Value', self.Portfolio.TotalPortfolioValue)
            self.Plot("Bollinger", 'BB Lower', self.Bolband[symbol].LowerBand.Current.Value)
            self.Plot("Bollinger", 'BB Upper', self.Bolband[symbol].UpperBand.Current.Value)
            self.Plot("Bollinger", 'BB Middle', self.Bolband[symbol].MiddleBand.Current.Value)
            self.Plot("Bollinger", str(symbol), price)
            self.Plot("Stochastic", "faststoch", self.sto[symbol].FastStoch.Current.Value)
            self.Plot("Stochastic", "stochk", self.sto[symbol].StochK.Current.Value)
            self.Plot("Stochastic", "stochd", self.sto[symbol].StochD.Current.Value)