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
# Slow Adaptive Trend Line (SATL) FIR_Filter 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 SlowAdaptiveTrendLine(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.sma = self.SMA(self.stock, PERIOD, 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.satl.IsReady: return

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

        self.Plot("Indicator", "PRICE", float(price))
        self.Plot("Indicator", "SATL", float(self.satl.Value))
        self.Plot("Indicator", "SMA", self.sma.Current.Value)
        
           
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