Overall Statistics |
Total Trades 76 Average Win 1.79% Average Loss -0.29% Compounding Annual Return 3.559% Drawdown 2.600% Expectancy 0.305 Net Profit 3.282% Sharpe Ratio 0.592 Loss Rate 82% Win Rate 18% Profit-Loss Ratio 6.09 Alpha 0.03 Beta -0.038 Annual Standard Deviation 0.042 Annual Variance 0.002 Information Ratio -1.412 Tracking Error 0.073 Treynor Ratio -0.669 Total Fees $0.00 |
namespace QuantConnect { public class BasicTemplateAlgorithm : QCAlgorithm { //Update identifying logic, 50 instead of 20? Make sure its pulling a leg start level from before the extreme //Possibly switch from fractal to short DCH channel public string symbol = "EURUSD"; RollingWindow<decimal> High; RollingWindow<decimal> Low; RollingWindow<decimal> SLost; RollingWindow<decimal> RGained; RollingWindow<decimal> LSUp; RollingWindow<decimal> LSDn; DateTime LUT; DateTime LDT; public decimal LongLevel; public decimal ShortLevel; RollingWindow<decimal>Price; RollingWindow<decimal>EntryPrice; public decimal DownLvl; public decimal UpLvl; public decimal EnterPrice; public decimal LongStop; public decimal LongStop1; public decimal ShortStop; DonchianChannel Extremum; public bool Entered; public bool Triggered; OrderTicket limitOrderTicket; OrderTicket targetOrderTicket; OrderTicket stopOrderTicket; QuoteBar Hourly; public decimal RR; public override void Initialize() { SetStartDate(2017, 1, 1); SetEndDate(DateTime.Now); SetCash(10000); AddForex(symbol, Resolution.Minute); High = new RollingWindow<decimal>(20); Low = new RollingWindow<decimal>(20); SLost = new RollingWindow<decimal>(5); RGained = new RollingWindow<decimal>(5); LSUp = new RollingWindow<decimal>(5); LSDn = new RollingWindow<decimal>(5); Price = new RollingWindow<decimal>(5); EntryPrice = new RollingWindow<decimal>(5); Extremum = DCH(symbol, 20, Resolution.Hour); Entered = false; var hourlyConsolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(60)); hourlyConsolidator.DataConsolidated += OnDataDaily; SubscriptionManager.AddConsolidator(symbol, hourlyConsolidator); } private void OnDataDaily(object sender, QuoteBar consolidated) { Hourly = consolidated; High.Add(Hourly.High); Low.Add(Hourly.Low); Price.Add(Hourly.Price); if(!(High.IsReady || Low.IsReady || Price.IsReady)) return; var BWFH = High[0] < High[1] && High[1] < High[2] && High[2] > High[3] && High[3] > High[4]; var BWFL = Low[0] > Low[1] && Low[1] > Low[2] && Low[2] < Low[3] && Low[3] < Low[4]; if (BWFH) { SLost.Add(High[2]); } if (BWFL) { RGained.Add(Low[2]); } if(!(SLost.IsReady || RGained.IsReady)) return; var lu = Low[10]==Extremum.LowerBand && Price[0]>RGained[1]; var ld = High[10]==Extremum.UpperBand && Price[0]<SLost[1]; if (lu) { if (RGained[0]==Low[10]) { LSUp.Add(RGained[1]); } if (RGained[0]!=Low[10]) { LSUp.Add(RGained[0]); } LUT = Time; LongStop1 = Extremum.LowerBand; } if (!LSUp.IsReady) return; if (ld) { if (SLost[0]==High[10]) { LSDn.Add(SLost[1]); } if (SLost[0]!=High[10]) { LSDn.Add(SLost[0]); } LDT = Time; ShortStop = Extremum.UpperBand; } if (!LSDn.IsReady) return; if (LDT-LUT > TimeSpan.FromMinutes(0)) { LongLevel = LSUp[0]; } if (LUT-LDT > TimeSpan.FromMinutes(0)) { ShortLevel = LSDn[0]; } var TargetDistance = ShortLevel-LongLevel; var StopDistance = LongLevel-LongStop1; RR = TargetDistance/StopDistance; } public void OnData(QuoteBars data) { if(!(High.IsReady || Low.IsReady || Price.IsReady)) return; if(!(SLost.IsReady || RGained.IsReady)) return; if (!LSUp.IsReady) return; if (!LSDn.IsReady) return; var qty = 30000; if (!Portfolio[symbol].IsLong && Entered==false && RR>1) { EntryPrice.Add(LongLevel); if (!EntryPrice.IsReady) return; if (!(EntryPrice[1]>0)) return; if (EntryPrice[0]!=EntryPrice[1]) { limitOrderTicket = LimitOrder(symbol, qty, LongLevel, "Long"); DownLvl = ShortLevel; LongStop = LongStop1; Entered = true; Triggered = false; EnterPrice = LongLevel; } } if (EnterPrice!=LongLevel && !Portfolio[symbol].IsLong) { if (Entered==true) { limitOrderTicket.Cancel(); Entered = false; } } if (Portfolio[symbol].IsLong && Triggered==false) { targetOrderTicket = LimitOrder(symbol, -Portfolio[symbol].Quantity, DownLvl, "Hit Leg Start Down at " + DownLvl); stopOrderTicket = StopMarketOrder(symbol, -Portfolio[symbol].Quantity, LongStop,"Stop Out Long at " + LongStop); Triggered = true; } if (!Portfolio[symbol].IsLong && Triggered==true) { if (targetOrderTicket.Status.IsOpen()) { targetOrderTicket.Cancel(); } Entered = false; } if (Portfolio[symbol].IsShort) { SetHoldings(symbol, 0, true, "Imbalance"); } } } }