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");
        	}
        }
    }
}