Overall Statistics |
Total Trades 59 Average Win 0.88% Average Loss -0.37% Compounding Annual Return 60.396% Drawdown 4.800% Expectancy 0.291 Net Profit 11.113% Sharpe Ratio 2.56 Loss Rate 62% Win Rate 38% Profit-Loss Ratio 2.40 Alpha 0.167 Beta 0.8 Annual Standard Deviation 0.13 Annual Variance 0.017 Information Ratio 1.01 Tracking Error 0.124 Treynor Ratio 0.415 Total Fees $109.15 |
using System; using System.Linq; using QuantConnect.Data; using QuantConnect.Orders; using QuantConnect.Securities; using QuantConnect.Securities.Future; using QuantConnect.Indicators; namespace QuantConnect.Algorithm.CSharp { /// <summary> /// EMA cross with SP500 E-mini futures /// In this example, we demonstrate how to trade futures contracts using /// a equity to generate the trading signals /// It also shows how you can prefilter contracts easily based on expirations. /// It also shows how you can inspect the futures chain to pick a specific contract to trade. /// </summary> /// <meta name="tag" content="using data" /> /// <meta name="tag" content="futures" /> /// <meta name="tag" content="indicators" /> /// <meta name="tag" content="strategy example" /> public class FuturesMomentumAlgorithm : QCAlgorithm { private const decimal _tolerance = 0.001m; private ExponentialMovingAverage _fast; private ExponentialMovingAverage _slow; private SimpleMovingAverage[] _ribbon; private RelativeStrengthIndex _rsi; private AroonOscillator _aroon; private bool _long = true; private decimal _price; private string _symbol = "SPY"; private bool _orderHold = true; private bool _tradeShort = true; private bool _tradeLong = true; private SecurityPortfolioManager _previousPortfolio = null; private decimal _vix; public bool IsReady { get { return _fast.IsReady && _slow.IsReady; } } public bool IsUpTrend { get { return IsReady && _fast > _slow * (1 + _tolerance); } } public bool IsDownTrend { get { return IsReady && _fast < _slow * (1 + _tolerance); } } public override void Initialize() { SetStartDate(2017, 10, 1); SetEndDate(DateTime.Now); SetCash(40000); SetWarmUp(Math.Max(24, 48)); //VIX volatility //AddData<Quandl>("CBOE/VIX"); AddData<QuandlVix>("CBOE/VIX"); // Adds SPY to be used in our EMA indicators AddSecurity(SecurityType.Equity, _symbol, Resolution.Minute); var equity = AddEquity(_symbol, Resolution.Minute); _fast = EMA(equity.Symbol, 24, Resolution.Hour); _slow = EMA(equity.Symbol, 5, Resolution.Daily); _aroon = AROON(_symbol, 24, Resolution.Hour); var ribbonCount = 8; var ribbonInterval = 15; _ribbon = Enumerable.Range(0, ribbonCount).Select(x => SMA(_symbol, (x + 1)*ribbonInterval, Resolution.Daily)).ToArray(); _rsi = RSI(_symbol, 14, MovingAverageType.Simple, Resolution.Daily); // Adds the future that will be traded and // set our expiry filter for this futures chain var future = AddFuture(Futures.Indices.SP500EMini); future.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(182)); var benchmark = AddEquity(_symbol); SetBenchmark(benchmark.Symbol); Securities[_symbol].TransactionModel = new ConstantFeeTransactionModel(1); //Brokerage model and account type: SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin); } public bool IsExecuteBeforeMarketClosure { get { var exchange = Securities[_symbol].Exchange; bool isMarketOpen = exchange.DateTimeIsOpen(Time); //bool isExecuteBeforeMarketClosure = isMarketOpen // && exchange.DateTimeIsOpen(Time.AddMinutes(10)) // && !exchange.DateTimeIsOpen(Time.AddMinutes(15)); //return isExecuteBeforeMarketClosure; return isMarketOpen; } } public void OnData(Quandl data) { if (data.Symbol=="CBOE/VIX") { _vix=data.Value; Plot("Data-vix", "VIX", _vix); } } public void OnData(TradeBars data) { if(data.ContainsKey(_symbol)) { _price = data[_symbol].Close; } if (!_slow.IsReady) return; //avoid random start if(_orderHold && Math.Abs(_fast - _slow) >= 0.05m) { _orderHold = false; Log("OrderHold = false"); Plot("Data", "Price", _price); Plot("Data", _fast, _slow); } } public override void OnData(Slice slice) { if (!_slow.IsReady || !_rsi.IsReady) return; if(_orderHold) return; if(_tradeLong) { if (!Portfolio.Invested && IsUpTrend) { foreach (var chain in slice.FutureChains) { // find the front contract expiring no earlier than in 90 days var contract = ( from futuresContract in chain.Value.OrderBy(x => x.Expiry) where futuresContract.Expiry > Time.Date.AddDays(90) select futuresContract ).FirstOrDefault(); // if found, trade it if (contract != null) { if(IsExecuteBeforeMarketClosure) { MarketOrder(contract.Symbol, 1); _long = true; } } } } if (Portfolio.Invested && _long && IsDownTrend) { if(IsExecuteBeforeMarketClosure) { Liquidate(); } } } if(_tradeShort) { if (!Portfolio.Invested && IsDownTrend) { foreach (var chain in slice.FutureChains) { // find the front contract expiring no earlier than in 90 days var contract = ( from futuresContract in chain.Value.OrderBy(x => x.Expiry) where futuresContract.Expiry > Time.Date.AddDays(90) select futuresContract ).FirstOrDefault(); // if found, trade it if (contract != null) { if(IsExecuteBeforeMarketClosure) { MarketOrder(contract.Symbol, -1); _long = false; } } } } if (Portfolio.Invested && !_long && IsUpTrend) { if(IsExecuteBeforeMarketClosure) { Liquidate(); } } } if(_previousPortfolio != null) { //Dictionary<Symbol, SecurityHolding> foreach (var holding in Portfolio.Values) { if(holding != null) { foreach (var previousHolding in _previousPortfolio.Values) { if(previousHolding != null) { if(holding.Quantity != previousHolding.Quantity)// || // futureHolding.IsLong != previousFutureHolding.IsLong || //futureHolding.IsShort != previousFutureHolding.IsShort) { Log("Holdings Changed"); Plot("Indicator Signal", "Trend", IsDownTrend ? -1 : IsUpTrend ? 1 : 0); Plot("Holdings", "Qty", holding.Quantity); Plot("Data", "Price", _price); Plot("Data", _fast, _slow); } } } } } } _previousPortfolio = Portfolio; } public override void OnEndOfDay() { if (!_slow.IsReady || !_rsi.IsReady) return; //Plot("EMA", "Price", _price); //Plot("EMA", _fast, _slow); //Plot("Ribbon", _ribbon); //Plot("RSI", _rsi); //Plot("AROON", _aroon.AroonUp, _aroon.AroonDown); //var price = Identity(_symbol); //PlotIndicator(_symbol, _price, _fast, _slow); } public override void OnOrderEvent(OrderEvent orderEvent) { Log(orderEvent.ToString()); } } public class QuandlVix : Quandl { public QuandlVix() : base(valueColumnName: "vix close") { } } }