Overall Statistics
Total Trades
112
Average Win
2.48%
Average Loss
-2.03%
Compounding Annual Return
9.725%
Drawdown
32.700%
Expectancy
0.095
Net Profit
7.292%
Sharpe Ratio
0.426
Probabilistic Sharpe Ratio
25.391%
Loss Rate
51%
Win Rate
49%
Profit-Loss Ratio
1.22
Alpha
0.274
Beta
0.077
Annual Standard Deviation
0.559
Annual Variance
0.313
Information Ratio
0.926
Tracking Error
0.768
Treynor Ratio
3.101
Total Fees
BUSD3395.73
Estimated Strategy Capacity
BUSD48000000000.00
Lowest Capacity Asset
FTMBUSD 18N
# region imports
from AlgorithmImports import *

# endregion

class FocusedBrownJaguar(QCAlgorithm):

    def Initialize(self):
        # *** initial configurations and backtest ***
        self.SetStartDate(2022, 1, 1)  # Set Start Date
        self.SetEndDate(2022, 10, 2)  # Set Start Date
        self.SetSecurityInitializer(self.CustomSecurityInitializer)
        self.SetAccountCurrency("BUSD") # Set Account Currency
        self.SetCash("BUSD", 100000, 1)  # Set Strategy Cash

        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(CryptoCoarseFundamentalUniverse(Market.Binance, self.UniverseSettings, self.universe_filter))
        # self.Settings.RebalancePortfolioOnInsightChanges = False
        self.Settings.RebalancePortfolioOnSecurityChanges = False
        
        # *** Universe Selection parameters ***
        self.minimumVolume = 10000000 # minimumVolume for coin selection
        self.minimumCoinPriceInUSD = 1
        self.maximumCoinPriceInUSD = 25
        # Maximum number of coins to be selected in coarse universe selection
        self.maxNumCoarse = 50

        self.portfolioTargets = []
        self.SetBenchmark(Symbol.Create("BTCUSDC", SecurityType.Crypto, Market.Binance))

        # *** Framework initialization ***
        self.AddAlpha(EmaCrossAlphaModel())
        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time: None))             
        self.AddRiskManagement(NullRiskManagementModel())
        self.SetExecution(ImmediateExecutionModel())
        
        # *** Brokerage settings
        self.SetBrokerageModel(BrokerageName.Binance, AccountType.Margin)
        self.order_properties = BinanceOrderProperties()
        
        # *** Aux properties ***
        self.month = 0
        self.filterCount = 0

    def OnData(self, data):
        pass
        
    def IsRebalanceDue(self, time):
        pass
    
    def OnSecuritiesChanged(self, changes: SecurityChanges) -> None:
        pass
    
    def CustomSecurityInitializer(self, security):
        security.SetFeeModel(BinanceFeeModel())
        security.SetFillModel(ImmediateFillModel())
        security.SetBuyingPowerModel(SecurityMarginModel(1))
       
    def universe_filter(self, crypto_coarse: List[CryptoCoarseFundamental]) -> List[Symbol]:
        # trying to filter universe only once
        if self.filterCount == 0:
            # randomly selecting small crypto Coins on USD
            coarseCoins = [ccf for ccf in crypto_coarse if ccf.Symbol.Value[-3:] == "USD" and ccf.Symbol.Value[:2] != "US" and ccf.Volume >= self.minimumVolume and ccf.Price >= self.minimumCoinPriceInUSD and ccf.Price <= self.maximumCoinPriceInUSD]
            selected = sorted([x for x in coarseCoins], key = lambda x: x.Volume, reverse = True)
            numSelected = min(len(selected),self.maxNumCoarse)
            self.filterCount = 1
            return [x.Symbol for x in selected[:numSelected]]
        else:
            return Universe.Unchanged