Overall Statistics |
Total Trades 26 Average Win 1.11% Average Loss -0.32% Annual Return 1.003% Drawdown 2.300% Expectancy 1.064 Net Profit 9.198% Sharpe Ratio 0.7 Loss Rate 54% Win Rate 46% Profit-Loss Ratio 3.47 Trade Frequency Weekly trades |
-no value-
using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Linq; using QuantConnect; using QuantConnect.Models; namespace QuantConnect.Indicator { public class ExponentialMovingAverage : QCAlgorithm { private int _period; private decimal _ema; private int _samples; private bool flag; private Queue <decimal>_data = new Queue <decimal> (); /******************************************************** * CLASS PUBLIC VARIABLES *********************************************************/ //Current value of the EMA. public decimal EMA { get{ return _ema;} } //Track the number of samples: public int Samples { get { return _samples; } } //The EMA constant multiplier: public decimal GetExpConst { get{ return (decimal) 2/(_period +1);} } //We've got sufficient data samples to know its the EMA. public bool Ready { get { return _data.Count >= _period; } } /******************************************************** * CLASS CONSTRUCTOR *********************************************************/ /// <summary> /// Initialise the Algorithm /// </summary> public ExponentialMovingAverage(int period) { _period = period; _ema = 0; flag = false; } /******************************************************** * CLASS METHODS *********************************************************/ /// <summary> /// Calculate the exponential moving average /// </summary> public decimal AddSample(decimal quote) { _data.Enqueue(quote); _samples++; if(_data.Count < _period) { return _data.Average(); } else { if(!flag) { _ema = _data.Average(); flag = true; } else { _ema = (1-GetExpConst) * _ema +GetExpConst * quote; } } return _ema; } } }
using System; using System.Collections; using System.Collections.Generic; using System.Text; using QuantConnect.Indicator; namespace QuantConnect { using QuantConnect.Securities; using QuantConnect.Models; //50-10 Day EMA Cross: with 1% Safety Margin and public class QCUMovingAverageCross : QCAlgorithm, IAlgorithm { //Define required variables: int quantity = 0; decimal price = 0; decimal tolerance = 0.001m; //0.1% safety margin in prices to avoid bouncing. string symbol = "SPY"; DateTime sampledToday = DateTime.Now; //Set up the EMA Class: ExponentialMovingAverage emaShort = new ExponentialMovingAverage(10); ExponentialMovingAverage emaLong = new ExponentialMovingAverage(50); //Initialize the data and resolution you require for your strategy: public override void Initialize() { SetStartDate(2008, 01, 01); SetEndDate(2014, 04, 30); SetCash(25000); AddSecurity(SecurityType.Equity, symbol, Resolution.Minute); SetRunMode(RunMode.Series); } //Handle TradeBar Events: a TradeBar occurs on every time-interval public override void OnTradeBar(Dictionary<string, TradeBar> data) { //One data point per day: if (sampledToday.Date == data[symbol].Time.Date) return; //Only take one data point per day (opening price) price = Securities[symbol].Open; sampledToday = data[symbol].Time; //Push values into EMA. emaShort.AddSample(price); emaLong.AddSample(price); //Wait until EMA's are ready: if (!emaShort.Ready || !emaLong.Ready) return; //Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio. decimal cash = Portfolio.Cash; int holdings = Portfolio[symbol].Quantity; quantity = Convert.ToInt32((cash * 0.1m) / price); if (holdings > 0 || holdings == 0) { //If we're long, or flat: check if EMA crossed negative: and crossed outside our safety margin: if ((emaShort.EMA * (1+tolerance)) < emaLong.EMA) { //Now go short: Short-EMA signals a negative turn: reverse holdings Order(symbol, -(holdings + quantity)); Log(Time.ToShortDateString() + " > Go Short > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " + emaShort.Samples); } } else if (holdings < 0 || holdings == 0) { //If we're short, or flat: check if EMA crossed positive: and crossed outside our safety margin: if ((emaShort.EMA * (1 - tolerance)) > emaLong.EMA ) { //Now go long: Short-EMA crossed above long-EMA by sufficient margin Order(symbol, Math.Abs(holdings) + quantity); Log(Time.ToShortDateString() + "> Go Long > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString() + " Samples: " + emaShort.Samples); } } } } }