Overall Statistics
Total Trades
3200
Average Win
0.09%
Average Loss
-0.08%
Compounding Annual Return
12.061%
Drawdown
31.200%
Expectancy
0.165
Net Profit
40.766%
Sharpe Ratio
0.639
Probabilistic Sharpe Ratio
25.399%
Loss Rate
45%
Win Rate
55%
Profit-Loss Ratio
1.13
Alpha
0.12
Beta
-0.095
Annual Standard Deviation
0.169
Annual Variance
0.028
Information Ratio
-0.066
Tracking Error
0.211
Treynor Ratio
-1.131
Total Fees
$3357.93
import numpy as np
import pandas as pd
import datetime
class NadionResistanceAutosequencers(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2017, 1, 1)
        self.SetEndDate(2020,1,1)# Set Start Date
        self.SetCash(100000)
        self.Security=["LMT","MSFT","GM","MS","FB","NKE","TSLA","MS","GS","AMZN","T","BA","BLK","EA","C","KO","AMD","MMM","AXP","F","HON","SPY"]
        for s in self.Security:
            self.AddEquity(s,Resolution.Daily)
        
        self.SMASPYS = self.SMA('SPY',10)
        self.SMASPYL = self.SMA('SPY',30)
        
        self.SetWarmUp(360)


        # Set Strategy Cash
        # self.AddEquity("SPY", Resolution.Minute)


    def OnData(self,data):
        
        if self.IsWarmingUp:
            return 
        
        S=["LMT","MSFT","GM","MS","FB","NKE","TSLA","MS","GS","AMZN","T","BA","BLK","EA","C","KO","AMD","MMM","AXP","F","HON","SPY"]
        
        M=self.History(S,360,Resolution.Daily)
        
        M=M.close
        
        V=M.unstack(level=0)
        
        Daily_returns=np.log(V/V.shift(1))
        
        Daily_returns_mean = Daily_returns.mean()
        
        Daily_std = Daily_returns.std()
        
        SPY_index_return = Daily_returns_mean[-1] * 250
        
        SPY_index_Var = Daily_returns.var()[-1] * 250**(1/2)
        
        covariance_index_stock = Daily_returns.cov()
        
        Beta = (covariance_index_stock.iloc[:,-1]/SPY_index_Var)*250
        
        Rcapm = 0.02 + Beta * (SPY_index_return-0.02)
        
        SR = (Rcapm - 0.02)/(Daily_std*250)

        
        for i in range(len(S)-1):
            if SR[i]>0 and self.SMASPYS.Current.Value >self.SMASPYL.Current.Value :
                self.SetHoldings(S[i],2/(len(S)-1))
            elif SR[i]>0 and self.SMASPYS.Current.Value <self.SMASPYL.Current.Value :
                self.Liquidate(S[i])
            else:
                return
        for i in range(len(S)-1):
            if SR[i]<0 and self.SMASPYS.Current.Value < self.SMASPYL.Current.Value :
                self.SetHoldings(S[i],-2/(len(S)-1))
            elif SR[i]<0 and self.SMASPYS.Current.Value > self.SMASPYL.Current.Value :
                self.Liquidate(S[i])
            else:
                return
class MaximumDrawdownPercentPerSecurity(RiskManagementModel):
    
    
    def __init__(self,maximumDrawdownPercent = 0.10) :
        self.maximumDrawDownPercent = -abs(maximumDrawdownPercent)
        
        
    def ManageRisk(self,algorithm,targets) :
        target = []
        for items in algorithm.Securities :
            security = items.Value
            
            if not security.Invested:
                return
            
            pnl = self.Holdings.UnrealizedProfitPercent
            
            if pnl < self.maximumDrawdownPercent :
                target.append(PortfolioTarget(security.Symbol,0))
                
                return target