Overall Statistics
namespace QuantConnect
{
	/*    
    For Gold Futures, this reversal algo watches for a certain number of 
    lower highs and stops in long the first time we cross a previous high
    with a stop at the lowest low of the previous 2 candles and a target 
    of X:1 Risk Reward
    
    This version is creating custom bars from minute bars
    */
	
	
	
	public class GoldBarScalperLong : QCAlgorithm
    {
    	//USER DEFINED VARIABLES
        private int startingCash = 12000;
		private int minEquity = 5000;			// account min cutoff
        private int barsDnTrigger = 3;			// # cons Down Bars trigger
        private decimal riskVar = 2;			// Risk : Reward Ratio (x : 1)
        private int candleSize = 30;			// size of new cons candles
        public decimal quantity = 1;			// # contracts to trade

        



    	//PROGRAM VARIABLES
    	public string ticker;
        public decimal price;
    	private QuoteBar lastBar;
    	public decimal entryPrice;
        public decimal stopPrice;
        public decimal targetPrice;
        public int barsDn;						// Counter for cons lower highs
        public decimal holding;
  		public decimal currentHigh;
		public decimal previousHigh;
		public decimal currentLow;
		public decimal previousLow;
		OrderTicket stopMarketOrder;
        public string baseSymbol;
        
    	private const string RootGold = Futures.Metals.Gold;
        public Symbol Gold = QuantConnect.Symbol.Create(
        					 RootGold, SecurityType.Future, Market.USA);
		private HashSet<Symbol> _futureContracts = new HashSet<Symbol>();

        
        
        
        
//////////////////////////////////////////////////////////////////////////////////////////////////        
//set the date range and filter recent contracts        
        
        
        
        public override void Initialize()					
        {
            SetStartDate(2018, 5, 1);
            SetEndDate(2018, 5, 2);
            SetCash(startingCash);
			SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
			
			
            var futureGold = AddFuture(RootGold);
            futureGold.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(182));

            SetBenchmark(x => 0);
        }

        
        
        
        
//////////////////////////////////////////////////////////////////////////////////////////////////        
// set the current traded price and create consolidated bars       
        
        
        public override void OnData(Slice data)					
        														
        {
//ERROR LINE COMMENTED FOR BACKTEST	COMPILE		price = data[futureGold].Price;

            foreach (var chain in data.FutureChains)
            {
                foreach (var contract in chain.Value)
                {
                    if (!_futureContracts.Contains(contract.Symbol))
                    {
                        _futureContracts.Add(contract.Symbol);

                        var consolidator = new QuoteBarConsolidator(TimeSpan.FromMinutes(candleSize));
                        consolidator.DataConsolidated += OnDataConsolidated;
                        SubscriptionManager.AddConsolidator(contract.Symbol, consolidator);

                        
                        ticker = contract.Symbol;
                    }
                }

            }
            
            

        }

        
        
        
        
        
//////////////////////////////////////////////////////////////////////////////////////////////////        
//actions based on new consolidated bars here        
		
    
        public void OnDataConsolidated(object sender, QuoteBar quoteBar )
        {
        	//if we have a consolidated bar completed, 
			//set current and previous candle High and Low  	
        	if(lastBar != null)	
    		{
    			
    			Log("Open: " + quoteBar.Open 
    			+ " High: " + quoteBar.High 
    			+ " Low: " + quoteBar.Low 
    			+ " Close: " + quoteBar.Close);
    			
    			
    			previousLow = currentLow;
    			currentLow = quoteBar.Low;
    			previousHigh = currentHigh;
    			currentHigh = quoteBar.High;
    			
    		}
    		
    		// if Not in trade and candle is lower than previous 
    		// then count it as a Down Bar
    		if(!Portfolio.Invested && currentHigh <= previousHigh )		
        	{
        		barsDn++;
        	}
        	
        	//otherwise, reset down bar counter
        	else
        	{
        		barsDn = 0;												
        	}
        	
        		Log("Bars Down Count: " + barsDn);
        	
        	
        	
        	
        	//if Not in trade and x down bars completed,
        	//and we have enough money
        	if(!Portfolio.Invested && barsDn >= barsDnTrigger			
        		&& Portfolio.TotalPortfolioValue > minEquity)			
        	{
        		//cancel any pending buy stops
        		if(stopMarketOrder != null)								
        		{
        			stopMarketOrder.Cancel();
        		}
        		
        		
        		//set entry, stop, and targets
        		entryPrice = currentHigh;
        		stopPrice = Math.Min(currentLow, previousLow);
        		targetPrice = entryPrice + ((entryPrice - stopPrice) * riskVar);	
        		
        		   
                //and set a new buy stop at the previous high
                stopMarketOrder = StopMarketOrder(ticker, quantity, entryPrice);	
                
                	Log("Created Buy Stop order with " + ticker + 
    					" Price: " + entryPrice + 
    					" id: " + stopMarketOrder.OrderId);
    				Log($"Stop is: {stopPrice} Target is: {targetPrice} Quantity is: {quantity}");
    		
        	}
    		
            //if we're in a trade
            if(Portfolio.Invested)										
            {
            	//Sell at target
            	if (price >= targetPrice)								
            	{
            		Liquidate();										
            		stopMarketOrder = null;
            		Log($"Took profit {ticker} at {price}");
            	}
            	
            	//or Sell at stop
            	if (price <= stopPrice)
            	{
            		Liquidate();										
            		stopMarketOrder = null;
            		Log($"Stopped out {ticker} at {price}");
            	}
            	
            }
            //finally, reset the last bar 
    		lastBar = quoteBar;											
        }
    }
}