Overall Statistics
Total Trades
8
Average Win
98.67%
Average Loss
-0.17%
Compounding Annual Return
743.582%
Drawdown
14.300%
Expectancy
476.738
Net Profit
743.582%
Sharpe Ratio
8.05
Probabilistic Sharpe Ratio
99.958%
Loss Rate
20%
Win Rate
80%
Profit-Loss Ratio
596.17
Alpha
3.903
Beta
0.51
Annual Standard Deviation
0.483
Annual Variance
0.234
Information Ratio
8.102
Tracking Error
0.483
Treynor Ratio
7.631
Total Fees
$4635.35
Estimated Strategy Capacity
$55000000.00
Lowest Capacity Asset
JNJ R735QTJ8XC9X
# region imports
from AlgorithmImports import *
# endregion

"""
You are given $1 million to invest two stocks AMD and JNJ from 1/1/2018 to 1/1/2019. 
You are given discretions to take long or short positions in these stocks, subject to 
QC margin call. Your objective is to generate highest profit during this period subject 
to the following conditions:

You must use momentum strategies involving BOTH indicators RSI and BB, 
plus SMA indicators as needed. You can only use either trend following
 or/and trend reversing strategy based on these indicators.
You are free to choose parameters for the strategies in terms of 
lookback period, # of standard deviations, RSI upper/lower bands, 
size of positions etc.

During the entire trading period, the absolute value of the market value 
weight for each stock should be at least 25%.
You must ensure the drawdown amount is less than 15%, and the Sharpe Ratio > 1.0 
5. Clear articulation as to why your performance result makes sense intuitively,
 and list one or two significant factors that could make your strategy performance
  worse or better.

• Your raw grade on this assignment will depend on your relative performance 
ranking among all five groups.

• There will be qualitative adjustment on your grade based on clarity of 
thoughts, explanations, potential areas of improvements as well as logic flows 
of your codes.

"""

class FocusedMagentaBeaver(QCAlgorithm):

    def Initialize(self):

        # Requirements: 
        # weight >= 0.25 each 
        # drawdowown < 15%
        # sharpe > 1.0

        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1)
        self.SetCash(1000000)  # Set Strategy Cash
        self.SetWarmup(30)

        self.amd = "AMD"
        self.jnj = "JNJ"
        self.symA = self.AddEquity(self.amd, Resolution.Daily)
        self.symJ = self.AddEquity(self.jnj, Resolution.Daily)

        self.amdrsi = self.RSI(self.amd, 20, Resolution.Daily)
        self.amdbb = self.BB(self.amd, 20, 2, Resolution.Daily)
        self.jnjrsi = self.RSI(self.jnj, 20, Resolution.Daily)
        self.jnjbb = self.BB(self.jnj, 20, 2, Resolution.Daily)

        self.wt = 0.25

        self.bb_trend_reversal = True # False if Trend Following; True if Trend Reversing

        self.rsi_calc = False

    def OnData(self, data: Slice):

        #Indicators for AMD
        rsi_amd = self.amdrsi.Current.Value
        bbup_amd = self.amdbb.UpperBand.Current.Value
        bbdn_amd = self.amdbb.LowerBand.Current.Value
        bbmd_amd = self.amdbb.MiddleBand.Current.Value

        #Indicators for JNJ
        rsi_jnj = self.jnjrsi.Current.Value
        bbup_jnj = self.jnjbb.UpperBand.Current.Value
        bbdn_jnj = self.jnjbb.LowerBand.Current.Value
        bbmd_jnj = self.jnjbb.MiddleBand.Current.Value

        #Follow trend-following strategy for RSI for JNJ
        
        if not self.rsi_calc:

            if rsi_jnj > 63 and not self.Portfolio[self.jnj].IsShort:
            
                self.SetHoldings(self.symJ.Symbol, -1.5*self.wt)

            elif rsi_jnj < 37 and not self.Portfolio[self.jnj].IsLong:

                self.SetHoldings(self.symJ.Symbol, 1.5*self.wt)

            elif self.Portfolio[self.jnj].IsLong and rsi_jnj > 37:
                
                self.SetHoldings(self.symJ.Symbol, self.wt)
                
            elif self.Portfolio[self.jnj].IsShort and rsi_jnj < 63:

                self.SetHoldings(self.symJ.Symbol, -self.wt)    

        # Trend Reversal strategy for AMD?
#        if self.bb_trend_reversal:
#
#            if not self.Portfolio[self.amd].Invested:
#            
#                if self.symA.Price > bbup_amd:
#
#                    self.SetHoldings(self.symA.Symbol, 1.5*self.wt)
#
#                    self.Debug("BB1 Reverse short")
#
#                elif self.symA.Price < bbdn:
#
#                    self.SetHoldings(self.symA.Symbol, -1.5*self.wt)
#
#                    self.Debug("BB1 Reverse Long")
#
#            elif self.Portfolio[self.amd].IsLong and self.symA.Price< bbdn_amd:
#
#                self.SetHoldings(self.symA.Symbol, 1.25*self.wt)
#
#            elif self.Portfolio[self.amd].IsShort and self.symA.Price> bbup_amd:
#
#                self.SetHoldings(self.symA.Symbol, 1.25*self.wt)

        # Trend following strategy for bb for JNJ?

#        if not self.bb_trend_reversal:
#
#            if not self.Portfolio[self.jnj].Invested:
#            
#                if self.symJ.Price > bbup_jnj:
#
#                    self.SetHoldings(self.symJ.Symbol, -1.5*self.wt)
#
#                    self.Debug("BB Trend Short")
#
#                elif self.symJ.Price < bbdn_jnj:
#
#                    self.SetHoldings(self.symJ.Symbol, 1.5*self.wt)
#
#                    self.Debug("BB Trend Long")
#
#            elif self.Portfolio[self.jnj].IsLong and self.symJ.Price< bbdn_jnj:
#                
#                self.SetHoldings(self.symJ.Symbol, self.wt)
#
#            elif self.Portfolio[self.jnj].IsShort and self.symJ.Price> bbup_jnj:
#
#                self.SetHoldings(self.symJ.Symbol, -self.wt)
# 
        # Trend reversal strategy for bb for AMD
        if self.bb_trend_reversal:

            if not self.Portfolio[self.amd].IsLong and self.symA.Price > bbup_amd:

                self.SetHoldings(self.symA.Symbol, 2*self.wt)

            elif not self.Portfolio[self.amd].IsShort and self.symA.Price < bbdn_amd:

                self.SetHoldings(self.symA.Symbol, -2*self.wt)

            elif self.Portfolio[self.amd].IsShort and self.symA.Price > bbdn_amd and self.symA.Price < bbmd_amd:
                
                self.SetHoldings(self.symA.Symbol, self.wt)

            elif self.Portfolio[self.amd].IsLong and self.symA.Price > bbup_amd and self.symA.Price > bbmd_amd:

                self.SetHoldings(self.symA.Symbol, self.wt)      
# region imports
from AlgorithmImports import *
# endregion

"""
You are given $1 million to invest two stocks AMD and JNJ from 1/1/2018 to 1/1/2019. 
You are given discretions to take long or short positions in these stocks, subject to 
QC margin call. Your objective is to generate highest profit during this period subject 
to the following conditions:

You must use momentum strategies involving BOTH indicators RSI and BB, 
plus SMA indicators as needed. You can only use either trend following
 or/and trend reversing strategy based on these indicators.
You are free to choose parameters for the strategies in terms of 
lookback period, # of standard deviations, RSI upper/lower bands, 
size of positions etc.

During the entire trading period, the absolute value of the market value 
weight for each stock should be at least 25%.
You must ensure the drawdown amount is less than 15%, and the Sharpe Ratio > 1.0 
5. Clear articulation as to why your performance result makes sense intuitively,
 and list one or two significant factors that could make your strategy performance
  worse or better.

• Your raw grade on this assignment will depend on your relative performance 
ranking among all five groups.

• There will be qualitative adjustment on your grade based on clarity of 
thoughts, explanations, potential areas of improvements as well as logic flows 
of your codes.

"""

class FocusedMagentaBeaver(QCAlgorithm):

    def Initialize(self):

        # Requirements: 
        # weight >= 0.25 each 
        # drawdowown < 15%
        # sharpe > 1.0

        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1)
        self.SetCash(1000000)  # Set Strategy Cash
        # self.SetWarmup(30)

        self.amd = "AMD"
        self.jnj = "JNJ"
        self.symA = self.AddEquity(self.amd, Resolution.Daily)
        self.symJ = self.AddEquity(self.jnj, Resolution.Daily)
        self.amdsma = self.SMA(self.amd, 30, Resolution.Daily)
        self.amdrsi = self.RSI(self.amd, 20, Resolution.Daily)
        self.amdbb = self.BB(self.amd, 20, 2, Resolution.Daily)
        self.jnjrsi = self.RSI(self.jnj, 20, Resolution.Daily)
        self.jnjbb = self.BB(self.jnj, 20, 2.1, Resolution.Daily)
        self.jnjsma = self.SMA(self.amd, 30, Resolution.Daily)


        self.wt = 0.25

        self.bb_trend_reversal = True # False if Trend Following; True if Trend Reversing


        self.count = 1

    def OnData(self, data: Slice):

        if self.count == 1:

            # Buy Both Stock on First Day
            self.SetHoldings(self.symJ.Symbol, -6*self.wt)
            self.SetHoldings(self.symA.Symbol,self.wt)
            self.count+=1
            self.amd_holding = 1
            self.jnj_holding = 1
        
        else: 
            #Indicators for AMD
            sma_amd = self.amdsma.Current.Value
            rsi_amd = self.amdrsi.Current.Value
            bbup_amd = self.amdbb.UpperBand.Current.Value
            bbdn_amd = self.amdbb.LowerBand.Current.Value
            bbmd_amd = self.amdbb.MiddleBand.Current.Value

            #Indicators for JNJ
            sma_jnj = self.jnjsma.Current.Value
            rsi_jnj = self.jnjrsi.Current.Value
            bbup_jnj = self.jnjbb.UpperBand.Current.Value
            bbdn_jnj = self.jnjbb.LowerBand.Current.Value
            bbmd_jnj = self.jnjbb.MiddleBand.Current.Value

            # Trend-reversal strategy for AMD based on RSI and SMA
            self.Debug( " Time: " + str(self.Time) + "Price: " + str(self.symJ.Price)+" SMA: "+str()+" "+str(bbdn_jnj))

            # If see decresing trend and only hold initial holding, long 150%
            if self.symA.Price - sma_amd < -1.8  and self.amd_holding == 1:
            
                self.SetHoldings(self.symA.Symbol, 5*self.wt)
                self.amd_holding += 5

            # Trend Reversal for AMD based on RSI and SMA
            if rsi_amd>80 and self.symA.Price - sma_amd > 9 and not self.Portfolio[self.amd].IsShort:
            
                self.SetHoldings(self.symA.Symbol, -7*self.wt)
                self.amd_holding = -7

            elif rsi_amd < 30.4 and sma_amd < 27.6 and self.Portfolio[self.amd].IsShort:
                self.SetHoldings(self.symA.Symbol, self.wt)

            
            
            # Follow trend-reversal strategy for JNJ based on BB
            if bbdn_jnj > self.symJ.Price and not self.Portfolio[self.jnj].IsLong:
                self.SetHoldings(self.symJ.Symbol,1.8*self.wt)

            elif bbup_jnj < self.symJ.Price and not self.Portfolio[self.jnj].IsShort:
                self.SetHoldings(self.symJ.Symbol,-1*self.wt)

# region imports
from AlgorithmImports import *
# endregion

class GroupProject1(QCAlgorithm):

    def Initialize(self):

        # Requirements: 
        # weight >= 0.25 each 
        # drawdowown < 15%
        # sharpe > 1.0

        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1)
        self.SetCash(1000000)  # Set Strategy Cash
        self.SetWarmup(30)

        self.amd = "AMD"
        self.jnj = "JNJ"
        self.symA = self.AddEquity(self.amd, Resolution.Daily)
        self.symJ = self.AddEquity(self.jnj, Resolution.Daily)

        self.amdrsi = self.RSI(self.amd, 20, Resolution.Daily)
        self.amdbb = self.BB(self.amd, 20, 2, Resolution.Daily)
        self.jnjrsi = self.RSI(self.jnj, 20, Resolution.Daily)
        self.jnjbb = self.BB(self.jnj, 20, 2, Resolution.Daily)

        self.wt = 0.25

        self.bb_trend_reversal = True # False if Trend Following; True if Trend Reversing

        self.rsi_calc = False

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

        if self.count == 1:
            self.SetHoldings(self.symJ.Symbol, 0.5*self.wt)
            self.SetHoldings(self.symA.Symbol, 0.5*self.wt)

        #Indicators for AMD
        rsi_amd = self.amdrsi.Current.Value
        bbup_amd = self.amdbb.UpperBand.Current.Value
        bbdn_amd = self.amdbb.LowerBand.Current.Value
        bbmd_amd = self.amdbb.MiddleBand.Current.Value

        #Indicators for JNJ
        rsi_jnj = self.jnjrsi.Current.Value
        bbup_jnj = self.jnjbb.UpperBand.Current.Value
        bbdn_jnj = self.jnjbb.LowerBand.Current.Value
        bbmd_jnj = self.jnjbb.MiddleBand.Current.Value

        #Follow trend-following strategy for RSI for JNJ
        
        if not self.rsi_calc:

            if rsi_jnj > 63 and not self.Portfolio[self.jnj].IsShort:
            
                self.SetHoldings(self.symJ.Symbol, -1.5*self.wt)

            elif rsi_jnj < 37 and not self.Portfolio[self.jnj].IsLong:

                self.SetHoldings(self.symJ.Symbol, 1.5*self.wt)

            elif self.Portfolio[self.jnj].IsLong and rsi_jnj > 37:
                
                self.SetHoldings(self.symJ.Symbol, self.wt)
                
            elif self.Portfolio[self.jnj].IsShort and rsi_jnj < 63:

                self.SetHoldings(self.symJ.Symbol, -self.wt)    

        # Trend Reversal strategy for AMD?
#        if self.bb_trend_reversal:
#
#            if not self.Portfolio[self.amd].Invested:
#            
#                if self.symA.Price > bbup_amd:
#
#                    self.SetHoldings(self.symA.Symbol, 1.5*self.wt)
#
#                    self.Debug("BB1 Reverse short")
#
#                elif self.symA.Price < bbdn:
#
#                    self.SetHoldings(self.symA.Symbol, -1.5*self.wt)
#
#                    self.Debug("BB1 Reverse Long")
#
#            elif self.Portfolio[self.amd].IsLong and self.symA.Price< bbdn_amd:
#
#                self.SetHoldings(self.symA.Symbol, 1.25*self.wt)
#
#            elif self.Portfolio[self.amd].IsShort and self.symA.Price> bbup_amd:
#
#                self.SetHoldings(self.symA.Symbol, 1.25*self.wt)

        # Trend following strategy for bb for JNJ?

#        if not self.bb_trend_reversal:
#
#            if not self.Portfolio[self.jnj].Invested:
#            
#                if self.symJ.Price > bbup_jnj:
#
#                    self.SetHoldings(self.symJ.Symbol, -1.5*self.wt)
#
#                    self.Debug("BB Trend Short")
#
#                elif self.symJ.Price < bbdn_jnj:
#
#                    self.SetHoldings(self.symJ.Symbol, 1.5*self.wt)
#
#                    self.Debug("BB Trend Long")
#
#            elif self.Portfolio[self.jnj].IsLong and self.symJ.Price< bbdn_jnj:
#                
#                self.SetHoldings(self.symJ.Symbol, self.wt)
#
#            elif self.Portfolio[self.jnj].IsShort and self.symJ.Price> bbup_jnj:
#
#                self.SetHoldings(self.symJ.Symbol, -self.wt)
# 
        # Trend reversal strategy for bb for AMD
        if self.bb_trend_reversal:

            if not self.Portfolio[self.amd].IsLong and self.symA.Price > bbup_amd:

                self.SetHoldings(self.symA.Symbol, 2*self.wt)

            elif not self.Portfolio[self.amd].IsShort and self.symA.Price < bbdn_amd:

                self.SetHoldings(self.symA.Symbol, -2*self.wt)

            elif self.Portfolio[self.amd].IsShort and self.symA.Price > bbdn_amd and self.symA.Price < bbmd_amd:
                
                self.SetHoldings(self.symA.Symbol, self.wt)

            elif self.Portfolio[self.amd].IsLong and self.symA.Price > bbup_amd and self.symA.Price > bbmd_amd:

                self.SetHoldings(self.symA.Symbol, self.wt)      
# region imports
from AlgorithmImports import *
# endregion

"""
You are given $1 million to invest two stocks AMD and JNJ from 1/1/2018 to 1/1/2019. 
You are given discretions to take long or short positions in these stocks, subject to 
QC margin call. Your objective is to generate highest profit during this period subject 
to the following conditions:

You must use momentum strategies involving BOTH indicators RSI and BB, 
plus SMA indicators as needed. You can only use either trend following
 or/and trend reversing strategy based on these indicators.
You are free to choose parameters for the strategies in terms of 
lookback period, # of standard deviations, RSI upper/lower bands, 
size of positions etc.

During the entire trading period, the absolute value of the market value 
weight for each stock should be at least 25%.
You must ensure the drawdown amount is less than 15%, and the Sharpe Ratio > 1.0 
5. Clear articulation as to why your performance result makes sense intuitively,
 and list one or two significant factors that could make your strategy performance
  worse or better.

• Your raw grade on this assignment will depend on your relative performance 
ranking among all five groups.

• There will be qualitative adjustment on your grade based on clarity of 
thoughts, explanations, potential areas of improvements as well as logic flows 
of your codes.

"""

class FocusedMagentaBeaver(QCAlgorithm):

    def Initialize(self):

        # Requirements: 
        # weight >= 0.25 each 
        # drawdowown < 15%
        # sharpe > 1.0

        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetEndDate(2019, 1, 1)
        self.SetCash(1000000)  # Set Strategy Cash
        # self.SetWarmup(30)

        self.amd = "AMD"
        self.jnj = "JNJ"
        self.symA = self.AddEquity(self.amd, Resolution.Daily)
        self.symJ = self.AddEquity(self.jnj, Resolution.Daily)
        self.amdsma = self.SMA(self.amd, 30, Resolution.Daily)
        self.amdrsi = self.RSI(self.amd, 20, Resolution.Daily)
        self.amdbb = self.BB(self.amd, 20, 2, Resolution.Daily)
        self.jnjrsi = self.RSI(self.jnj, 20, Resolution.Daily)
        self.jnjbb = self.BB(self.jnj, 20, 2.1, Resolution.Daily)
        self.jnjsma = self.SMA(self.amd, 30, Resolution.Daily)


        self.wt = 0.25

        self.bb_trend_reversal = True # False if Trend Following; True if Trend Reversing


        self.count = 1

    def OnData(self, data: Slice):

        if self.count == 1:

            # Buy Both Stock on First Day
            self.SetHoldings(self.symJ.Symbol, -6*self.wt)
            self.SetHoldings(self.symA.Symbol,self.wt)
            self.count+=1
            self.amd_holding = 1
            self.jnj_holding = 1
        
        else: 
            #Indicators for AMD
            sma_amd = self.amdsma.Current.Value
            rsi_amd = self.amdrsi.Current.Value
            bbup_amd = self.amdbb.UpperBand.Current.Value
            bbdn_amd = self.amdbb.LowerBand.Current.Value
            bbmd_amd = self.amdbb.MiddleBand.Current.Value

            #Indicators for JNJ
            sma_jnj = self.jnjsma.Current.Value
            rsi_jnj = self.jnjrsi.Current.Value
            bbup_jnj = self.jnjbb.UpperBand.Current.Value
            bbdn_jnj = self.jnjbb.LowerBand.Current.Value
            bbmd_jnj = self.jnjbb.MiddleBand.Current.Value


            

            # Trend-reversal strategy for AMD based on RSI and SMA
            self.Debug( " Time: " + str(self.Time) + "Price: " + str(self.symJ.Price)+" SMA: "+str()+" "+str(bbdn_jnj))

            # If see decresing trend and only hold initial holding, long 150%
            if self.symA.Price - sma_amd < -1.8  and self.amd_holding == 1:
            
                self.SetHoldings(self.symA.Symbol, 5*self.wt)
                self.amd_holding += 5

            # Trend Reversal for AMD based on RSI and SMA
            if rsi_amd>80 and self.symA.Price - sma_amd > 9 and not self.Portfolio[self.amd].IsShort:
            
                self.SetHoldings(self.symA.Symbol, -7*self.wt)
                self.amd_holding = -7

            elif rsi_amd < 30.4 and sma_amd < 27.6 and self.Portfolio[self.amd].IsShort:
                self.SetHoldings(self.symA.Symbol, self.wt)

            
            
            # Trend-reversal strategy for JNJ based on BB
            if bbdn_jnj > self.symJ.Price and not self.Portfolio[self.jnj].IsLong:
                self.SetHoldings(self.symJ.Symbol,1.8*self.wt)

            elif bbup_jnj < self.symJ.Price and not self.Portfolio[self.jnj].IsShort:
                self.SetHoldings(self.symJ.Symbol,-1*self.wt)