Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-0.988
Tracking Error
0.168
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
# Custom indicator based on the Epanechnikov kernel. 

# Nonparametric estimation of a multidimensional probability density by V. A. Epanechnikov
# http://www.mathnet.ru/links/74bd23faeeb1ccffdba0a1b221fd436c/tvp1130.pdf
# https://en.wikipedia.org/wiki/Kernel_(statistics)
# http://staff.ustc.edu.cn/~zwp/teach/Math-Stat/kernel.pdf
# -------------------------
STOCK = 'MSFT'; PERIOD = 50; 
# -------------------------
import numpy as np

class CustomIndicator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2016, 6, 24)
        self.SetCash(100000) 
        self.stock = self.AddEquity(STOCK, Resolution.Daily).Symbol
        self.ek_filter = EpanechnikovKernel(PERIOD)
        self.RegisterIndicator(self.stock, self.ek_filter, Resolution.Daily)
        self.SetWarmUp(PERIOD)


    def OnData(self, data):
        if self.IsWarmingUp or not self.ek_filter.IsReady: return

        price = float(self.Securities[self.stock].Price)

        self.Plot("Indicator", "ek_filter", float(self.ek_filter.Value))
        self.Plot("Indicator", "price", price)
        
           
class EpanechnikovKernel(PythonIndicator):   # Second-Order Epanechnikov kernel
    def __init__(self, period):
        self.period = period
        self.Time = datetime.min
        self.Value = 0
        self.prices = np.array([])
        

    def Update(self, input):
        self.prices = np.append(self.prices, input.Close)[-self.period:]

        if len(self.prices) != self.period:
            self.Value = 0
            return False
        
        self.Value = self.ek(self.prices)
        return True
        
    
    def ek(self, prices):
        prices = np.array([])
        for i in range(len(self.prices)):
            price = self.prices[i] 
            prices = np.append(prices, price)
            
        return self.weighted_average(prices, self.ek_weights(len(prices)))

        
    def ek_weights(self, length):
        weights = np.array([])

        for i in range(length):
            w = 0.75*(1 - (1 - i/length)**2) 
            weights = np.append(weights, w)
        return weights
        
        
    def weighted_average(self, prices, weights):
        products = []
        for i in range(len(prices)):
            products.append(prices[i] * weights[i])
        return sum(products) / sum(weights)