Overall Statistics
Total Trades
258
Average Win
1.36%
Average Loss
-0.96%
Compounding Annual Return
5.127%
Drawdown
12.200%
Expectancy
0.222
Net Profit
28.912%
Sharpe Ratio
0.584
Probabilistic Sharpe Ratio
15.208%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
1.42
Alpha
0.046
Beta
-0.009
Annual Standard Deviation
0.077
Annual Variance
0.006
Information Ratio
-0.405
Tracking Error
0.144
Treynor Ratio
-5.083
Total Fees
$258.00
import numpy as np
import pandas as pd
import math

class NadionHorizontalCircuit(QCAlgorithm):

        ## order ticket for stop order
        stopMarketTicket = None
        stopMarketFillTime = datetime.min
        highestPrice = 0
        

        def Initialize(self):
                self.SetStartDate(2015, 1, 2)  # Set Start Date
                self.SetEndDate(2020, 1, 28)
                self.SetCash(10000)  # Set Strategy Cash
               
                self.ziv = self.AddEquity("ZIV", Resolution.Daily)
                self.ziv.SetDataNormalizationMode(DataNormalizationMode.Raw)
            
                self.roc = self.ROC("ZIV", 5, Resolution.Daily)
                #self.SetWarmUp(5)
                self.lastOrderEvent = None ## this is for listening to order status
                
                # get ATR to use for stop loss.
                self.atr = self.ATR("ZIV", 20, Resolution.Daily)
                
                # get volatility
                self.lookback = 30
                self.SetWarmUp(self.lookback)
                
                # define portfolio volatility
                self.target_portfolio_sigma = 0.12
        
        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
                '''
                if self.IsWarmingUp:
                    return
                
                # check that 1 day have passed since we hit the stop loss.
                if(self.Time - self.stopMarketFillTime).days < 2:
                    return ## this means wait
                
                if not self.Portfolio.Invested:
                    if self.roc.Current.Value > 0:
                        # get historical return data and calculate volatility
                        history_data = self.History(self.Symbol("ZIV"),self.lookback, Resolution.Daily).close.unstack(level=0)
                        history_data = history_data['ZIV']
                        change = history_data.pct_change().dropna()
                        volatility = change.std(ddof=1)
                        volatility = volatility * np.sqrt(252)
                
                        # calculate quantity to trade based on the targeted vol
                        weight = self.target_portfolio_sigma / volatility
                        quantity = (self.Portfolio.TotalPortfolioValue * weight)/self.Securities["ZIV"].Close
                        
                        self.MarketOrder("ZIV", quantity)
                        # create stop loss and track the ticket
                        self.stopMarketTicket = self.StopMarketOrder("ZIV", -quantity, self.Securities["ZIV"].Close - 2 * self.atr.Current.Value)
                else:
                    if self.roc.Current.Value > 0:
                        # check if the current price is higher than the highest closing price since we entered position
                        if self.Securities["ZIV"].Close > self.highestPrice:
                            # save the new highestPrice
                            self.highestPrice = self.Securities["ZIV"].Close
                            updateFields = UpdateOrderFields()
                            updateFields.StopPrice = self.highestPrice - 2 * self.atr.Current.Value ## updating stop price
                            self.stopMarketTicket.Update(updateFields)
                            self.Debug("ZIV: " + str(self.highestPrice) + " Stop: " + str(updateFields.StopPrice))
                    else:
                        self.Liquidate("ZIV")
       
        def OnOrderEvent(self, orderEvent):
            
            if orderEvent.Status != OrderStatus.Filled:
                return ## if no orders were filled then wait and dont worry.
            
            # this checks that the stop order ticket was submitted
            if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId:
                self.stopMarketFillTime = self.Time
                self.Debug(self.stopMarketFillTime)
class Volatility(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 2)  # Set Start Date
        self.SetCash(10000)  # Set Strategy Cash
        # self.AddEquity("SPY", Resolution.Minute)
        self.ziv = self.AddEquity("ZIV", Resolution.Daily)
        self.ziv.SetDataNormalizationMode(DataNormalizationMode.Raw)
    
        self.roc = self.ROC("ZIV", 5, Resolution.Daily)
        self.SetWarmUp(5)
        
        self.Schedule.On(self.DateRules.EveryDay("ZIV"), self.TimeRules.BeforeMarketClose("ZIV", 5), self.trade_signal)
        
    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
        '''
        if self.IsWarmingUp:
            return
        
        '''
        if self.roc.Current.Value > 0:
            self.SetHoldings("ZIV",1)
        else:
            self.Liquidate("ZIV")
         '''
         
            
    def trade_signal(self):
        
        if self.roc.Current.Value > 0 and not self.portfolio.Invested:
            self.SetHoldings("ZIV",1)
        else:
            self.Liquidate("ZIV")