| Overall Statistics |
|
Total Trades 2273 Average Win 0.25% Average Loss -0.23% Compounding Annual Return 7.848% Drawdown 13.400% Expectancy -0.019 Net Profit 19.952% Sharpe Ratio 0.666 Loss Rate 53% Win Rate 47% Profit-Loss Ratio 1.11 Alpha NaN Beta NaN Annual Standard Deviation 0.125 Annual Variance 0.016 Information Ratio NaN Tracking Error NaN Treynor Ratio NaN Total Fees $2284.88 |
/*
* 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.
*/
namespace QuantConnect
{
public class BasicLaguerre : QCAlgorithm
{
public static string[] symbols = { "AAPL", "AMZN", "FB", "GE", "GOOGL", "JNJ", "JPM",
"MSFT", "NVS", "PFE", "PG", "PTR", "TM", "VZ", "WFC" };
public static double LaguerreFactor = 0.4;
Dictionary<string, Laguerre> Strategy = new Dictionary<string, Laguerre>();
public override void Initialize()
{
SetStartDate(2013, 1, 1); //Set Start Date
SetEndDate(2015, 5, 31); //Set End Date
SetCash(100000); //Set Strategy Cash
// Find more symbols here: http://quantconnect.com/data
foreach (string symbol in symbols)
{
AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
Strategy.Add(symbol, new Laguerre(LaguerreFactor));
}
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">TradeBars IDictionary object with your stock data</param>
public void OnData(TradeBars data)
{
foreach (string symbol in symbols)
{
Strategy[symbol].Add(data[symbol].Price);
if (Strategy[symbol].Signal != 0)
{
bool longSignal = (Strategy[symbol].Signal == 1) ? true : false;
bool shortSignal = (Strategy[symbol].Signal == -1) ? true : false;
if (!Portfolio[symbol].HoldStock)
{
SetHoldings(symbol, Strategy[symbol].Signal * 0.25);
}
else
{
if (Portfolio[symbol].IsLong && shortSignal) Liquidate(symbol);
if (Portfolio[symbol].IsShort && longSignal) Liquidate(symbol);
}
}
}
}
}
}
namespace QuantConnect
{
class Laguerre
{
decimal factor; // the factor constant
decimal tolerance = 0.09m;
decimal[] previousL = new decimal[4]; // contains the previous values of the L series
decimal[] actualL = new decimal[4]; // contains the previous values of the L series
decimal previousLaguerre;
decimal actualLaguerre;
decimal actualFIR;
decimal previousFIR;
int signal = 0;
public decimal PreviousLaguerre
{
get { return previousLaguerre; }
set { previousLaguerre = value; }
}
public decimal ActualLaguerre
{
get { return actualLaguerre; }
}
public decimal ActualFIR
{
get { return actualFIR; }
}
RollingWindow<decimal> windowFIR = new RollingWindow<decimal>(4);
public bool IsReady()
{
return windowFIR.IsReady;
}
public int Signal
{
get { return signal; }
}
public Laguerre(double Factor)
{
factor = new decimal(Factor);
}
/// <summary>
/// Adds the last value and estimate the Laguerre and FIR indicators.
/// </summary>
/// <param name="lastValue">The last value.</param>
/// <returns>Void.</returns>
public void Add(decimal lastValue)
{
if (windowFIR.Count == 0)
{
for (int i = 0; i < previousL.Length; i++) previousL[i] = lastValue;
previousLaguerre = lastValue;
previousFIR = lastValue;
windowFIR.Add(lastValue);
}
CalculateNextValue(lastValue);
CheckCross(previousLaguerre, actualLaguerre, previousFIR, actualFIR);
previousLaguerre = actualLaguerre;
previousFIR = actualFIR;
for (int i = 0; i < actualL.Length; i++) previousL[i] = actualL[i];
}
private void CalculateNextValue(decimal lastValue)
{
// Estimate L0
actualL[0] = (1m - factor) * lastValue + factor * previousL[0];
// Estimate L1 to L3
for (int i = 1; i < 4; i++)
{
actualL[i] = - factor * actualL[i - 1] + previousL[i - 1] + factor * previousL[i];
}
actualLaguerre = (actualL[3] + 2 * actualL[2] + 2 * actualL[1] + actualL[0]) / 6;
// Update the Fir window.
windowFIR.Add(lastValue);
if (windowFIR.IsReady)
{
actualFIR = (windowFIR[3] + 2 * windowFIR[2] + 2 * windowFIR[1] + windowFIR[0]) / 6;
}
else
{
actualFIR = lastValue;
}
}
private void CheckCross(decimal prevLaguerre, decimal actLaguerre, decimal prevFir, decimal actFIR)
{
decimal prevOscilator = prevLaguerre - prevFir;
decimal actualOscilator = actLaguerre - actFIR;
if (prevOscilator - tolerance > 0 && actualOscilator + tolerance < 0) signal = 1;
else if (prevOscilator + tolerance < 0 && actualOscilator - tolerance > 0) signal = -1;
else signal = 0;
}
}
}