Overall Statistics
Total Trades
146
Average Win
3.01%
Average Loss
0%
Compounding Annual Return
36.350%
Drawdown
55.500%
Expectancy
0
Net Profit
1936.624%
Sharpe Ratio
1.12
Probabilistic Sharpe Ratio
44.327%
Loss Rate
0%
Win Rate
100%
Profit-Loss Ratio
0
Alpha
0.398
Beta
-0.268
Annual Standard Deviation
0.321
Annual Variance
0.103
Information Ratio
0.588
Tracking Error
0.369
Treynor Ratio
-1.344
Total Fees
$485.56
Estimated Strategy Capacity
$130000000.00
Lowest Capacity Asset
TQQQ UK280CGTCB51
from AlgorithmImports import *


class MultiAssetManager(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2012, 1, 1)
        self.SetEndDate(2022, 1, 1)
        self.SetCash(100000)
        self.resolution = int(self.GetParameter("Resolution"))
        self.equities = self.GetParameter("Equities").split(",")
        self.forexPairs = self.GetParameter("ForexPairs").split(",")
        self.cryptoPairs = self.GetParameter("CryptoPairs").split(",")
        for equity in self.equities:
            if len(equity) < 3:
                continue
            self.AddEquity(equity, self.resolution)
        for forex in self.forexPairs:
            if len(forex) < 3:
                continue
            self.AddForex(forex, self.resolution)
        for crypto in self.cryptoPairs:
            if len(crypto) < 3:
                continue
            self.AddCrypto(crypto, self.resolution)

        allocationRatioVariable = self.GetParameter(
            "AllocationRatio").split(",")
        self.allocationRatio = {}
        allocationSum = 0
        for allocation in allocationRatioVariable:
            [pair, ratio] = allocation.split(":")
            self.allocationRatio[pair] = float(ratio)
            allocationSum += float(ratio)
        if allocationSum > 1:
            raise Exception('Allocation Sum is more than 1')
        else:
            self.Log("Not allocated%:"+str(1-allocationSum))
        self.preparePlotPrices()

        schedulePair = list(self.allocationRatio.keys())[0]
        self.Schedule.On(self.DateRules.MonthStart(),  
                 self.TimeRules.AfterMarketOpen(schedulePair, 10), 
                 self.rebalanceEveryMonth)

    def OnData(self, data):
        self.plotPrices(data)
        self.plotAssets()

    def rebalanceEveryMonth(self):
      self.rebalanceAllocations()

    def preparePlotPrices(self):
        pricesChart = Chart('Prices')
        for pair in self.allocationRatio.keys():
            pricesChart.AddSeries(
                Series(pair, SeriesType.Line, "$"))
        self.AddChart(pricesChart)

    def plotPrices(self, data):
        for pair in self.allocationRatio.keys():
            if pair not in data:
                continue
            if data[pair]:
              price = data[pair].Value
              self.Plot("Prices", pair, price)
    
    def preparePlotAssets(self):
        assetsChart = Chart('Assets')
        for pair in self.allocationRatio.keys():
            assetsChart.AddSeries(
                Series(pair, SeriesType.Line, "$"))
        self.AddChart(assetsChart)

    def plotAssets(self):
        for pair in self.allocationRatio.keys():
            if pair not in self.Portfolio:
                continue
            self.Plot("Assets", pair, self.Portfolio[pair].Quantity * self.Portfolio[pair].Price)


    def rebalanceAllocations(self):
      portfolioTargers = []
      for pair in self.allocationRatio.keys():
        portfolioTargers.append(PortfolioTarget(pair,self.allocationRatio[pair]))
      self.SetHoldings(portfolioTargers)

    # def rebalanceAllocations(self,data):
    #   portfolioTargers = []
    #   for pair in self.allocationRatio.keys():
    #     portfolioTargers.append(PortfolioTarget(pair,self.allocationRatio[pair]))
        
    #   self.SetHoldings([PortfolioTarget("SPY", 0.8), PortfolioTarget("IBM", 0.2)])
    #   allocations = []
    #   portfolioValue = self.Portfolio.TotalPortfolioValue
    #   for pair in self.allocationRatio.keys():
    #         if not self.Portfolio[pair].Invested:
    #             continue
    #         allocations.append([pair,portfolioValue / (self.Portfolio[pair].Price * self.Portfolio[pair].Quantity)])
      
    #   allocations.sort(key=self.allocationSortKey,reverse=True)
    #   self.SetHoldings()


    # def allocationSortKey(element):
    #       return element[1]