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); } } } }