Overall Statistics
Total Trades
Average Win
Average Loss
Compounding Annual Return
Net Profit
Sharpe Ratio
Loss Rate
Win Rate
Profit-Loss Ratio
Annual Standard Deviation
Annual Variance
Information Ratio
Tracking Error
Treynor Ratio
Total Fees
from datetime import timedelta, datetime
from QuantConnect.Algorithm.Framework.Alphas import AlphaModel, Insight, InsightType, InsightDirection
import numpy as np
from collections import deque
import calendar

class BetaAlphaModel(AlphaModel):

    def __init__(self):
        self.period = timedelta(hours=6)
        self.Name = 'BetaAlphaModel'
        self.assets = {}
        self.month = datetime.min
    def Update(self, algorithm, data):
        if data.ContainsKey("SPY"):
        for key, value in self.assets.items():
            if data.ContainsKey(key):

        insights = []

        if self.month != algorithm.Time.month:    
            self.month = algorithm.Time.month 
            beta_values = {} 
            market_return = np.diff(np.array(self.market_price))/np.array(self.market_price)[:-1]
            long = None
            for key, value in self.assets.items():
                if key != "SPY" and len(value.Price) == value.Price.maxlen:
                    asset_return = np.diff(np.array(value.Price))/np.array(value.Price)[:-1]
                    beta_values[key] = self.beta(asset_return, market_return)
            sorted_by_beta = sorted(beta_values, key = lambda x: beta_values[x])
            long = sorted_by_beta[:int(0.25*len(sorted_by_beta))]
            short = sorted_by_beta[-int(0.25*len(sorted_by_beta)):]
            # day: the weekday of first day of the month 
            # num_days: number of days in month  
            day, num_days = calendar.monthrange(algorithm.Time.year, algorithm.Time.month)
            insight_period = num_days - algorithm.Time.day - 1
            if long and short:
                invested = [x.Key for x in algorithm.Portfolio if x.Value.Invested]
                for i in invested:
                    if algorithm.Portfolio[i].IsLong and i not in long:  
                        insights.append(Insight.Price(i, timedelta(days=1), InsightDirection.Flat))
                    if algorithm.Portfolio[i].IsShort and i not in short:  
                        insights.append(Insight.Price(i, timedelta(days=1), InsightDirection.Flat))
                for i in long:
                    insights.append(Insight.Price(i, timedelta(days=insight_period), InsightDirection.Up))
                for i in short:
                    insights.append(Insight.Price(i, timedelta(days=insight_period), InsightDirection.Down))
        return insights

    def OnSecuritiesChanged(self, algorithm, changes):
        for added in changes.AddedSecurities:
            if added.Symbol.Value == "SPY":
                self.market_price = deque(maxlen=253)
                hist_SPY = algorithm.History(["SPY"], 500, Resolution.Daily)
                for i in hist_SPY.loc["SPY"].itertuples():

            if added not in self.assets and added.Symbol.Value != "SPY":
                hist = algorithm.History([added.Symbol.Value], 500, Resolution.Daily)
                if not hist.empty:
                    self.assets[added.Symbol] = SymbolData(added)
                    for i in hist.loc[added.Symbol.Value].itertuples():

        for removed in changes.RemovedSecurities:

    def beta(self, asset_return, market_return):
        asset_return = np.array(asset_return, dtype=np.float32)
        market_return = np.array(market_return, dtype=np.float32)
        return np.cov(asset_return, market_return)[0][1]/np.var(market_return)
class SymbolData:
    def __init__(self, symbol):
        self.Symbol = symbol
        self.Price = deque(maxlen=253)
from datetime import datetime

class MonthlyPortfolioConstructionModel(PortfolioConstructionModel):

    def __init__(self):
        self.month = datetime.min

    def CreateTargets(self, algorithm, insights):
        if self.month == algorithm.Time.month:
            return []
        targets = []
        self.month = algorithm.Time.month
        if len(insights) != 0:
            percent = 1 / len(insights)
            for insight in insights:
                target = PortfolioTarget.Percent(algorithm, insight.Symbol, insight.Direction * percent)
                if not target is None:
        return targets
from Alphas.ConstantAlphaModel import ConstantAlphaModel
from AlphaModel import BetaAlphaModel
from Risk.NullRiskManagementModel import NullRiskManagementModel
from datetime import datetime
from PortfolioConstructionModel import MonthlyPortfolioConstructionModel

class BetaAlgorithm(QCAlgorithmFramework):

    def Initialize(self):

        self.SetStartDate(2012, 1, 1)   #Set Start Date
        self.SetEndDate(2018, 3, 1)    #Set End Date
        self.SetCash(100000)            #Set Strategy Cash

        self.UniverseSettings.Resolution = Resolution.Daily
        tickers =  [
                    "EWJ",  # iShares MSCI Japan Index ETF
                    "EZU",  # iShares MSCI Eurozone ETF
                    "EFNL", # iShares MSCI Finland Capped Investable Market Index ETF
                    "EWW",  # iShares MSCI Mexico Inv. Mt. Idx
                    "ERUS", # iShares MSCI Russia ETF
                    "IVV",  # iShares S&P 500 Index
                    "ICOL", # Consumer Discretionary Select Sector SPDR Fund
                    "AAXJ", # iShares MSCI All Country Asia ex Japan Index ETF
                    "AUD",  # Australia Bond Index Fund
                    "EWQ",  # iShares MSCI France Index ETF
                    "BUND", # Pimco Germany Bond Index Fund
                    "EWH",  # iShares MSCI Hong Kong Index ETF
                    "EPI",  # WisdomTree India Earnings ETF
                    "EIDO"  # iShares MSCI Indonesia Investable Market Index ETF
                    "EWI",  # iShares MSCI Italy Index ETF
                    "GAF",  # SPDR S&P Emerging Middle East & Africa ETF
                    "ENZL", # iShares MSCI New Zealand Investable Market Index Fund
                    "NORW"  # Global X FTSE Norway 30 ETF
                    "EWY",  # iShares MSCI South Korea Index ETF
                    "EWP",  # iShares MSCI Spain Index ETF
                    "EWD",  # iShares MSCI Sweden Index ETF
                    "EWL",  # iShares MSCI Switzerland Index ETF
                    "GXC",  # SPDR S&P China ETF
                    "EWC",  # iShares MSCI Canada Index ETF
                    "EWZ",  # iShares MSCI Brazil Index ETF
                    "ARGT", # Global X FTSE Argentina 20 ETF
                    "AND",  # Global X FTSE Andean 40 ETF
                    "AIA",  # iShares S&P Asia 50 Index ETF
                    "EWO",  # iShares MSCI Austria Investable Mkt Index ETF
                    "EWK",  # iShares MSCI Belgium Investable Market Index ETF
                    "BRAQ", # Global X Brazil Consumer ETF
                    "ECH",  # iShares MSCI Chile Investable Market Index ETF
                    "CHIB", # Global X China Technology ETF
                    "EGPT", # Market Vectors Egypt Index ETF
                    "ADRU"] # BLDRS Europe 100 ADR Index ETF
        symbols = [Symbol.Create(ticker, SecurityType.Equity, Market.USA) for ticker in tickers]
        self.AddEquity("SPY", Resolution.Daily)