Overall Statistics
using MathNet.Numerics;
using QuantConnectCustom;

namespace QuantConnect
{  
    
    public class IndicatorSuiteAlgorithm : QCAlgorithm
    {
    	public string pair1 = "AUDUSD";
    	RollingWindow<TradeBar> window;
    	const int WL = 13;
    	bool Long = false;
    	bool hasTraded = false;
    	//QuantConnect.Indicators.BollingerBands bb;
    	QuantConnectCustom.BollingerBands customBB;
    	MovingAverageConvergenceDivergence macd;
    	double Prev = 0;
    	
        public override void Initialize() 
        {
        	SetStartDate(2007,04,01);
            SetEndDate(2017, 07, 22);         
            
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage);
            
            SetCash(100000);
            
            window = new RollingWindow<TradeBar>(WL);
         
            AddForex(pair1, Resolution.Minute, Market.Oanda);
            //bb = BB(pair1, WL, (decimal)2.2, MovingAverageType.Simple,Resolution.Minute); //working
            
            customBB = new QuantConnectCustom.BollingerBands(pair1, WL, (decimal)2.2, (decimal)2.1,MovingAverageType.Simple); //desired
            
            //RegisterIndicator(pair1, customBB, Resolution.Minute);
         
			macd = MACD(pair1, 6, 19, 40, MovingAverageType.Exponential, Resolution.Minute);
            
           

         }
        
	    public void OnData(TradeBars data) {
	    
	    
			window.Add(data[pair1]);
			if(!window.IsReady) return;
			if(!customBB.IsReady) return;
		
			var close = (double)data[pair1].Close;
			
			
			// Exit
			if (hasTraded)
			{
				// Take profit
				if(Long && close > customBB.MiddleBand)
				{
					Liquidate();
					hasTraded = false;
					return;
				}
				else if(!Long && close < customBB.MiddleBand) 
				{
					Liquidate();
					hasTraded = false;
					return;
				}
			}	
			// Entry
			else if(!hasTraded)
			{
			if	(close < customBB.LowerBand && Prev > customBB.LowerBand && macd.Signal > 0)
				{
					SetHoldings(pair1, 1);
					Long = true;
					hasTraded = true;
					return;
				}
			else if	(close > customBB.UpperBand && Prev < customBB.UpperBand && macd.Signal < 0)
				{
					SetHoldings(pair1, -1);
					Long = false;
					hasTraded = true;
					return;
				}
			}
			
			Prev = close;
			
			Plot("BB", customBB, customBB.LowerBand, customBB.UpperBand);
			            Plot("MACD", macd, macd.Signal);
           	Plot(pair1, "Open", data[pair1].Open);

        }
        
	  
    }
}
using System;

namespace QuantConnectCustom
{
    /// <summary>
    /// This indicator creates a moving average (middle band) with an upper band and lower band
    /// fixed at k standard deviations above and below the moving average.
    /// </summary>
    public class BollingerBands : Indicator
    {
        /// <summary>
        /// Gets the type of moving average
        /// </summary>
        public MovingAverageType MovingAverageType { get; private set; }

        /// <summary>
        /// Gets the standard deviation
        /// </summary>
        public IndicatorBase<IndicatorDataPoint> StandardDeviation { get; private set; }

        /// <summary>
        /// Gets the middle bollinger band (moving average)
        /// </summary>
        public IndicatorBase<IndicatorDataPoint> MiddleBand { get; private set; }

        /// <summary>
        /// Gets the upper bollinger band (middleBand + k1 * stdDev)
        /// </summary>
        public IndicatorBase<IndicatorDataPoint> UpperBand { get; private set; }

        /// <summary>
        /// Gets the lower bollinger band (middleBand - k2 * stdDev)
        /// </summary>
        public IndicatorBase<IndicatorDataPoint> LowerBand { get; private set; }

        /// <summary>
        /// Initializes a new instance of the BollingerBands class
        /// </summary>
        /// <param name="period">The period of the standard deviation and moving average (middle band)</param>
        /// <param name="k1">The number of standard deviations specifying the distance between the middle band and upper band </param>
        /// <param name="k2">The number of standard deviations specifying the distance between the middle band and lower band </param>
        /// <param name="movingAverageType">The type of moving average to be used</param>
        public BollingerBands(int period, decimal k1, decimal k2, MovingAverageType movingAverageType = MovingAverageType.Simple)
            : this(string.Format("BB({0},{1})", period, k1, k2), period, k1, k2, movingAverageType)
        {
        }

        /// <summary>
        /// Initializes a new instance of the BollingerBands class
        /// </summary>
        /// <param name="name">The name of this indicator</param>
        /// <param name="period">The period of the standard deviation and moving average (middle band)</param>
        /// <param name="k">The number of standard deviations specifying the distance between the middle band and upper or lower bands</param>
        /// <param name="movingAverageType">The type of moving average to be used</param>
        
        public BollingerBands(String name, int period, decimal k1, decimal k2, MovingAverageType movingAverageType = MovingAverageType.Simple)
            : base(name)
        {
            MovingAverageType = movingAverageType;
            StandardDeviation = new StandardDeviation(name + "_StandardDeviation", period);
            MiddleBand = movingAverageType.AsIndicator(name + "_MiddleBand", period);
            LowerBand = MiddleBand.Minus(StandardDeviation.Times(k2), name + "_LowerBand");
            UpperBand = MiddleBand.Plus(StandardDeviation.Times(k1), name + "_UpperBand");
        }
           
        /// <summary>
        /// Gets a flag indicating when this indicator is ready and fully initialized
        /// </summary>
        public override bool IsReady
        {
            get { return MiddleBand.IsReady && UpperBand.IsReady && LowerBand.IsReady; }
        }

        /// <summary>
        /// Computes the next value of the following sub-indicators from the given state:
        /// StandardDeviation, MiddleBand, UpperBand, LowerBand
        /// </summary>
        /// <param name="input">The input given to the indicator</param>
        /// <returns>The input is returned unmodified.</returns>
        protected override decimal ComputeNextValue(IndicatorDataPoint input)
        {
            StandardDeviation.Update(input);
            MiddleBand.Update(input);
            UpperBand.Update(input);
            LowerBand.Update(input);
            return input;
        }

        /// <summary>
        /// Resets this indicator and all sub-indicators (StandardDeviation, LowerBand, MiddleBand, UpperBand)
        /// </summary>
        public override void Reset()
        {
            StandardDeviation.Reset();
            MiddleBand.Reset();
            UpperBand.Reset();
            LowerBand.Reset();
            base.Reset();
        }
    }
}