Overall Statistics
Total Trades
59
Average Win
1.89%
Average Loss
-1.01%
Compounding Annual Return
0.088%
Drawdown
13.400%
Expectancy
-0.009
Net Profit
0.538%
Sharpe Ratio
0.038
Loss Rate
66%
Win Rate
34%
Profit-Loss Ratio
1.88
Alpha
0.009
Beta
0.247
Annual Standard Deviation
0.044
Annual Variance
0.002
Information Ratio
0.4
Tracking Error
0.078
Treynor Ratio
0.007
Total Fees
$0.00
using System;
using System.Linq;
using QuantConnect.Indicators;
using QuantConnect.Models;
using MathNet.Numerics.Statistics;

namespace QuantConnect
{
	// https://www.quantconnect.com/tutorials/dynamic-breakout-ii-strategy/
    public class DynamicBreakoutAlgorithm : QCAlgorithm
    {
    	IEnumerable<Slice> slices;
		IEnumerable<decimal> close;
		IEnumerable<decimal> high;
		IEnumerable<decimal> low;
			
        BollingerBands Bolband;
        private const string Symbol = "EURUSD";
        //private const string Symbol = "GBPUSD";
        private int numdays = 20;
        private decimal buypoint, sellpoint, longLiqPoint, shortLiqPoint, yesterdayclose = 0;
        
        public override void Initialize()
        {
            SetStartDate(2010,1,15);
        	SetEndDate(2016,2,15);
        	SetCash(100000);
            AddForex(Symbol, Resolution.Hour);
            SetBenchmark(Symbol);

        	const int ceiling = 60, floor = 20;
            double[] closes, highs, lows, historyclose;
        	double todayvol, yesterdayvol, deltavol;
			Schedule.On(DateRules.EveryDay(Symbol), TimeRules.BeforeMarketClose(Symbol, 1), () =>
			{
				slices = History(31, Resolution.Daily);
		        close = slices.Get(Symbol, Field.Close);
		        closes = close.ToDoubleArray();
				todayvol = closes.Skip(1).StandardDeviation();
				yesterdayvol = closes.Take(30).StandardDeviation();
				deltavol = (todayvol - yesterdayvol) / todayvol;
        		numdays = (int)(Math.Round(numdays * (1 + deltavol)));
        		numdays = Math.Max(Math.Min(numdays, ceiling), floor);
        		
        		Bolband = BB(Symbol, numdays, 2, MovingAverageType.Simple, Resolution.Daily);
		        slices = History(numdays, Resolution.Daily);
		        
		        high = slices.Get(Symbol, Field.High);
		        highs = high.ToDoubleArray();
				low = slices.Get(Symbol, Field.Low);
				lows = low.ToDoubleArray();
		        buypoint = (decimal)highs.Max();
		        sellpoint = (decimal)lows.Min();
		        
		        close = slices.Get(Symbol, Field.Close);
				historyclose = close.ToDoubleArray();
		        longLiqPoint = (decimal)(historyclose.Mean());
		        shortLiqPoint = (decimal)(historyclose.Mean());
		        yesterdayclose = (decimal)historyclose.Skip(numdays-2).Take(1).Mean();
			});
        }
		
        private decimal price, holdings;
        public void OnData(TradeBars data)
        {
        	// wait for our BollingerBand to fully initialize
        	if (yesterdayclose == 0) 
        	{
        		return;
        	}
            holdings = Portfolio[Symbol].Quantity;
  			price = Portfolio[Symbol].Price;
            if (yesterdayclose > Bolband.UpperBand.Current.Value && price >= buypoint) 
            {	
	            SetHoldings(Symbol, 1);
            }
            else if (yesterdayclose < Bolband.LowerBand.Current.Value && price <= sellpoint) 
            {
            	SetHoldings(Symbol, -1);
            }
            
            if (holdings > 0 && price <= longLiqPoint)
            {	
	            Liquidate(Symbol);
            }
            else if (holdings < 0 && price >= shortLiqPoint)
            {
            	Liquidate(Symbol);
            }
            Log(yesterdayclose + " # of day " + numdays);
        }
    }
}