Overall Statistics |
Total Trades 2246 Average Win 0.25% Average Loss -0.19% Compounding Annual Return 5.577% Drawdown 6.300% Expectancy 0.112 Net Profit 26.535% Sharpe Ratio 0.974 Loss Rate 52% Win Rate 48% Profit-Loss Ratio 1.32 Alpha 0.049 Beta -0.036 Annual Standard Deviation 0.047 Annual Variance 0.002 Information Ratio -0.462 Tracking Error 0.126 Treynor Ratio -1.269 Total Fees $2246.00 |
using System; using System.Linq; using QuantConnect.Indicators; using QuantConnect.Models; namespace QuantConnect.Algorithm.Examples { /// <summary> /// /// QuantConnect University: EMA + SMA Cross /// /// In this example we look at the canonical 20/50 day moving average cross. This algorithm /// will go long when the 20 crosses above the 50 and will liquidate when the 20 crosses /// back below the 50. // -------VATS CHANGES ----------- // 1) Intraday - 30 min chart // 2) 1/65 period SMA cross // // -------VATS CHANGES ----------- /// </summary> public class QCUMovingAverageCross : QCAlgorithm { private const string Symbol = "UVXY"; private SimpleMovingAverage fast; private SimpleMovingAverage slow; TradeBar _symbolMinutes; public override void Initialize() { SetStartDate(2013, 1, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); SetCash(10000); AddSecurity(SecurityType.Equity, Symbol, Resolution.Minute); Securities[Symbol].SetDataNormalizationMode(DataNormalizationMode.Raw); // define our daily trade bar consolidator. we can access the daily bar // from the DataConsolidated events, this consolidator can only be used // for a single symbol! var minConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5)); // attach our event handler. the event handler is a function that will be called each time we produce // a new consolidated piece of data. minConsolidator.DataConsolidated += OnThirtyMinutes; // this call adds our daily consolidator to the manager to receive updates from the engine SubscriptionManager.AddConsolidator(Symbol, minConsolidator); int fastPeriod = 20; int slowPeriod = 50; fast = new SimpleMovingAverage(Symbol + "_SMA_" + fastPeriod, fastPeriod); slow = new SimpleMovingAverage(Symbol + "_SMA_" + slowPeriod, slowPeriod); // we need to manually register these indicators for automatic updates RegisterIndicator(Symbol, fast, minConsolidator); RegisterIndicator(Symbol, slow, minConsolidator); Schedule.On(DateRules.EveryDay(Symbol), TimeRules.BeforeMarketClose(Symbol, 10), () => { Liquidate(); }); } private void OnThirtyMinutes(object sender, TradeBar consolidated) { _symbolMinutes = consolidated; //Log(consolidated.Time.ToString("o") + " >> " + Symbol + ">> LONG >> 100 >> " + Portfolio[Symbol].Quantity); // if you want code to run every five minutes then you can run it inside of here if (!slow.IsReady) return; // only once per day // Commented the following line to simulate intraday - Vats //if (previous.Date == data.Time.Date) return; if (Time.Hour <= 9 || Time.Hour > 14) return; const decimal tolerance = 0.00001m; var holdings = Portfolio[Symbol].Quantity; if (!Portfolio.HoldStock) { // if the slow is greater than the fast, we'll go short if (slow > fast * (1 + tolerance)) { Log("SELL >> " + Securities[Symbol].Price); Order(Symbol, -1000/Securities[Symbol].Price); } } // Vats' changes - Long here . We only want to liquidate if we're currently short // if the slow is less than the fast we'll liquidate our short if (Portfolio.HoldStock && slow < fast) { Log("BUY >> " + Securities[Symbol].Price); Liquidate(Symbol); } //Plot(Symbol, "Price", data[Symbol].Price); //Plot(Symbol, fast, slow); //previous = data.Time; } private DateTime previous; public void OnData(TradeBars data) { } } }