Overall Statistics |
Total Trades 24 Average Win 0.33% Average Loss -0.62% Compounding Annual Return -1.108% Drawdown 2.600% Expectancy -0.234 Net Profit -1.751% Sharpe Ratio -0.638 Loss Rate 50% Win Rate 50% Profit-Loss Ratio 0.53 Alpha -0.013 Beta 0.02 Annual Standard Deviation 0.017 Annual Variance 0 Information Ratio -0.945 Tracking Error 0.107 Treynor Ratio -0.534 Total Fees $131.56 |
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using QuantConnect.Data; using QuantConnect.Data.Market; using QuantConnect.Data.Consolidators; using System.Collections; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect.Algorithm.Examples { /// <summary> /// Algorithm that detects over night gaps /// </summary> public class GapAlgorithm : QCAlgorithm { //parameters go here private const decimal StopLossPercent = 0.012m; private const decimal TakeProfitPercent = 0.01m;//1.0m; private const string symbol = "SPY"; private const string symbol_1 = "SPY"; // these are open/close minute bars // we'll set the open at the beginning of each day to detect gaps private TradeBar open; // we'll set the close at the end of each day private TradeBar close; private RateOfChangePercent ROCP_1_CFO ; private decimal price = 0; private decimal price_1 = 0; private decimal gapChange=0.0m; private decimal ROCP_CFO=0.0m; private RollingWindow<TradeBar> _window = new RollingWindow<TradeBar>(2); //Consolidator Class: private Consolidator _consolidator; //Set the consolidator period: private TimeSpan _barPeriod = TimeSpan.FromDays(1); public override void Initialize() { SetStartDate(2004, 01, 01); //SetStartDate(2009, 01, 01); //SetStartDate(1998, 01, 01); //SetStartDate(2002, 07, 03); //SetStartDate(2016, 01, 03); //SetEndDate(2016, 02, 01); SetEndDate(2005, 08, 01); //SetEndDate(DateTime.Now.Date.AddDays(-1)); //SetEndDate(2016, 11, 05); AddSecurity(SecurityType.Equity, symbol, Resolution.Minute); AddSecurity(SecurityType.Equity, symbol_1, Resolution.Minute); // 252 trading days in a US year ROCP_1_CFO = ROCP(symbol, 5, Resolution.Minute, Field.Close); //Setup Consolidator bar _consolidator = new Consolidator(_barPeriod); // schedule an event to fire every trading day for a security // the time rule here tells it to fire 2 minutes before SPY's market close Schedule.On(DateRules.EveryDay("SPY"), TimeRules.BeforeMarketClose("SPY", 2), () => { if(!Portfolio.Invested) return; Log("Liquidate all holdings 2 min before close."); Liquidate(); }); } public void OnData(TradeBars data) { //Date gets updated until the consolidator period and then returns true: if (_consolidator.Update(data["SPY"])) { var bar = _consolidator.Bar; _window.Add(bar); if (!_window.IsReady) return; } // populate our opening price variable if (open == null || open.Time.Date != Time.Date) { // when TryGetValue succeeds it will populate the 'open' // variable with our first minute bar of the day (at 9:31, the bar that spans from 9:30->9:31) // if it fails then 'open' will have a value of null data.TryGetValue("SPY", out open); if (open != null && close != null && open.Time.Date != close.Time.Date) { // The close of yesterday is greater than the open today. // Gap_Down = Close[1] > Open[0] //bool gapDown = close.Close > open.Open; //decimal gapChange = open.Open/close.Close - 1m; gapChange = open.Open/close.Close - 1m; } } if (!_window.IsReady) return; //Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio. var cash = Portfolio.Cash; var holdings = Portfolio[symbol_1].Quantity; price = data[symbol].Close; price_1 = data[symbol_1].Close; ROCP_CFO = price / open.Open-1.0m; if (( gapChange > 0.001m && Time.TimeOfDay == new TimeSpan(9, 40, 0) ) && ( ROCP_CFO>0.001m && price > _window[0].High ) && ((holdings < 0 || holdings == 0))) { Debug(Time + " -> GapUp: " + gapChange.ToString("0.000") ); Debug(Time + " -> CFO: " + ROCP_CFO); SetHoldings(symbol_1, 1m); } if (Time.TimeOfDay.TotalHours == 16) { // when TryGetValue succeeds it will populate the 'close' // variable with our final minute bar of the day (at $:00) // if it fails then 'close' will have a value of null data.TryGetValue("SPY", out close); } } public override void OnOrderEvent(OrderEvent orderEvent) { // Only process filled orders if (!orderEvent.Status.IsFill()) return; var orderId = orderEvent.OrderId; var orderTicket = Transactions.GetOrderTicket(orderId); var price = orderTicket.AverageFillPrice; Log(string.Format("{0} -> {1}-{2} order (#{3}) filled at ${4}", Time, orderEvent.Direction, orderTicket.OrderType, orderId, price.ToString("0.00"))); // When a buy market order is filled, create stop and limit orders if (orderEvent.Direction == OrderDirection.Buy) { var quantity = orderTicket.Quantity; // Set StopLoss order StopMarketOrder(symbol_1, -quantity, price * (1m - StopLossPercent)); // Set Profit Target LimitOrder(symbol_1, -quantity, price * (1m + TakeProfitPercent)); } // Cancel all open orders else { Transactions.CancelOpenOrders(symbol_1); } } } }
using System; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { /* * TimeSpanConsolidator Helper Routine: Assemble generic timespan bar lengths: e.g. 10 minutes: * * 1. Setup the new Consolidator class with the timespan period: * var _consolidator = new Consolidator(TimeSpan.FromMinutes(10)); * * 2. Add in the data with the update routine. It will return true when bar ready * if (_consolidator.Update(data["MSFT"])) { UseBar } */ public class Consolidator { private TradeBar _resultBar; private TradeBar _workingBar; private DateTime _start; private TimeSpan _period; //Result: public TradeBar Bar { get { return _resultBar; } } //Constructor: Set the period we'd like to scan public Consolidator(TimeSpan span) { this._period = span; this._resultBar = new TradeBar(); this._workingBar = new TradeBar(new DateTime(), "", Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0); } //Submit this bar, return true if we've started a new one. public bool Update(TradeBar newBar) { //Intialize: if (_start == new DateTime()) { _start = newBar.Time; } //While we're less than end date, keep adding to this bar: if (newBar.Time < (_start + _period)) { //Building bar: AddToBar(newBar); return false; } else { //Completed bar: start new one: _resultBar = _workingBar; //Create a new bar: _workingBar = new TradeBar(newBar.Time, newBar.Symbol, Decimal.Zero, Decimal.MinValue, Decimal.MaxValue, 0, 0); //Start of this bar: _start = newBar.Time; AddToBar(newBar); return true; } } //Add to a tradebar private void AddToBar(TradeBar newBar) { //Add this data to working bar: if (_workingBar.Time == new DateTime()) _workingBar.Time = newBar.Time; if (_workingBar.Symbol == "") _workingBar.Symbol = newBar.Symbol; if (_workingBar.Open == Decimal.Zero) _workingBar.Open = newBar.Open; if (newBar.High > _workingBar.High) _workingBar.High = newBar.High; if (newBar.Low < _workingBar.Low) _workingBar.Low = newBar.Low; _workingBar.Close = newBar.Close; _workingBar.Volume = newBar.Volume; } } }