Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
using QuantConnect.Indicators.CandlestickPatterns; namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { //**************************************************************************************************************************************** // INITIALIASE BLOCK //**************************************************************************************************************************************** public override void Initialize() { SetStartDate(2019, 10, 12); SetEndDate(2020, 01, 20); SetAccountCurrency("USD"); SetCash(100000); // Loop through our list of symbols and add them to our subscription manager foreach (var _symbol in _MySymbolList) { var _Crypto = AddCrypto(_symbol, _Res); DataDico.Add(_symbol, new SymbolData(this, _Crypto.Symbol, _Crypto.BaseCurrencySymbol)); } SetWarmUp(TimeSpan.FromDays(_WarmUpPeriod)); SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin); } //**************************************************************************************************************************************** // ONDATA BLOCK //**************************************************************************************************************************************** public override void OnData(Slice data) { //Loop through our dictionary foreach (var symbolData in DataDico.Values) { if(!data.ContainsKey(symbolData.Symbol)) { return; } //Check if algorithm is warming up and if indicators are ready, if not break if(IsWarmingUp) { return; } if(!symbolData.IsReady()) { return; } if(!symbolData.ConsolidatorFlag) { return; } symbolData.ConsolidatorFlag = false; symbolData.Price = data[symbolData.Symbol].Close; //Plot($"BB ext {symbolData.Symbol}", $"Price", symbolData.Price); //Plot($"BB ext {symbolData.Symbol}", $"Upper Band", symbolData.BBext.UpperBand); //Plot($"BB ext {symbolData.Symbol}", $"Middle Band", symbolData.BBext.MiddleBand); //Plot($"BB ext {symbolData.Symbol}", $"Lower Band", symbolData.BBext.LowerBand); Plot($"BB ext BandWidth {symbolData.Symbol}", $"BandWidth Indic", symbolData.BBext.BandWidth); Plot($"BB ext BandWidth {symbolData.Symbol}", $"BandWidth Calc", ((symbolData.BBext.UpperBand - symbolData.BBext.LowerBand) / symbolData.BBext.MiddleBand) * 100m); Plot($"BB ext BandWidth {symbolData.Symbol}", $"Upper Band", symbolData.BBofBB.UpperBand); Plot($"BB ext BandWidth {symbolData.Symbol}", $"Middle Band", symbolData.BBofBB.MiddleBand); Plot($"BB ext BandWidth {symbolData.Symbol}", $"Lower Band", symbolData.BBofBB.LowerBand); Plot($"%B {symbolData.Symbol}", $"%B Indic", symbolData.BBext.PctB); Plot($"%B {symbolData.Symbol}", $"%B Calc", (symbolData.Price - symbolData.BBext.LowerBand) / (symbolData.BBext.UpperBand - symbolData.BBext.LowerBand)); } } } }
namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { //**************************************************************************************************************************************** //USER VARIABLES //**************************************************************************************************************************************** Resolution _Res = Resolution.Hour; // Reference resolution for our custom TradeBar // Set the size of our rolling window (used among other to store historical consolidated bars) private int _WarmUpPeriod = 200; public decimal _PctRisk = 0.10m; private decimal _StopLossPct = 0.05m; //***Symbol List*** Dictionary <string, SymbolData> DataDico = new Dictionary <string, SymbolData>(); List <string> _MySymbolList = new List <string> { //"BTCUSD", "ETHUSD", //"LTCUSD", //"BCHUSD" }; private decimal _TotalEquity; } }
namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { public class SymbolData { public readonly QCAlgorithm algorithm; public readonly Symbol Symbol; public readonly string BaseSymbol; public readonly string AccountSymbol; public OrderTicket EntryOrder; public OrderTicket StopMarketOrder; public decimal EntryPrice; public decimal StopPrice; public readonly TimeSpan BarPeriod; public bool ConsolidatorFlag = false; // Flag whether a new custom candle has been fully consolidated; used to prevent ONDATA block code to be executed otherwise public readonly RollingWindow<IBaseDataBar> BarsWin; public TradeBarConsolidator Consolidator; public static int _BarPerTimeSpan = 24; // Number of block of data per custum TradeBar public readonly TimeSpan _BarPeriod = TimeSpan.FromHours(_BarPerTimeSpan); // Set the size of our custum TradeBar public readonly int _WindowSize = 2; public decimal Holding; public decimal Price; public decimal Price_P1; //***Bollinger Bands*** public BollingerBandsExtended BBext; public BollingerBands BBofBB; private int _BBPeriod = 14; private decimal _BBxStdv = 2.5m; private MovingAverageType _BB_MAtype = MovingAverageType.Simple; private int _BBofBBPeriod = 20; private decimal _BBofBBxStdv = 2.0m; //***SymbolData class constructor which initializes a new instance of SymbolData*** public SymbolData(QCAlgorithm algorithm, Symbol symbol, string baseSymbol) { this.algorithm = algorithm; Symbol = symbol; BaseSymbol = baseSymbol; AccountSymbol = symbol.ToString().Remove(0,3); Consolidator = new TradeBarConsolidator(_BarPeriod); BarsWin = new RollingWindow<IBaseDataBar>(_WindowSize); BBext = new BollingerBandsExtended(Symbol, _BBPeriod, _BBxStdv, _BB_MAtype); BBofBB = new BollingerBands(_BBofBBPeriod, _BBofBBxStdv).Of(BBext.BandWidth); Consolidator.DataConsolidated += (sender, baseData) => { // '_bar' here is our newly consolidated data var _bar = (IBaseDataBar)baseData; // Update the indicators ConsolidatorFlag = true; BarsWin.Add(_bar); BBext.Update(_bar.Time, _bar.Close); //BBofBB.Update(_bar.Time, _bar.Close); }; algorithm.SubscriptionManager.AddConsolidator(symbol, Consolidator); // Adding this consolidator to the Subscription Manager so it gets auto updates } //***Returns true if all the data in this instance is ready (indicators, rolling windows, ect...)*** public bool IsReady() { return BarsWin.IsReady && BBext.IsReady; } } } }
namespace QuantConnect { /// <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 BollingerBandsExtended : Indicator, IIndicatorWarmUpPeriodProvider { //public IndicatorDataPoint price; // { get; private set; } public SimpleMovingAverage smaPrice { get; private set; } public decimal price { get; private set; } /// <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 + k * stdDev) /// </summary> public IndicatorBase<IndicatorDataPoint> UpperBand { get; private set; } /// <summary> /// Gets the lower Bollinger band (middleBand - k * stdDev) /// </summary> public IndicatorBase<IndicatorDataPoint> LowerBand { get; private set; } /// <summary> /// Gets the Bollinger Band Width ((Upper Band - Lower Band) / Middle Band) * 100 /// </summary> public IndicatorBase<IndicatorDataPoint> BandWidth { get; private set; } /// <summary> /// Gets the Bollinger %B (Price - Lower Band)/(Upper Band - Lower Band) /// </summary> public IndicatorBase<IndicatorDataPoint> PctB { 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="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 BollingerBandsExtended(int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple) : this($"BB({period},{k})", period, k, 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 BollingerBandsExtended(string name, int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple) : base(name) { /*price = new FunctionalIndicator<IBaseDataBar>(name + "_Price", currentBar => { var value = UpdatePrice(currentBar); return value; }, isReady => price != null ); */ WarmUpPeriod = period; MovingAverageType = movingAverageType; smaPrice = new SimpleMovingAverage(name + "_smaPrice", 1); StandardDeviation = new StandardDeviation(name + "_StandardDeviation", period); MiddleBand = movingAverageType.AsIndicator(name + "_MiddleBand", period); LowerBand = MiddleBand.Minus(StandardDeviation.Times(k), name + "_LowerBand"); UpperBand = MiddleBand.Plus(StandardDeviation.Times(k), name + "_UpperBand"); BandWidth = IndicatorExtensions.Times(UpperBand.Minus(LowerBand).Over(MiddleBand, name + "_BandWidth"), 100); //BandWidth = (UpperBand.Minus(LowerBand).Over(MiddleBand).Times(100m, name + "_BandWidth"); PctB = smaPrice.Minus(LowerBand).Over(UpperBand.Minus(LowerBand), name + "_PctB"); //PctB = priceWin[0].Minus(LowerBand).Over(UpperBand.Minus(LowerBand), name + "_PctB"); //PctB = (priceWin[0] - LowerBand) / (UpperBand - LowerBand); //PctB = price.Minus(LowerBand).Over(UpperBand.Minus(LowerBand), name + "_PctB"); //PctB = (price - LowerBand) / (UpperBand - LowerBand); } /// <summary> /// Gets a flag indicating when this indicator is ready and fully initialized /// </summary> public override bool IsReady => MiddleBand.IsReady && UpperBand.IsReady && LowerBand.IsReady; /// <summary> /// Required period, in data points, for the indicator to be ready and fully initialized. /// </summary> public int WarmUpPeriod { get; } /// <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); smaPrice.Update(input); //UpdatePrice(input); //price = 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(); BandWidth.Reset(); PctB.Reset(); smaPrice.Reset(); base.Reset(); } private decimal UpdatePrice(IBaseDataBar input) { var _price = new decimal(0.0); _price = input.Close; return _price; } } }