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
-2.125
Tracking Error
0.125
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
# Finite Impulse Response Synthesized Filters (TATL, FATL, SATL) by Vladimir

# Inspired by my friend and colleague Aleksandr Temesov Ph.D. in digital signal processing, 
# who synthesized the minimum phase part of the filter generated by the REMEZ exchange algorithm.
# https://eeweb.engineering.nyu.edu/iselesni/EL713/remez/remez.pdf
# Hope they will be useful in generating alphas on QuantConnect

# ---------------------------
STOCK = 'AMZN'; PERIOD = 100;
# ---------------------------
import numpy as np

class FiniteImpulseResponseSynthesizedFilters(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)
        self.SetEndDate(2021, 6, 16) 
        self.SetCash(100000) 
        self.stock = self.AddEquity(STOCK, Resolution.Daily).Symbol
        self.tatl = TATL('TATL')
        self.RegisterIndicator(self.stock, self.tatl, Resolution.Daily)
        self.fatl = FATL('FATL')
        self.RegisterIndicator(self.stock, self.fatl, Resolution.Daily)
        self.satl = SATL('SATL')
        self.RegisterIndicator(self.stock, self.satl, Resolution.Daily)
        
        self.SetWarmUp(PERIOD)


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

        price = self.Securities[self.stock].Price

        self.Plot("Indicator", "price", float(price))
        self.Plot("Indicator", "TATL", float(self.tatl.Value))
        self.Plot("Indicator", "FATL", float(self.fatl.Value))
        self.Plot("Indicator", "SATL", float(self.satl.Value))
        
           
class TATL(PythonIndicator): # Temesov Adaptive Trend Line
    def __init__(self, name):
        self.Name = name
        
        self.weights = [-0.00047584,0.00252315,0.0032737,-0.00084161,-0.00847755,
        -0.01379877,-0.00910121,0.00922824,0.03537854,0.0539437,0.0472029,
        0.0067766,-0.05713211,-0.11600142,-0.13455926,-0.08874218,0.01991035,
        0.16192065,0.29187502,0.36853396,0.42856314 ]
        
        self.filter_length = len(self.weights)
        self.Time = datetime.min
        self.Value = 0
        self.prices = np.array([])
        

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

        if len(self.prices) != self.filter_length:
            self.Value = 0
            return False
        
        self.Value = sum(self.prices * self.weights) / sum(self.weights)
        return True
  
        
class FATL(PythonIndicator): # Fast Adaptive Trend Line
    def __init__(self, name):
        self.Name = name
        
        self.weights = [-0.00238594,0.01100795,0.00633334,0.00368077,-0.00024667,
        -0.0046041,-0.00732354,-0.00664142,-0.00225157,0.00421217,0.00968245,0.01104504,
        0.00680725,-0.00180739,-0.01102892,-0.01608535,-0.01356695,-0.00346634,
        0.01024398,0.02098501,0.02259397,0.01260074,-0.00583542,-0.02458918,-0.03389151,
        -0.02706271,-0.00450561,0.02515976,0.04786514,0.0500806,0.02569156,-0.01937382,
        -0.06715848,-0.09325235,-0.07580002,-0.005095,0.11067179,0.24604608,0.36562024,
        0.43564443]
        
        self.filter_length = len(self.weights)
        self.Time = datetime.min
        self.Value = 0
        self.prices = np.array([])
        

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

        if len(self.prices) != self.filter_length:
            self.Value = 0
            return False
        
        self.Value = sum(self.prices * self.weights) / sum(self.weights)
        return True
   
        
class SATL(PythonIndicator):  # Slow Adaptive Trend Line
    def __init__(self, name):
        self.Name = name
        
        self.weights = [-0.00315077,0.00108904,0.00102578,0.00102857,0.00107984,
        0.00116196,0.00126304,0.00136938,0.00147216,0.00155979,0.00162571,0.0016596,
        0.00165751,0.00161068,0.00151795,0.00137232,0.00117709,0.00092568,
        0.00063025,0.00028027,-0.00010612,-0.00052179,-0.00097111,-0.00143083,
        -0.00189157,-0.0023386,-0.00276276,-0.00314733,-0.00347943,-0.0037418,
        -0.00392283,-0.00400856,-0.00399047,-0.00385916,-0.00361072,-0.00324089,
        -0.0027517,-0.00214592,-0.00143082,-0.00062046,0.00027523,0.0012338,
        0.0022344,0.00325413,0.00426606,0.00524054,0.006148,0.00695895,0.00764401,
        0.00817482,0.00852418,0.00866919,0.00858979,0.00827162,0.00770422,0.00688468,
        0.00581377,0.00450249,0.00296496,0.00122562,-0.00068465,-0.0027303,-0.00486716,
        -0.00704613,-0.00921393,-0.01131352,-0.01328381,-0.01506315,-0.01658875,
        -0.01780034,-0.01863875,-0.01904923,-0.01898181,-0.01839402,-0.01725033,
        -0.0155248,-0.01320106,-0.01027274,-0.00674638,-0.00263737,0.00202481,    
        0.00720018,0.01283793,0.01887708,0.02524585,0.0318656,0.03864959,0.04550578,
        0.05233786,0.05904702,0.06553496,0.0717041,0.07746041,0.08271427,0.08738411,
        0.09139542,0.09468511,0.09719971,0.09889903,0.0997559]
        
        self.filter_length = len(self.weights)
        self.Time = datetime.min
        self.Value = 0
        self.prices = np.array([])
        

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

        if len(self.prices) != self.filter_length:
            self.Value = 0
            return False
        
        self.Value = sum(self.prices * self.weights) / sum(self.weights)
        return True