Overall Statistics
Total Trades
57
Average Win
0.44%
Average Loss
-0.39%
Compounding Annual Return
4.389%
Drawdown
10.300%
Expectancy
0.701
Net Profit
41.039%
Sharpe Ratio
0.678
Loss Rate
20%
Win Rate
80%
Profit-Loss Ratio
1.13
Alpha
0.032
Beta
0.624
Annual Standard Deviation
0.065
Annual Variance
0.004
Information Ratio
0.378
Tracking Error
0.065
Treynor Ratio
0.07
Total Fees
$57.00
import numpy as np

### <summary>
# All Weather Portfolio
# ---------------------------------------------
# Strategy Author: Ray Dalio 
# Source: Tony Robbins / Money, master the game
# ----------------------------------------------
### </summary>
class BasicTemplateAlgorithm(QCAlgorithm):
    '''Basic template algorithm simply initializes the date range and cash'''

    def Initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.SetStartDate(2011,1,1)  #Set Start Date
        self.SetEndDate(2019,1,1)    #Set End Date
        self.SetCash(10000)           #Set Strategy Cash
        
        # Dividend Handling
        self.raw_handling = True
        
        # Simulate topping up your account with savings every period 
        self.savings_on = False
        self.savings_amt = 1000
        
        # This is to stop us adding savings on the first rebalance as it is 
        # immediately after starting the algo
        self.first_rebalance = True
        
        
        # This dictionary will be looped through to add equities and setholdings 
        # It can be expanded to hold more ETF's/Equities.
        self.all_weather = {
            "Equity 1":{
                    "Ticker": "VOO", # Vanguard S&P 500 ETF
                    "Weight": 0.15,
                    },
            "Equity 2":{
                    "Ticker": "VEA", # Vanguard FTSE Developed Markets ETF
                    "Weight": 0.15,
                    },        
            
            "Bonds Med-Term":{
                    "Ticker": "IEF", # iShares 7-10 Year Treasury Bond ETF
                    "Weight": 0.15,
                    },
                    
            "Bonds Long-Term":{
                    "Ticker": "TLT", # iShares 20+ Year Treasury Bond ETF
                    "Weight": 0.4,
                    },
            "Commodity 1":{
                    "Ticker": "GLD", # SPDR Gold Trust
                    "Weight": 0.075,
                    },
            "Commodity 2":{
                    "Ticker": "USO", # United States Oil Fund
                    "Weight": 0.075,
                    },
                    
            }
            
        
        # Setup IB Broker simulation
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
            
        
        # Add The ETF'S!
        # ---------------
        for key, asset in self.all_weather.items():
            self.AddEquity(asset["Ticker"], Resolution.Daily)
            
            # Set Dividend Handling Method
            # ----------------------------
            # https://www.quantconnect.com/forum/discussion/508/update-dividends-splits-and-custom-price-normalization/p1
            if self.raw_handling:
                self.Securities[asset["Ticker"]].SetDataNormalizationMode(DataNormalizationMode.Raw)
            else:
                self.Securities[asset["Ticker"]].SetDataNormalizationMode(DataNormalizationMode.TotalReturn)
        
        
        # We will assume that if we can place an order for the Equity, then the other
        # ETF's should be fine. 
        self.Schedule.On(self.DateRules.MonthStart(self.all_weather["Equity 1"]["Ticker"]),
                            self.TimeRules.AfterMarketOpen(self.all_weather["Equity 1"]["Ticker"]),
                            self.Rebalance)
                            

    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.

        Arguments:
            data: Slice object keyed by symbol containing the stock data
        '''
        # Log any dividends received.
        # ---------------------------
        for kvp in data.Dividends: # update this to Dividends dictionary
            div_ticker = kvp.Key
            div_distribution = kvp.Value.Distribution
            div_total_value = div_distribution * self.Portfolio[div_ticker].Quantity
            self.Log("DIVIDEND >> {0} - ${1} - ${2}".format(div_ticker, div_distribution, div_total_value))
            
            
    def Rebalance(self):
        month = self.Time.month
        
        # Return if we don't want to rebalance this month
        # Add extra months in here to rebalance more often
        # i.e for March insert 3 into the list. 
        if month not in [1,6]: return
    
        self.Log('-------------------->>')
        self.Log("{0} RE-BALANCE >> Total Value {1} | Cash {2}".format(
                                                                    self.Time.strftime('%B').upper(),
                                                                    self.Portfolio.TotalPortfolioValue,
                                                                    self.Portfolio.Cash))
    
    
        if self.savings_on and not self.first_rebalance:
            
            cash_after_savings = self.Portfolio.Cash + self.savings_amt
            self.Log("Top Up Savings >> New Cash Balance {0}".format(
                                                                cash_after_savings))
            self.Portfolio.SetCash(cash_after_savings)
    
        # Rebalance!                                                                
        for key, asset in self.all_weather.items():
            
            holdings = self.Portfolio[asset["Ticker"]].Quantity
            price = self.Portfolio[asset["Ticker"]].Price
            
            self.Log("{0} >> Current Holdings {1} | Current Price {2}".format(
                                                                    self.Portfolio[asset["Ticker"]].Symbol,
                                                                    holdings,
                                                                    price))

            self.SetHoldings(asset["Ticker"], asset["Weight"])
            
        self.Log('-------------------->>')
        
        # Set first rebalance to False so we add the savings next time around
        # (if turned on)
        self.first_rebalance = False