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 = "BTCUSD"; //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); AddCrypto(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); } } }

 

Author