Overall Statistics
Total Trades
1
Average Win
0%
Average Loss
0%
Compounding Annual Return
23.741%
Drawdown
13.200%
Expectancy
0
Net Profit
23.597%
Sharpe Ratio
1.017
Probabilistic Sharpe Ratio
47.014%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
-0.105
Beta
1.893
Annual Standard Deviation
0.173
Annual Variance
0.03
Information Ratio
0.192
Tracking Error
0.146
Treynor Ratio
0.093
Total Fees
$136.71
Estimated Strategy Capacity
$15000000.00
Lowest Capacity Asset
MWD R735QTJ8XC9X
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020,1,1)
        self.SetEndDate(2021,1,1)
        self.SetCash(1000000)

        # add securities 
        self.AddEquity("GOOG", Resolution.Daily)
        self.GOOG = self.Symbol("GOOG")
        self.AddEquity("AMZN", Resolution.Daily)
        self.AMZN = self.Symbol("AMZN")

        self.count = 0 

    def OnData(self, data: Slice):

        if self.count == 0:
            self.MarketOrder("GOOG", 6000)
            self.MarketOrder("AMZN",-8000)

        value = self.Portfolio.TotalPortfolioValue
        self.Log('Portfolio Value : ' + str(value))

        self.count += 1 

        if value < 900000:
            order_ids = self.Liquidate()
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020,1,1)
        self.SetEndDate(2021,1,1)
        self.SetCash(1000000)

        # add securities 
        self.AddEquity("GOOG", Resolution.Daily)
        self.AddEquity("AMZN", Resolution.Daily)

    def OnData(self, data: Slice):

        # get starting date prices
        if self.Time.day == 1 and self.Time.month == 1 and self.Time.year == 2020:
            self.AMZN_start = self.Securities["AMZN"].Price
            self.GOOG_start = self.Securities["GOOG"].Price

            self.LimitOrder("AMZN", -8000, 1.05 * self.AMZN_start)
            self.LimitOrder("GOOG", 6000, 0.95 * self.GOOG_start)

        value = self.Portfolio.TotalPortfolioValue
        if value < 900000:
            order_ids = self.Liquidate()

        value = self.Portfolio.TotalPortfolioValue
        if value < 900000:
            order_ids = self.Liquidate()
# region imports
from AlgorithmImports import *
# endregion

class MeasuredTanJackal(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2020,1,1)
        self.SetEndDate(2021,1,1)
        self.SetCash(1000000)

        # add securities 
        self.AddEquity("GOOG", Resolution.Daily)
        self.AddEquity("AMZN", Resolution.Daily)

        self.amzn_orders = -5628
        self.goog_orders = round(self.amzn_orders * 3/4,0)

    def OnData(self, data: Slice):

        self.Debug(f"AMZN : {self.amzn_orders} \n GOOG : {self.goog_orders}")

        if self.Time.day == 1 and self.Time.year == 2020 and self.Time.month == 1:
            self.MarketOrder("AMZN", self.amzn_orders) 
            self.MarketOrder("GOOG", -self.goog_orders)
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    """
    1. (5 pts) Compute the Sharpe Ratio of a buy-and-hold strategy for each of the above stocks 
    individually for the given time period, that is, you need to compute four 
    Sharpe Ratios separately, one for each stock.
    """

    def Initialize(self):
        self.SetStartDate(2019,2,1)
        self.SetEndDate(2021,2,1)
        self.SetCash(1000000)

        #self.AddEquity('GS', Resolution.Daily)
        #self.AddEquity('MS', Resolution.Daily)
        #self.AddEquity('AMD', Resolution.Daily)
        self.AddEquity('XOM', Resolution.Daily)

    def OnData(self, data: Slice):

        #self.SetHoldings('GS', 1)
        #self.SetHoldings('MS', 1)
        #self.SetHoldings('AMD', 1)
        self.SetHoldings('XOM', 1)
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019,2,1)
        self.SetEndDate(2021,2,1)
        self.SetCash(1000000)

        # just commenting and uncommenting the below to find the statistic for 
        # the relevant ticker

        #self.AddEquity('GS', Resolution.Daily)
        self.AddEquity('MS', Resolution.Daily)
        #self.AddEquity('AMD', Resolution.Daily)
        #self.AddEquity('XOM', Resolution.Daily)

        self.count = 0 
    
    def OnData(self, data: Slice):

        if self.count == 0:
            #self.SetHoldings('GS', 1)
            self.SetHoldings('MS', 1)
            #self.SetHoldings('AMD', 1)
            #self.SetHoldings('XOM', 1)
        
        value = self.Portfolio.TotalUnrealizedProfit
        stop_loss = 0.07 * 1000000
        self.count += 1

        # with 1MM starting value, equates to losing or gaining $70,000
        if (value <=  -stop_loss) or (value >= stop_loss):
            order = self.Liquidate()
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019,2,1)
        self.SetEndDate(2021,2,1)
        self.SetCash(1000000)

        # just commenting and uncommenting the below to find the statistic for 
        # the relevant ticker

        self.AddEquity('GS', Resolution.Daily)
        self.AddEquity('MS', Resolution.Daily)
        #self.AddEquity('AMD', Resolution.Daily)
        #self.AddEquity('XOM', Resolution.Daily)

        self.count = 0 

    def OnData(self, data: Slice):

        if self.count == 0: 
            self.SetHoldings('GS', 0.5)
            self.SetHoldings('MS', -0.5)
            #self.SetHoldings('AMD', 1)
            #self.SetHoldings('XOM', 1)
        
        self.count += 1
    
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019,2,1)
        self.SetEndDate(2021,2,1)
        self.SetCash(1000000)

        # just commenting and uncommenting the below to find the statistic for 
        # the relevant ticker

        self.AddEquity('GS', Resolution.Daily)
        self.AddEquity('MS', Resolution.Daily)
        self.AddEquity('AMD', Resolution.Daily)
        self.AddEquity('XOM', Resolution.Daily)

        self.count = 0 

    def OnData(self, data: Slice):

        if self.count == 0:
            self.SetHoldings('GS', 0.25)
            self.SetHoldings('MS', -0.25)
            self.SetHoldings('AMD', 0.25)
            self.SetHoldings('XOM', -.25)

        self.count += 1
        
#region imports
from AlgorithmImports import *
#endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019,8,20)
        self.SetEndDate(2020,7,20)
        self.SetCash(2000000)

        self.ticker ='ROKU'
        self.sym = self.AddEquity(self.ticker, Resolution.Daily) #S1
        self.sma = self.SMA(self.ticker, 20, Resolution.Daily)

        self.port = False

        if self.port:
            self.wt = 0.25 # if we have two stocks, each wt will be 25%
        else:
             self.wt = 0.5 # single stock wt 50%

    def OnData(self, data: Slice):
        
        ind = self.sma.Current.Value

        if not self.Portfolio[self.ticker].Invested:
            if self.sym.Price > ind:
                self.SetHoldings(self.sym.Symbol, self.wt)
            elif self.sym.Price < ind:
                self.SetHoldings(self.sym.Symbol, -self.wt)
        elif (self.Portfolio[self.ticker].IsLong and self.sym.Price< ind) or (self.Portfolio[self.ticker].IsShort and self.sym.Price> ind):
            self.SetHoldings(self.sym.Symbol, 0.0)
    
#region imports
from AlgorithmImports import *
#endregion
class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019,8,20)
        self.SetEndDate(2020,7,20)
        self.SetCash(2000000)

        self.ticker1 ='AMD'
        self.sym1 = self.AddEquity(self.ticker1, Resolution.Daily) #S1
        self.sma = self.SMA(self.ticker1, 20, Resolution.Daily)

        self.port = False

        if self.port:
            self.wt = 0.25 # if we have two stocks, each wt will be 25%
        else:
             self.wt = 0.5 # single stock wt 50%

    def OnData(self, data: Slice):
        
        ind1 = self.sma.Current.Value

        if not self.Portfolio[self.ticker1].Invested:
            if self.sym1.Price > ind1: 
                self.SetHoldings(self.sym1.Symbol, -self.wt)
            elif self.sym1.Price < ind1:
                self.SetHoldings(self.sym1.Symbol, self.wt)
        elif self.Portfolio[self.ticker1].IsLong and self.sym1.Price< ind1 or self.Portfolio[self.ticker1].IsShort and self.sym1.Price> ind1:
            self.SetHoldings(self.sym1.Symbol, 0.0)    

    
# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019,8,20)
        self.SetEndDate(2020,7,20)
        self.SetCash(2000000)

        self.ticker1 ='ROKU'
        self.sym1 = self.AddEquity(self.ticker1, Resolution.Daily) #S1
        self.sma1 = self.SMA(self.ticker1, 20, Resolution.Daily)

        self.ticker2 = 'AMD'
        self.sym2 = self.AddEquity(self.ticker2, Resolution.Daily) #S2
        self.sma2 = self.SMA(self.ticker2, 20, Resolution.Daily)

        self.port = True

        if self.port:
            self.wt = 0.25 # if we have two stocks, each wt will be 25%
        else:
             self.wt = 0.5 # single stock wt 50%

    def OnData(self, data: Slice):
        
        ind1 = self.sma1.Current.Value
        ind2 = self.sma2.Current.Value

        self.Debug("Price1 " + str(self.sym1.Price) + "indicator " +str(ind1))
        self.Debug("Price2 " + str(self.sym2.Price) + "indicator " +str(ind2))

        if not self.Portfolio[self.ticker1].Invested:
            if self.sym1.Price > ind1:
                self.SetHoldings(self.sym1.Symbol, self.wt)
            elif self.sym1.Price < ind1:
                self.SetHoldings(self.sym1.Symbol, -self.wt)
        elif self.Portfolio[self.ticker1].IsLong and self.sym1.Price< ind1 or \
            self.Portfolio[self.ticker1].IsShort and self.sym1.Price> ind1:
            self.SetHoldings(self.sym1.Symbol, 0.0)

        #Trend-reversal Strategy for self.ticker1
        if self.port:
            if not self.Portfolio[self.ticker2].Invested:
                if self.sym2.Price > ind2:
                    self.SetHoldings(self.sym2.Symbol, -self.wt)
                elif self.sym2.Price <ind2:
                    self.SetHoldings(self.sym2.Symbol, self.wt)
            elif self.Portfolio[self.ticker2].IsLong and self.sym2.Price< ind2 or \
                self.Portfolio[self.ticker2].IsShort and self.sym2.Price> ind2:
                self.SetHoldings(self.sym2.Symbol, 0.0)

    
#region imports

from AlgorithmImports import *
#endregion

import numpy as np
import pandas as pd
from datetime import timedelta, datetime
import math 
import statsmodels.api as sm
from statsmodels.tsa.stattools import coint, adfuller

class PairsTradingAlgorithm(QCAlgorithm):
    
    def Initialize(self):

        self.SetCash(100000)
    
        self.enter = 2 # Set the enter threshold
        self.exit = 0  # Set the exit threshold 
        self.lookback = 20  # Set the loockback period 90 days
        
        self.pairs =['MSFT','GOOG']
        self.symbols =[]
        
        for ticker in self.pairs:
            
            self.AddEquity(ticker, Resolution.Hour)
            self.symbols.append(self.Symbol(ticker))

        self.sym1 = self.pairs[0]
        self.sym2 = self.pairs[1]
        
    def stats(self, symbols):
        
        #Use Statsmodels package to compute linear regression and ADF statistics

        self.df = self.History(symbols, self.lookback)
        self.dg = self.df["open"].unstack(level=0)
        
        #self.Debug(self.dg)
        
        ticker1= str(symbols[0])
        ticker2= str(symbols[1])

        Y = self.dg[ticker1].apply(lambda x: math.log(x))
        X = self.dg[ticker2].apply(lambda x: math.log(x))
        
        X = sm.add_constant(X)
        model = sm.OLS(Y,X)
        results = model.fit()
        sigma = math.sqrt(results.mse_resid) # standard deviation of the residual
        slope = results.params[1]
        intercept = results.params[0]
        res = results.resid #regression residual mean of res =0 by definition
        zscore = res/sigma
        adf = adfuller (res)
        
        return [adf, zscore, slope]
     
    def OnData(self, data):

        margin = self.Portfolio.MarginRemaining
        self.Log(f"margin remaining : {margin}")

        # margin risk management
        if margin <= 20000:
            self.Liquidate()

        self.IsInvested = (self.Portfolio[self.sym1].Invested) or (self.Portfolio[self.sym2].Invested)
        self.ShortSpread = self.Portfolio[self.sym1].IsShort
        self.LongSpread = self.Portfolio[self.sym1].IsLong
        
        try:
            stats = self.stats([self.sym1, self.sym2])
        except:
            stats = (1,(1,1),1) # placeholder for exception in calc

        self.beta = stats[2]
        zscore= stats[1][-1]
        
        self.wt1 = 1/(1+self.beta)
        self.wt2 = self.beta/(1+self.beta)
        
        self.pos1 = self.Portfolio[self.sym1].Quantity
        self.px1 = self.Portfolio[self.sym1].Price
        self.pos2 = self.Portfolio[self.sym2].Quantity
        self.px2 = self.Portfolio[self.sym2].Price
        
        self.equity =self.Portfolio.TotalPortfolioValue
        
        if self.IsInvested:
            if self.ShortSpread and zscore <= self.exit or \
                self.LongSpread and zscore >= self.exit or \
                zscore >= 3:
                self.Liquidate()
        else:
            if zscore > self.enter:
                self.SetHoldings(self.sym1, -self.wt1)
                self.SetHoldings(self.sym2, self.wt2)   
            if zscore < - self.enter:
                self.SetHoldings(self.sym1, self.wt1)
                self.SetHoldings(self.sym2, -self.wt2) 

        self.pos1 = self.Portfolio[self.sym1].Quantity
        self.pos2 = self.Portfolio[self.sym2].Quantity

# region imports
from AlgorithmImports import *
# endregion

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018,1,1)
        self.SetEndDate(2018,1,5)
        self.SetCash(1000000)

        self.AddUniverse(self.Coarse, self.Fine)
        self.UniverseSettings.Resolution = Resolution.Daily
        self.SetSecurityInitializer(lambda x: x.SetDataNormalizationMode(DataNormalizationMode.Raw))

    def Coarse(self, coarse):
        
        sortedByDollarVolume = sorted(coarse, key=lambda c: c.DollarVolume, reverse=True)
        filteredByPrice = [c.Symbol for c in sortedByDollarVolume if c.Price>10]
        self.filter_coarse = filteredByPrice[:100]

        return self.filter_coarse
        
    def Fine(self, fine):
        
        fine1 = [x for x in fine if x.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices]
        sortedByMarketCap = sorted(fine1, key=lambda c: c.MarketCap, reverse=True)
        self.filter_fine = [i.Symbol for i in sortedByMarketCap][0:3]

        return self.filter_fine

    def OnData(self, data: Slice):

        self.Log(f"OnData({self.UtcTime}): Keys: {', '.join([key.Value for key in data.Keys])}")
import statsmodels.api as sm
from statsmodels.tsa.stattools import coint, adfuller
# region imports
from AlgorithmImports import *
# endregion


class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):

        self.lookback = 60

        self.SetStartDate(2018,1,1)
        self.SetEndDate(2019,1,1)

        self.SetCash(1000000)

        self.enter = 2 # Set the enter threshold 
        self.exit = 0  # Set the exit threshold 
        self.lookback = 90  # Set the loockback period 90 days

        # BAC, BRK.B, JPM
        self.pairs =['JPM','BAC']

        self.ticker1 = self.pairs[0]
        self.ticker2 = self.pairs[1]

        self.AddEquity(self.ticker1, Resolution.Daily)
        self.AddEquity(self.ticker2, Resolution.Daily)

        self.symbols = [self.Symbol(self.ticker1), self.Symbol(self.ticker2)]

    # borrowing code presented in class, lecture 8 p. 162
    def stats(self, symbols):
        #symbols is a pair of QC Symbol Object
        self.df = self.History(symbols, self.lookback)
        self.dg = self.df["open"].unstack(level=0)

        Y = self.dg[self.ticker1].apply(lambda x: math.log(x))
        X = self.dg[self.ticker2].apply(lambda x: math.log(x))
        X = sm.add_constant(X)
        
        model = sm.OLS(Y,X)
        results = model.fit()
        sigma = math.sqrt(results.mse_resid) #standard deviation of the residual
        slope = results.params[1]
        intercept = results.params[0]
        res = results.resid #regression residual has mean =0 by definition
        zscore = res/sigma
        adf = adfuller(res)

        return [adf, zscore, slope]

    def OnData(self, data: Slice):

        # get the adf and the actual adf score per the docs
        adf = self.stats(self.symbols)[0]
    
        self.Log(f"ADF for {self.ticker1} and {self.ticker2} : {adf[0]}; p-value : {adf[1]}")
#region imports

from AlgorithmImports import *
#endregion

import numpy as np
import pandas as pd
from datetime import timedelta, datetime
import math 
import statsmodels.api as sm
from statsmodels.tsa.stattools import coint, adfuller

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):

        self.SetStartDate(2018,1,1)
        self.SetEndDate(2019,1,1)

        self.SetCash(1000000)

        self.enter = 2
        self.exit = 0 
        self.lookback = 20 

        # BAC, BRK.B, JPM
        self.pairs =['JPM','BAC']

        self.ticker1 = self.pairs[0]
        self.ticker2 = self.pairs[1]

        self.AddEquity(self.ticker1, Resolution.Daily)
        self.AddEquity(self.ticker2, Resolution.Daily)

        self.symbols = [self.Symbol(self.ticker1), self.Symbol(self.ticker2)]
        self.sym1 = self.symbols[0]
        self.sym2 = self.symbols[1]

    # borrowing code presented in class, lecture 8 p. 162
    def stats(self, symbols):
        #symbols is a pair of QC Symbol Object
        self.df = self.History(symbols, self.lookback)
        self.dg = self.df["open"].unstack(level=0)

        Y = self.dg[self.ticker1].apply(lambda x: math.log(x))
        X = self.dg[self.ticker2].apply(lambda x: math.log(x))
        X = sm.add_constant(X)
        
        model = sm.OLS(Y,X)
        results = model.fit()
        sigma = math.sqrt(results.mse_resid) #standard deviation of the residual
        slope = results.params[1]
        intercept = results.params[0]
        res = results.resid #regression residual has mean =0 by definition
        zscore = res/sigma
        adf = adfuller(res)

        return [adf, zscore, slope]

    def OnData(self, data):

        self.IsInvested = (self.Portfolio[self.sym1].Invested) or (self.Portfolio[self.sym2].Invested)
        self.ShortSpread = self.Portfolio[self.sym1].IsShort
        self.LongSpread = self.Portfolio[self.sym1].IsLong

        stats = self.stats([self.sym1, self.sym2])
        self.beta = stats[2]
        zscore= stats[1][-1]
        
        self.wt1 = 1/(1+self.beta)
        self.wt2 = self.beta/(1+self.beta)
        
        self.pos1 = self.Portfolio[self.sym1].Quantity
        self.px1 = self.Portfolio[self.sym1].Price
        self.pos2 = self.Portfolio[self.sym2].Quantity
        self.px2 = self.Portfolio[self.sym2].Price
        
        self.equity =self.Portfolio.TotalPortfolioValue
        
        if self.IsInvested:
            if self.ShortSpread and zscore <= self.exit or \
                self.LongSpread and zscore >= self.exit:
                self.Liquidate()
        else:
            if zscore > self.enter:
                self.SetHoldings(self.sym1, -self.wt1)
                self.SetHoldings(self.sym2, self.wt2)   
            if zscore < -self.enter:
                self.SetHoldings(self.sym1, self.wt1)
                self.SetHoldings(self.sym2, -self.wt2) 

        self.pos1 = self.Portfolio[self.sym1].Quantity
        self.pos2 = self.Portfolio[self.sym2].Quantity
#region imports

from AlgorithmImports import *
#endregion

import numpy as np
import pandas as pd
from datetime import timedelta, datetime
import math 
import statsmodels.api as sm
from statsmodels.tsa.stattools import coint, adfuller

class EnergeticYellowGreenGiraffe(QCAlgorithm):

    def Initialize(self):

        self.lookback = 60

        self.SetStartDate(2018,1,1)
        self.SetEndDate(2019,1,1)

        self.SetCash(1000000)

        self.enter = 2
        self.exit = 0 
        self.lookback = 20 

        # BAC, BRK.B, JPM
        self.pairs =['JPM','BAC']

        self.ticker1 = self.pairs[0]
        self.ticker2 = self.pairs[1]

        self.AddEquity(self.ticker1, Resolution.Daily)
        self.AddEquity(self.ticker2, Resolution.Daily)

        self.symbols = [self.Symbol(self.ticker1), self.Symbol(self.ticker2)]
        self.sym1 = self.symbols[0]
        self.sym2 = self.symbols[1]

    # borrowing code presented in class, lecture 8 p. 162
    def stats(self, symbols):
        #symbols is a pair of QC Symbol Object
        self.df = self.History(symbols, self.lookback)
        self.dg = self.df["open"].unstack(level=0)

        Y = self.dg[self.ticker1].apply(lambda x: math.log(x))
        X = self.dg[self.ticker2].apply(lambda x: math.log(x))
        X = sm.add_constant(X)
        
        model = sm.OLS(Y,X)
        results = model.fit()
        sigma = math.sqrt(results.mse_resid) #standard deviation of the residual
        slope = results.params[1]
        intercept = results.params[0]
        res = results.resid #regression residual has mean =0 by definition
        zscore = res/sigma
        adf = adfuller(res)

        return [adf, zscore, slope]

    def OnData(self, data):

        self.IsInvested = (self.Portfolio[self.sym1].Invested) or (self.Portfolio[self.sym2].Invested)
        self.ShortSpread = self.Portfolio[self.sym1].IsShort
        self.LongSpread = self.Portfolio[self.sym2].IsLong

        stats = self.stats([self.sym1, self.sym2])
        self.beta = stats[2]
        zscore= stats[1][-1]
        abs_z = abs(zscore)
        
        self.wt1 = 1/(1+self.beta)
        self.wt2 = self.beta/(1+self.beta)
        
        self.pos1 = self.Portfolio[self.sym1].Quantity
        self.px1 = self.Portfolio[self.sym1].Price
        self.pos2 = self.Portfolio[self.sym2].Quantity
        self.px2 = self.Portfolio[self.sym2].Price
        
        self.equity =self.Portfolio.TotalPortfolioValue
        
        if self.IsInvested:
            if self.ShortSpread and zscore <= self.exit or \
                self.LongSpread and zscore >= self.exit or \
                abs_z > 3:
                self.Liquidate()
        else:
            if zscore > self.enter:
                self.SetHoldings(self.sym1, -self.wt1)
                self.SetHoldings(self.sym2, self.wt2)   
            if zscore < -self.enter:
                self.SetHoldings(self.sym1, self.wt1)
                self.SetHoldings(self.sym2, -self.wt2) 

        self.pos1 = self.Portfolio[self.sym1].Quantity
        self.pos2 = self.Portfolio[self.sym2].Quantity

        self.Debug(f"z-score : {zscore}; abs z-score : {abs_z}")
#region imports
from AlgorithmImports import *
#endregion


# Your New Python File
#region imports

from AlgorithmImports import *
#endregion


"""
(10 pts) Demonstrate Portfolio Diversification Benefits - Start with $1M and perform backtest 
over the same time period in #1. Let SR[TICKER] denote the Sharpe Ratio of a buy-and-hold strategy
of a stock with the ticker symbol TICKER. Let 0.5MS+0.5XOM denote the portfolio for equal weights
in MS and XOM. Also, SPY is the ETF for S&P market index. Test the validity of the Equation (2) 
on slide 194 by computing the Sharpe Ratios of the four buy-hold strategies below and explain 
why your answers make sense.

SR[MS]
SR[XOM]
SR[0.5MS+0.5XOM]
SR[SPY]
"""

class PairsTradingAlgorithm(QCAlgorithm):
    
    def Initialize(self):

        self.SetStartDate(2017,1,1)
        self.SetEndDate(2018,1,1)

        self.SetCash(1000000)
        self.pairs =['MS']
        self.symbols =[]
        
        for ticker in self.pairs:
            
            self.AddEquity(ticker, Resolution.Daily)
            self.symbols.append(self.Symbol(ticker))

        self.sym1 = self.pairs[0]

    def OnData(self, data):
        
        if not self.Portfolio.Invested:
            self.SetHoldings(self.sym1,1)
#region imports

from AlgorithmImports import *
#endregion

import numpy as np
import pandas as pd
from datetime import timedelta, datetime
import math 
import statsmodels.api as sm
from statsmodels.tsa.stattools import coint, adfuller

class PairsTradingAlgorithm(QCAlgorithm):
    
    def Initialize(self):
       
        self.SetStartDate(2021, 6, 1)
        self.SetEndDate(2022,8,1)

        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        
        self.SetCash(100000)
        
        self.pairs =['GOOG','MSFT']
        self.symbols =[]
        
        for ticker in self.pairs:
            
            self.AddEquity(ticker, Resolution.Daily)
            self.symbols.append(self.Symbol(ticker))

        self.sym1 = self.symbols[0]
        self.sym2 = self.symbols[1]
        
    def OnData(self, data):

        margin = self.Portfolio.MarginRemaining
        self.Log(f"margin remaining : {margin}")

        if margin <= .25 * 100000:
            self.Liquidate()

        if not self.Portfolio.Invested:
            self.SetHoldings('GOOG',-2)