| Overall Statistics |
|
Total Trades 136 Average Win 1.23% Average Loss -0.98% Compounding Annual Return -7.541% Drawdown 30.800% Expectancy -0.310 Net Profit -18.323% Sharpe Ratio -0.567 Loss Rate 69% Win Rate 31% Profit-Loss Ratio 1.25 Alpha -0.176 Beta 0.6 Annual Standard Deviation 0.124 Annual Variance 0.015 Information Ratio -2.175 Tracking Error 0.114 Treynor Ratio -0.118 Total Fees $141.28 |
namespace QuantConnect
{
public enum Decision { Long, Short, Neutral };
// quick demo of the RollingWindow<T> class
public class RollingWindowAlgorithm : QCAlgorithm
{
// keep 5 of the last data points, max index of 4
public RollingWindow<TradeBar> History = new RollingWindow<TradeBar>(5);
// we want 3 decisions in a row to be the same
public RollingWindow<Decision> RecentDecisions = new RollingWindow<Decision>(2);
// define some indicators
public ExponentialMovingAverage Fast;
public ExponentialMovingAverage Slow;
// these will hold the history of our indicators
public RollingWindow<decimal> FastEmaHistory = new RollingWindow<decimal>(10);
public RollingWindow<decimal> SlowEmaHistory = new RollingWindow<decimal>(10);
//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
//Start and End Date range for the backtest:
SetStartDate(2013, 1, 1);
SetEndDate(DateTime.Now.Date.AddDays(-1));
//Cash allocation
SetCash(25000);
//Add as many securities as you like. All the data will be passed into the event handler:
AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily);
Fast = EMA("SPY", 10);
Slow = EMA("SPY", 30);
// plot the fast ema, the slow ema, and the close price
PlotIndicator("SPY", Fast, Slow, Identity("SPY"));
}
decimal tolerance = 0.005m;
//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
public void OnData(TradeBars data)
{
// Add the data from this time step to our rolling windows
History.Add(data["SPY"]);
FastEmaHistory.Add(Fast);
SlowEmaHistory.Add(Slow);
// wait for our history to be ready
if (!History.IsReady) return;
//if ( close of the previous bar > low of the bar that occurred 2 bars ago)
//if (History[1].Close > History[2].Close)
// you can access the rolling window using indexing,
// History[0] is the piece of data we just put in
// History[1] is the piece of data we put in last time step
// History[n] is the piece of data we put in n time steps ago
//if (10 period EMA > 30 period EMA for 3 bars in a row)
if (Fast > Slow*(1+tolerance))
{
RecentDecisions.Add(Decision.Long);
}
else if (Fast < Slow*(1-tolerance))
{
RecentDecisions.Add(Decision.Short);
}
else
{
RecentDecisions.Add(Decision.Neutral);
}
// determine if all the decisions are the same by dropping
// them into a hash, if they're all unique then th count is 1
var hash = RecentDecisions.ToHashSet();
if (hash.Count != 1)
{
// inconclusive decisions
}
else
{
// grab the only decision
var decision = hash.Single();
decimal percentage = 0;
switch (decision)
{
case Decision.Long:
percentage = 1.5m;
break;
case Decision.Short:
percentage = -1.5m;
break;
case Decision.Neutral:
percentage = 0m;
break;
}
SetHoldings("SPY", percentage);
}
}
}
}