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
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
namespace QuantConnect.Indicators {
	
	using System.Numerics;
	
	public class FourierSeries {
		
		private readonly int _period;
		private readonly double _frequency;
		private readonly int _depth;
		private double _leading;
		private double _value;
		private GuassianQuadrature _gauss;
		
		public int WarmUpPeriod { get; }
		
		public bool IsReady => CosineCoefficients.Count() == _depth && SineCoefficients.Count() == _depth;
		public double Value => _value;
		
		public double LeadingCoefficient => _leading;
		public List<double> CosineCoefficients { get; }
		public List<double> SineCoefficients { get; }
		
		public void Reset()
		{
			CosineCoefficients.Clear();
			SineCoefficients.Clear();
		}
		
		public FourierSeries(string name, int period, int n = 5, double frequency = 2 * (double)Math.PI, int depth = 5) 
		{
			_period = period;
			_frequency = frequency;
			_depth = depth;
			_gauss = new GuassianQuadrature(n);
			
			WarmUpPeriod = period;
			CosineCoefficients = new List<double>();
			SineCoefficients = new List<double>();
		}
		
		
		private static Func<double, double> _func;
		private static int _n = 0;
		public double AlphaIntegralFunction(double t) {
			return _func(t) * Math.Cos(_n * t);
		}
		
		public double BetaIntegralFunction(double t) {
			return _func(t) * Math.Sin(_n * t);
		}
		
		public void Update(double value, Func<double, double> f) 
		{
			// update temp variables
			_func = f;
			
			// calculate coefficients
			_leading = (1.0 / _frequency) * _gauss.Solve(f, 0, _frequency);
			
			// clear coefficients
			CosineCoefficients.Clear();
			SineCoefficients.Clear();
			
			for(int i = 1; i <= _depth; i++) 
			{
				_n = i;
				
				double a_n = (2.0 / _frequency) * _gauss.Solve(AlphaIntegralFunction, 0, _frequency);
				CosineCoefficients.Add(a_n);
				
				double b_n = (2.0 / _frequency) * _gauss.Solve(BetaIntegralFunction, 0, _frequency);
				SineCoefficients.Add(b_n);
			}
			
			_value = CalculateFunction(value);
		}
		
		public double CalculateFunction(double value, int iterations) {
			
			double result = value;
			for(int i = 0; i <= iterations; i++)
				result = CalculateFunction(result);
			
			return result;
		}
		
		public double CalculateFunction(double value) {
			
			var function = LeadingCoefficient;
			
			for(int i = 0; i < _depth; i++) {
				function += (CosineCoefficients[i] * (double)Math.Cos((double)((i + 1) * (double)Math.PI * value / _frequency))) / (i + 1);
				function += (SineCoefficients[i] * (double)Math.Sin((double)((i + 1) * (double)Math.PI * value / _frequency))) / (i + 1);
			}
			
			return function;
		}
	}
}
namespace QuantConnect.Indicators {
	
    public class GuassianQuadrature {
    	
    	private readonly int N;
    	private readonly double[] _roots;
    	private readonly double[] _weights;
    	private readonly double[,] _coefficients;
    	
    	public GuassianQuadrature(int N) {
    		this.N = N;
    		this._roots = new double[N];
    		this._weights = new double[N];
    		this._coefficients = new double[N + 1, N + 1];
    		
    		GenerateCoefficients();
    		GenerateRoots();
    	}
    	
		private void GenerateCoefficients() {
	        _coefficients[0, 0] = _coefficients[1, 1] = 1;
	 
	        for (int n = 2; n <= N; n++) {
	 
	            _coefficients[n, 0] = -(n - 1) * _coefficients[n - 2, 0] / n;
	 
	            for (int i = 1; i <= n; i++) {
	                _coefficients[n, i] = ((2 * n - 1) * _coefficients[n - 1, i - 1]
	                        - (n - 1) * _coefficients[n - 2, i]) / n;
	            }
	        }
	    }
	 
	    private double Evaluate(int n, double x) {
	        double s = _coefficients[n, n];
	        for (int i = n; i > 0; i--)
	            s = s * x + _coefficients[n, i - 1];
	        return s;
	    }
	 
	    private double Differentiate(int n, double x) {
	        return n * (x * Evaluate(n, x) - Evaluate(n - 1, x)) / (x * x - 1);
	    }
	 
	    private void GenerateRoots() {
	        double x, x1;
	        for (int i = 1; i <= N; i++) {
	            x = Math.Cos(Math.PI * (i - 0.25) / (N + 0.5));
	            do {
	                x1 = x;
	                x -= Evaluate(N, x) / Differentiate(N, x);
	            } while (x != x1);
	 
	            _roots[i - 1] = x;
	 
	            x1 = Differentiate(N, x);
	            _weights[i - 1] = 2 / ((1 - x * x) * x1 * x1);
	        }
	    }
	 
	    public double Solve(Func<Double, Double> f, double a, double b) {
	        double c1 = (b - a) / 2, c2 = (b + a) / 2, sum = 0;
	        for (int i = 0; i < N; i++)
	            sum += _weights[i] * f(c1 * _roots[i] + c2);
	        return c1 * sum;
	    }
    }
}
/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Linq;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra;

namespace QuantConnect.Indicators
{
    /// <summary>
    /// The Least Squares Moving Average (LSMA) first calculates a least squares regression line
    /// over the preceding time periods, and then projects it forward to the current period. In
    /// essence, it calculates what the value would be if the regression line continued.
    /// Source: https://rtmath.net/helpFinAnalysis/html/b3fab79c-f4b2-40fb-8709-fdba43cdb363.htm
    /// </summary>
    public class LeastSquaresMovingAverage : WindowIndicator<IndicatorDataPoint>, IIndicatorWarmUpPeriodProvider
    {
        /// <summary>
        /// Array representing the time.
        /// </summary>
        private readonly double[] _t;

        /// <summary>
        /// The point where the regression line crosses the y-axis (price-axis)
        /// </summary>
        public IndicatorBase<IndicatorDataPoint> Intercept { get; }
        
        /// <summary>
        /// The regression line slope
        /// </summary>
        public IndicatorBase<IndicatorDataPoint> Slope { get; }

        /// <summary>
        /// Required period, in data points, for the indicator to be ready and fully initialized.
        /// </summary>
        public int WarmUpPeriod => Period;

        /// <summary>
        /// Initializes a new instance of the <see cref="LeastSquaresMovingAverage"/> class.
        /// </summary>
        /// <param name="name">The name of this indicator</param>
        /// <param name="period">The number of data points to hold in the window</param>
        public LeastSquaresMovingAverage(string name, int period)
            : base(name, period)
        {
            _t = Vector<double>.Build.Dense(period, i => i + 1).ToArray();
            Intercept = new Identity(name + "_Intercept");
            Slope = new Identity(name + "_Slope");
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LeastSquaresMovingAverage"/> class.
        /// </summary>
        /// <param name="period">The number of data points to hold in the window.</param>
        public LeastSquaresMovingAverage(int period)
            : this($"LSMA({period})", period)
        {
        }

        /// <summary>
        /// Computes the next value of this indicator from the given state
        /// </summary>
        /// <param name="window"></param>
        /// <param name="input">The input given to the indicator</param>
        /// <returns>
        /// A new value for this indicator
        /// </returns>
        protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
        {
            // Until the window is ready, the indicator returns the input value.
            if (window.Samples <= window.Size) return input.Value;

            // Sort the window by time, convert the observations to double and transform it to an array
            var series = window
                .OrderBy(i => i.Time)
                .Select(i => Convert.ToDouble(i.Value))
                .ToArray();
            // Fit OLS
            var ols = Fit.Line(x: _t, y: series);
            Intercept.Update(input.Time, (decimal)ols.Item1);
            Slope.Update(input.Time, (decimal)ols.Item2);

            // Calculate the fitted value corresponding to the input
            return Intercept.Current.Value + Slope.Current.Value * Period;
        }

        /// <summary>
        /// Resets this indicator and all sub-indicators (Intercept, Slope)
        /// </summary>
        public override void Reset()
        {
            Intercept.Reset();
            Slope.Reset();
            base.Reset();
        }
    }
}
namespace QuantConnect.Algorithm.CSharp
{
	using System;
	using System.Numerics;
	
    public class ClientAlgorithm : QCAlgorithm
    {
    	// BACKTESTING PARAMETERS
    	// =================================================================================================================
    	
    	// general settings:
    	
    	// set starting cash
    	private int _startingCash = 100000;
    	
    	// backtesting start date time:
    	// date setting variables
    	private int _startYear = 2022;
    	private int _startMonth = 1;
    	private int _startDay = 3;
    	
    	// backtesting end date time:
    	// determines whether there is a specified end date
    	// if false it will go to the current date (if 'true' it will go to the specified date)
    	private bool _enableEndDate = true;
    	// date setting variables
    	private int _endYear = 2022;
    	private int _endMonth = 1;
    	private int _endDay = 3;
    	
    	// enable plotting
    	private bool enablePlotting = true;
    	
    	
    	// universe settings:
    	
    	// universe selection type
    	// determines whether securities are selected by QC's universe function
    	// or manually by the user
    	// manual = false; QC universe = true
    	private readonly bool _universeSelectionType = false;
    	
    	// number of securities for the universe selection to select
    	private readonly int _stockCount = 5;
    	
    	// use default values for universe
    	private readonly bool _useDefaultSymbolBase = false;
    	
    	// stock list for equities
    	// list of equities you want in the universe
    	// used in manual selection of universe
    	// set selectionType = false for activation
    	private readonly SymbolBase[] _universeList = new SymbolBase[]{
    			new SymbolBase(
    				"AMZN",				// symbol ticker
    				Resolution.Minute,	// data resolution
    				1,					// data resolution consolidation rate
    				1.0m				// portfolio allocation percentage
    			)
    	};
    	
    	// default symbol base settings
    	// used if using QC universe selection or a base is not detected for
    	// an added security
    	private readonly SymbolBase _defaultSymbolBase = new SymbolBase(
    		"<BASE>",					// do not modify
    		
    		// parameters to modify:
    		Resolution.Minute,			// data resolution
    		1,							// data resolution consolidation rate
    		1.0m						// portfolio allocation percentage
    	);
    	
    	
    	// position settings:
    	
    	// percent of portfolio to use for trading
    	// must be below 1
    	private readonly decimal _portfolioAllocation = 1m;
    	
    	// =================================================================================================================
		
		// contains all SymbolBase definitions
		private Dictionary<string, SymbolBase> _symbolBases = new Dictionary<string, SymbolBase>();
		
		// creates new universe variable setting
		private Dictionary<Symbol, SymbolData> _universe = new Dictionary<Symbol, SymbolData>();
		
		// security changes variable
		private SecurityChanges _securityChanges = SecurityChanges.None;
		
		// define offset universe to avoid first candle
		private bool offsetUniverse = true;
		
        public override void Initialize()
        {
        	// set start date
            SetStartDate(_startYear, _startMonth, _startDay);
            // set end date
            if(_enableEndDate)
            	SetEndDate(_endYear, _endMonth, _endDay);
            // set starting cash
            SetCash(_startingCash);
            
            // add default symbol base
            _symbolBases.Add("<BASE>", _defaultSymbolBase);
            
            // initialize universe
            if(!_universeSelectionType) {
 	            foreach(SymbolBase sb in _universeList) {
 	            	_symbolBases.Add(sb.Symbol, sb);
	            	AddEquity(sb.Symbol, sb.SymbolResolution);
	            }
            } else {
            	UniverseSettings.Resolution = _defaultSymbolBase.SymbolResolution;
            	AddUniverse(CoarseFilterFunction, FineFilterFunction
            	);
            }
        }

		public double f(double x) {
			return Math.Exp(x);
		}

		// filter based on CoarseFundamental
	    public IEnumerable<Symbol> CoarseFilterFunction(IEnumerable<CoarseFundamental> coarse) {
	    	// returns the highest DollarVolume stocks
	    	// returns "totalNumberOfStocks" amount of stocks
	        return (from stock in coarse
	        		where !stock.HasFundamentalData
	        		orderby stock.DollarVolume descending
	        		select stock.Symbol).Take(_stockCount);
        	return Universe.Unchanged;
	    }
	    
	    // filters out all symbols not contained in the NASDAQ exchange
	    public IEnumerable<Symbol> FineFilterFunction(IEnumerable<FineFundamental> fine) {
	    	return (from stock in fine
	    			select stock.Symbol).Take(_stockCount);
	    }
	    
		private static double[] _coefficients = null;
		public double Regression(double t) {
			if(_coefficients == null)
				return 0.0;
				
			double sum = 0;
			for(int i = 0; i < _coefficients.Count(); i++)
				sum += Math.Pow(t, i) * _coefficients[i];
			
			return sum;
		}
		
		private decimal time = 0;
		public void OnDataConsolidated(object sender, TradeBar bar) {
			SymbolData sd = _universe[bar.Symbol];
			sd.Close.Add(bar.Close);
			
			if(!sd.Close.IsReady)
				return;
				
			_coefficients = new double[] {(double)sd.LeastSquares.Intercept.Current.Value, (double)sd.LeastSquares.Slope.Current.Value};
			
			if(time % 5 == 0)
				sd.Fourier.Update((double)sd.Close[0], Regression);
			
			if(!sd.IsReady) {
				return;
			}
			
			if(enablePlotting) {
				Plot("FS", "P", bar.Close);
				Plot("FS", "F0", sd.Fourier.CalculateFunction(0));
				Plot("FS", "F1", sd.Fourier.CalculateFunction(1));
				Plot("LS", "I", sd.LeastSquares.Intercept);
				Plot("LS", "S", sd.LeastSquares.Slope);
				Plot("FSC", "A0", sd.Fourier.LeadingCoefficient);
				Plot("FSC", "A1", sd.Fourier.CosineCoefficients[0]);
				Plot("FSC", "B1", sd.Fourier.SineCoefficients[0]);
				//Plot("FSS", "B1", sd.Fourier.SineCoefficients[0]);
				//Plot("FSS", "B2", sd.Fourier.SineCoefficients[1]);
			}
			
			/*if(coeff < -3 && !Portfolio[sd.Symbol].Invested)
				SetHoldings(sd.Symbol, 1);
			else if(coeff > 3)
				Liquidate(sd.Symbol);
			
			sd.Fourier.Update(sd.Close[0], sd.LeastSquares.Intercept, sd.LeastSquares.Slope);*/
		}
		
		public decimal[] ForwardEuler(Func<decimal, decimal> f, decimal ya, int a, int b, int n) {
			
			decimal dt = (b - a * 1.0m) / n;
			
			decimal[] y = new decimal[n + 1];
			decimal[] t = new decimal[n + 1];
			y[0] = ya;
			t[0] = 0;
			
			for(int i = 1; i < n + 1; i++) {
				t[i] = t[i - 1] + dt;
				y[i] = y[i - 1] + (dt * f(t[i]));
			}
			
			return y;
		}
        
        // OnSecuritiesChanged runs when the universe updates current securities
        public override void OnSecuritiesChanged(SecurityChanges changes) {
            _securityChanges = changes;
            // remove stocks from list that get removed from universe
            foreach (var security in _securityChanges.RemovedSecurities) {
            	if(Securities[security.Symbol].Invested) {
            		Log($"{Time}->Portfolio: Liquidated security {security.Symbol} on universe exit");
            		Liquidate(security.Symbol);
            	}
            	
            	_universe.Remove(security.Symbol);
            	Log($"{Time}->Universe: Removed security {security.Symbol} from universe");
            }
            
            // add new securities to universe list
            foreach(var security in _securityChanges.AddedSecurities) {
            	// creare new SymbolData object
            	SymbolData sd;
            	
            	// if no base exists for symbol use default
            	if(!_symbolBases.ContainsKey(security.Symbol) || _useDefaultSymbolBase)
            		sd = new SymbolData(this, security.Symbol, _symbolBases["<BASE>"]);
            		
            	// otherwise use defined base
            	else
	            	sd = new SymbolData(this, security.Symbol, _symbolBases[security.Symbol]);
            	
            	// initialize consolidator and store if needed
            	TickConsolidator tickConsolidator = null;
            	TradeBarConsolidator barConsolidator = null;
            	if(sd.SymbolBase.SymbolResolution == Resolution.Tick) {
            		var consolidator = sd.GetTickConsolidator();
            		if(consolidator != null) {
	            		consolidator.DataConsolidated += OnDataConsolidated;
	            		SubscriptionManager.AddConsolidator(sd.Symbol, consolidator);
	            		tickConsolidator = consolidator;
            		}
            		
            	} else {
            		var consolidator = sd.GetConsolidator();
            		if(consolidator != null) {
	            		consolidator.DataConsolidated += OnDataConsolidated;
	            		SubscriptionManager.AddConsolidator(sd.Symbol, consolidator);
	            		barConsolidator = consolidator;
            		}
            	}
            	
            	// initialize indicators:
            	sd.Fourier = new FourierSeries(sd.Symbol, 15, 5, 2 * Math.PI, 2);
            	sd.LeastSquares = new LeastSquaresMovingAverage(sd.Symbol, 2);
            	
            	// register indicators
            	if(tickConsolidator != null) {
            		RegisterIndicator(sd.Symbol, sd.LeastSquares, tickConsolidator);
            	}
            	
            	else {
            		RegisterIndicator(sd.Symbol, sd.LeastSquares, barConsolidator);
            	}
            	
            	// load historical data
            	var historical = History(sd.Symbol, sd.LeastSquares.WarmUpPeriod, sd.SymbolBase.SymbolResolution);
            	foreach(var bar in historical) {
            		sd.LeastSquares.Update(bar.Time, bar.Close);
            	}
            	
            	// add SymbolData to universe
            	_universe.Add(security.Symbol, sd);
            	Log($"{Time}->Universe: Added security {security.Symbol} to universe");
            }
        }
        
        public class SymbolBase {
        	public readonly string Symbol;
        	public readonly Resolution SymbolResolution;
        	public readonly int SymbolConsolidationRate;
        	public readonly decimal PortfolioAllocation;
        	
        	public SymbolBase(string symbol = "<BASE>", Resolution symbolResolution = Resolution.Minute, int symbolConsolidationRate = 1, decimal portfolioAllocation = 1.0m) {
        		Symbol = symbol;
        		SymbolResolution = symbolResolution;
        		SymbolConsolidationRate = symbolConsolidationRate;
        		PortfolioAllocation = portfolioAllocation;
        	}
        }
		
		// default class containing all symbol information
		public class SymbolData {
			// Variables:
			// algorithm
			public readonly ClientAlgorithm Algorithm;
			// symbol
			public readonly string Symbol;
			// symbol base
			public readonly SymbolBase SymbolBase;
			// is ready
			public bool IsReady => Close.IsReady && Fourier.IsReady && LeastSquares.IsReady;
			
			// previous close
			public RollingWindow<decimal> Close = new RollingWindow<decimal>(10);
			// fourier series
			public FourierSeries Fourier;
			// least squares SMA
			public LeastSquaresMovingAverage LeastSquares;
			
			public SymbolData(ClientAlgorithm algorithm, Symbol symbol, SymbolBase symbolBase) {
				Algorithm = algorithm;
				Symbol = symbol;
				SymbolBase = symbolBase;
			}
			
			public TradeBarConsolidator GetConsolidator() {
				TimeSpan timeSpan;
				switch(SymbolBase.SymbolResolution) {
					case Resolution.Second:
						timeSpan = TimeSpan.FromSeconds(SymbolBase.SymbolConsolidationRate);
						break;
					case Resolution.Minute:
						timeSpan = TimeSpan.FromMinutes(SymbolBase.SymbolConsolidationRate);
						break;
					case Resolution.Hour:
						timeSpan = TimeSpan.FromHours(SymbolBase.SymbolConsolidationRate);
						break;
					case Resolution.Daily:
						timeSpan = TimeSpan.FromDays(SymbolBase.SymbolConsolidationRate);
						break;
					default:
						return null;
				}
				
				return new TradeBarConsolidator(timeSpan);
			}
			
			public TickConsolidator GetTickConsolidator() {
				return new TickConsolidator(SymbolBase.SymbolConsolidationRate);
			}
		}
    }
}