| Overall Statistics |
|
Total Trades 21 Average Win 21.07% Average Loss -11.50% Compounding Annual Return -0.237% Drawdown 54.200% Expectancy 0.133 Net Profit -4.081% Sharpe Ratio 0.085 Loss Rate 60% Win Rate 40% Profit-Loss Ratio 1.83 Alpha 0.019 Beta -0.032 Annual Standard Deviation 0.195 Annual Variance 0.038 Information Ratio -0.227 Tracking Error 0.281 Treynor Ratio -0.512 Total Fees $88.91 |
/*
* 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 MomersionAlgorithm : QCAlgorithm
{
string symbol = "SPY";
MomersionIndicator SlowMomersion;
MomersionIndicator FastMomersion;
SimpleMovingAverage MomersionSMA;
public override void Initialize()
{
SetStartDate(1998, 01, 02); //Set Start Date
SetEndDate(2015, 07, 31); //Set End Date
SetCash(100000); //Set Strategy Cash
AddSecurity(SecurityType.Equity, symbol, Resolution.Daily);
SlowMomersion = new MomersionIndicator(250);
RegisterIndicator(symbol, SlowMomersion, Resolution.Daily, Field.Close);
MomersionSMA = new SimpleMovingAverage(20).Of(SlowMomersion);
FastMomersion = new MomersionIndicator(20);
RegisterIndicator(symbol, FastMomersion, Resolution.Daily, Field.Close);
}
/// <summary>
/// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
/// </summary>
/// <param name="data">Slice object keyed by symbol containing the stock data</param>
public override void OnData(Slice data)
{
#region Slow smoothed Momersion
//if (!MomersionSMA.IsReady) return;
//if (!Portfolio[symbol].HoldStock && MomersionSMA.Current.Value < 45m)
//{
// SetHoldings(symbol, 1d);
//}
//if (Portfolio[symbol].HoldStock && MomersionSMA.Current.Value > 55m)
//{
// Liquidate(symbol);
//}
#endregion
#region Fast Momersion
if (!FastMomersion.IsReady) return;
bool shortSignal = FastMomersion.Current.Value > 70;
bool longSignal = FastMomersion.Current.Value < 30;
if (Portfolio[symbol].HoldStock)
{
if ((Portfolio[symbol].IsLong && shortSignal) ||
(Portfolio[symbol].IsShort && longSignal))
Liquidate(symbol);
}
else
{
if (longSignal) SetHoldings(symbol, 1);
if (shortSignal) SetHoldings(symbol, -1);
}
#endregion
}
}
}/*
* 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.Indicators
{
/// <summary>
/// Oscillator indicator that measures momentum and mean-reversion over a specified
/// period n.
/// Source: Harris, Michael. "Momersion Indicator." Price Action Lab.,
/// 13 Aug. 2015. Web. <http://www.priceactionlab.com/Blog/2015/08/momersion-indicator/>.
/// </summary>
public class MomersionIndicator : WindowIndicator<IndicatorDataPoint>
{
/// <summary>
/// The minimum observations needed to consider the indicator ready. After that observation
/// number is reached, the indicator will continue gathering data until the full period.
/// </summary>
private int? _minPeriod;
/// <summary>
/// The final full period used to estimate the indicator.
/// </summary>
private int _fullPeriod;
/// <summary>
/// The rolling window used to store the momentum.
/// </summary>
private RollingWindow<decimal> _multipliedDiffWindow;
/// <summary>
/// Initializes a new instance of the <see cref="MomersionIndicator"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="minPeriod">The minimum period.</param>
/// <param name="fullPeriod">The full period.</param>
/// <exception cref="System.ArgumentException">The minimum period should be greater of 3.;minPeriod</exception>
public MomersionIndicator(string name, int? minPeriod, int fullPeriod)
: base(name, 3)
{
_fullPeriod = fullPeriod;
_multipliedDiffWindow = new RollingWindow<decimal>(fullPeriod);
if (minPeriod < 4)
{
throw new ArgumentException("The minimum period should be greater of 3.", "minPeriod");
}
_minPeriod = minPeriod;
}
/// <summary>
/// Initializes a new instance of the <see cref="MomersionIndicator"/> class.
/// </summary>
/// <param name="minPeriod">The minimum period.</param>
/// <param name="fullPeriod">The full period.</param>
public MomersionIndicator(int minPeriod, int fullPeriod)
: this("Momersion_" + fullPeriod, minPeriod, fullPeriod)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MomersionIndicator"/> class.
/// </summary>
/// <param name="fullPeriod">The full period.</param>
public MomersionIndicator(int fullPeriod)
: this("Momersion_" + fullPeriod, null, fullPeriod)
{
}
/// <summary>
/// Gets a flag indicating when this indicator is ready and fully initialized
/// </summary>
public override bool IsReady
{
get
{
if (_minPeriod.HasValue)
{
return _multipliedDiffWindow.Count >= _minPeriod;
}
else
{
return _multipliedDiffWindow.IsReady;
}
}
}
/// <summary>
/// Resets this indicator to its initial state
/// </summary>
public override void Reset()
{
base.Reset();
_multipliedDiffWindow.Reset();
}
/// <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)
{
int Mc = 0;
int MRc = 0;
decimal momersion;
if (window.Count >= 3) _multipliedDiffWindow.Add((window[0] - window[1]) * (window[1] - window[2]));
if (this.IsReady)
{
Mc = _multipliedDiffWindow.Count(obs => obs > 0);
MRc = _multipliedDiffWindow.Count(obs => obs < 0);
momersion = 100m * Mc / (Mc + MRc);
}
else
{
momersion = 50m;
}
Current = new IndicatorDataPoint(input.Time, momersion);
return this.Current;
}
}
}