Overall Statistics
namespace QuantConnect.Algorithm.CSharp
{
    /// <summary>
    /// Basic template algorithm simply initializes the date range and cash. This is a skeleton
    /// framework you can use for designing an algorithm.
    /// </summary>
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
        private Symbol _symbol = QuantConnect.Symbol.Create("GOOGL", SecurityType.Equity, Market.USA);
        private decimal _price;
          private List<TradeBar> _TradeBar_window;
          private RollingWindow<TradeBar> RollWindow;
          private List<TradeBar> MyHistory;
          private int BackwardLookingPeriod = 7*50;
              SimpleMovingAverage _smaOnMyTimePeriod;
          private int minutesToExecute = 10;
          private int timeRoller = 0;
          private int ForwardLookingPeriod = 35;
          private Boolean maxCounter = false;//dont change this.
          private int WarmUpPeriod = 0;
          private decimal RelevantClose ;
          private decimal PurchaseClose ;
          private decimal FallFactor = 1m;
          private decimal RiseFactor = 0.7m;
          private decimal StopLossPct;
          private decimal StopLossPctAdjuster = 5m;
          private decimal maxPrice;
          private decimal deltaPCT;
          private int NumberOfMax;
          private int NumberOfMin;
     
          	private OrderTicket CurrentOrder;
    	private OrderTicket StopLoss;
    	private OrderTicket ProfitTarget;
    	
         
        private List <TradeBar> ListOfMax = new List<TradeBar>();
        private List <TradeBar> ListOfMin = new List<TradeBar>();
        
        	decimal FallAmount;
    			decimal RiseAmount;
    			decimal AverageFallPct;
    			decimal AverageRisePct;
    		


        public override void Initialize()
        {
            SetStartDate(2014, 01, 01);  //Set Start Date
            SetEndDate(2018, 01, 01);    //Set End Date
            SetCash(100000);             //Set Strategy Cash
            
            		AddEquity(_symbol, Resolution.Daily);
            	    
            //INITIALISE THE HISTORICAL PERIOD//
            
    		_TradeBar_window = new List<TradeBar>(BackwardLookingPeriod);

    
    	IEnumerable<TradeBar> slices = History(_symbol, BackwardLookingPeriod);
    
    	foreach (TradeBar bar in slices) {
    		_TradeBar_window.Add(bar);
    	}
    	//SET WARMUP
    	Debug("The last element in the initial history is: " + _TradeBar_window.Last().Time);
    		SetWarmUp(WarmUpPeriod);
    	
    	Debug("Setting warm up");
    	
    	//SCHEDULE THE ACTUAL CODE TO HAPPEN AND WHEN IT HAPPENS //
            
            	Schedule.On(   DateRules.EveryDay(_symbol), 
    	
    	TimeRules.AfterMarketOpen(_symbol,minutesToExecute), //Execute the function at the start of the day 
    	//                                                     x minutes in....
    	EveryDayOnMarketOpen     );
    	
    	}
    	
    	//DEFINE THE FUNCTION THAT YOU CALL ON THE MARKET
    	
    	
    	
    	public void EveryDayOnMarketOpen(){
    		
    		
    		ListOfMax.Clear();
    		ListOfMin.Clear();
    		maxCounter = false;
    	//	Debug("Number of things at start of day is: " + ListOfMax.Count);
    		//Debug("The time since start is: " + timeRoller);
    	
    		if(timeRoller ==527) {Debug("In period 527");
    			Debug("Tradebar window is of size: " + _TradeBar_window.Count);
    				Debug("Number of things at start of day is: " + ListOfMax.Count);
    					Debug("Number of things at start of day is: " + ListOfMin.Count);
    		}
    		timeRoller ++ ; 
    		
    		//RollWindow = new RollingWindow<TradeBar>(BackwardLookingPeriod);

    var history = History(_symbol,1,Resolution.Daily);
    
    	foreach (var i in history) {
    //		RollWindow.Add(i);//The rolling window just runs for all the periods each time it is called with IENumerable
    		
    		_TradeBar_window.Add(i);
    
    
    	}//END OF FOR EACH
    //	Debug("Tradebar window is now size: "+ _TradeBar_window.Count);
    		
    	
    		for ( var i = ForwardLookingPeriod ; i<_TradeBar_window.Count - ForwardLookingPeriod ; i++ ) {
    			
    			decimal currentClose = _TradeBar_window[i].Close;
    			_price = currentClose;
    			DateTime currentTime = _TradeBar_window[i].Time;
    			decimal maxRoller;
    			decimal minRoller;
    			//if(timeRoller == 50 ) {
    			//	Debug("At time 50 the close is: " + currentClose);
    			//	Debug("At time 50 the close is: " + currentTime);
    			//} THE DATE YOU GET DOES INCREASE AS I INCREASES
    		
           List<TradeBar> subList = _TradeBar_window.ToList().GetRange( i - ForwardLookingPeriod,ForwardLookingPeriod*2);
    
    			maxRoller = subList.Max(r => r.Close);	
    			minRoller = subList.Min(r => r.Close);
    			
    //Debug( max is: "+ maxRoller);
  //			Debug("The mins: "+ minRoller);
    	//Debug("The current is: " + currentClose);
    				
    			
    	
    			if (currentClose == maxRoller && maxCounter == false) {
    				ListOfMax.Add(_TradeBar_window[i]);
    				maxCounter = true;
    				//Debug("Max added");
    			}//End of If
    			if (currentClose == minRoller && maxCounter == true) {
    				ListOfMin.Add(_TradeBar_window[i]);
    				maxCounter = false;
    				//Debug("Min added");
    			}// End of If - can only be an odd number of min and max total if there is an extra max
    		//	if(i == _TradeBar_window.Count - ForwardLookingPeriod -1){ Debug("End of loop reached");}
    			} // end of For Loop
    			
    		
    			
    			if (   ((ListOfMax.Count + ListOfMin.Count) % 2) == 0 ) { //I.e. it is even so you have as many
    			//Mins as Max's....
    		//	Debug("Equal min and max number");
    				FallAmount = ListOfMax.Average(r=>r.Close) - ListOfMin.Average(r=>r.Close); //It is a positive number
    				//Calculate the average % fall
    				
    				List<decimal> PercentageList = new List<decimal>();
    				
    				for (var i = 0; i < ListOfMax.Count; i ++){
    				decimal PctFall =  1 - (ListOfMin[i].Close/ListOfMax[i].Close);
    				PercentageList.Add(PctFall);
    				
    				}
    				
    				AverageFallPct = PercentageList.Average(r=>r); //Positive % fall i.e. it is a positive number e.g. 10%
    				
    				RiseAmount = ((ListOfMax.Sum(r=>r.Close) - ListOfMax[1].Close) -
    				(ListOfMin.Sum(r=>r.Close) - ListOfMin[ListOfMin.Count-1].Close))/ListOfMax.Count;
    				
    					List<decimal> PercentageListRise = new List<decimal>();
    				
    				for (var i = 0; i < ListOfMax.Count -1 ; i ++) {
    					decimal PctRise = (ListOfMax[i+1].Close / ListOfMin[i].Close) - 1;
    					PercentageListRise.Add(PctRise);
    				}
    				AverageRisePct = PercentageListRise.Average(r=>r);
    				
    				
    			} else {
    		//		Debug("Unequal min and max number");
    				decimal MaxTotals = ListOfMax.Sum(r=>r.Close) - ListOfMax[ListOfMax.Count-1].Close;
    				decimal MinTotals = ListOfMin.Sum(r=>r.Close);
    				FallAmount = ((MaxTotals - MinTotals) / ListOfMax.Count);
    				
    				List<decimal> PercentageList = new List<decimal>();
    				
    				for (var i = 0; i < ListOfMax.Count -1; i ++){
    				decimal PctFall =  1 - (ListOfMin[i].Close/ListOfMax[i].Close);
    				PercentageList.Add(PctFall);
    				}
    				
    				AverageFallPct = PercentageList.Average(r=>r);
    				
    				RiseAmount = ((ListOfMax.Sum(r=>r.Close) - ListOfMax[1].Close) -
    				(ListOfMin.Sum(r=>r.Close) ))/ListOfMax.Count;
    				
    					List<decimal> PercentageListRise = new List<decimal>();
    				
    				for (var i = 0; i < ListOfMax.Count -1 ; i ++) {
    					decimal PctRise = (ListOfMax[i+1].Close / ListOfMin[i].Close) - 1;
    					PercentageListRise.Add(PctRise);
    				}
    				AverageRisePct = PercentageListRise.Average(r=>r);
    			}
    //	Debug("Finished calculating indicators");
    	
    //	Debug("The first max is: " + ListOfMax.First().Close);
    //	Debug("The first min is: " + ListOfMin.First().Close);
    
    
    //PRINT INDICATORS
    		if(timeRoller == 100){
    //			Debug("The average fall %% is: " +AverageFallPct);
    //			Debug("The average rise %% is: " +AverageRisePct);
    			
    		
    		}
    		if(timeRoller ==527){
    			Debug("The number of mins we have is: " + ListOfMin.Count);
    			Debug("The number of max we have is: " + ListOfMax.Count);
    			
    		Debug("The delta PCT is: "+ deltaPCT );
    		if(deltaPCT == 0 ) {
    			Debug("purchase close is: " + PurchaseClose);
    				Debug("relevant close is: " + RelevantClose);
    		}}
    		//DEFINE THE PURCHASE BEHAVIOUR
    		if(timeRoller == 97){
    	Debug("The last date is: " + _TradeBar_window.Last().Time);
    	Debug("The first date is: " + _TradeBar_window.First().Time);
    	Debug("The last price is: " + _TradeBar_window.Last().Close);
    	Debug("The first price is: " + _TradeBar_window.First().Close);
    	Debug("The purchase close is: " + PurchaseClose);
    		}
    		
    		if ( !Portfolio.HoldStock) {
    		
    		
    		List<TradeBar> subList2 = _TradeBar_window.ToList().GetRange( _TradeBar_window.Count - ForwardLookingPeriod,ForwardLookingPeriod);
    
    	RelevantClose = subList2.Max(r => r.Close);	
    	
    		PurchaseClose = _TradeBar_window.Last().Close;
    	
    		 deltaPCT = 1-(PurchaseClose / RelevantClose) ; //A positive number
    		
    	
    		
    	//Debug ("The delta PCt is: " + deltaPCT);
    		
    		if (deltaPCT > AverageFallPct*FallFactor) { //If you are at a min, then purchase
   // 		Debug("Purchasing at price " + PurchaseClose + "Reference price of" + RelevantClose + " and delta pct of " + deltaPCT);
    			var quantity = (int)Math.Floor(Portfolio.Cash / PurchaseClose);
    			CurrentOrder = Order(_symbol, quantity);
    			
    			ProfitTarget = LimitOrder(_symbol,-quantity, PurchaseClose*(1+ AverageRisePct*RiseFactor));
    			StopLossPct = AverageFallPct*StopLossPctAdjuster;
    	
    		
    		}
    	} else {
    		
    		ProfitTarget.Update( new UpdateOrderFields {
    			
    			LimitPrice = PurchaseClose*(1+AverageRisePct*RiseFactor)
    			
    		}	);
    		
    	//	StopLossPct = AverageFallPct*StopLossPctAdjuster;
    		
    	//	StopLoss.Update( new UpdateOrderFields {
    			
    	//		StopPrice = PurchaseClose*(1-StopLossPct)
    	//		
    //		}	);
    		
    		
    	};
    		
       
    }//END OF FUNCTION DEFINITION
    
    //Define the plotting of indicators
    public override void OnEndOfDay(){
         Plot("BB", "AvgFallPct", AverageFallPct);
     Plot("BB", "AvgRisePct", AverageRisePct);
      Plot("BB", "deltaPct", deltaPCT);
      
      Plot("MaxAndMin","max",ListOfMax.Count);
      Plot("MaxAndMin","Min",ListOfMin.Count);
      
      Plot("Time","time",timeRoller);
      
      Plot("Purchase Prices","Purchase Price", PurchaseClose);
      Plot("Purchase Prices","Last TradeBar", _TradeBar_window.Last().Close);
    }
       
        }//END OF BASIC TEMPLATE ALGORITHM
    
    
    
        
    }// END OF NAMESPACE