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, 12, 12); SetEndDate(2020, 01, 13); 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(_Crypto.Symbol, _Crypto.BaseCurrencySymbol, _BarPeriod, _WindowSize)); } // Loop through the dictionary foreach (var kvp in DataDico) { var symbolData = kvp.Value; var Consolidator = new TradeBarConsolidator(_BarPeriod); ///symbolData.W_Bottom = new WBottom(_Wbottom_Period, _Wbottom_MinBarInterval); // UNCOMMENT THIS LINES AND IT WILL BREAK ///RegisterIndicator(symbolData.Symbol, symbolData.W_Bottom, Consolidator); // UNCOMMENT THIS LINES AND IT WILL BREAK Consolidator.DataConsolidated += (sender, baseData) => { // '_bar' here is our newly consolidated data var _bar = (IBaseDataBar)baseData; // Update the indicators symbolData.ConsolidatorFlag = true; symbolData.BarsWin.Add(_bar); ///symbolData.W_Bottom.wBottom.BarsWin.Add(_bar); // UNCOMMENT THIS LINES AND IT WILL BREAK }; Consolidator.DataConsolidated += ConsolidatorHandler; // Call ConsolidatorHandeler custom method SubscriptionManager.AddConsolidator(symbolData.Symbol, Consolidator); // Adding this consolidator to the Subscription Manager so it gets auto updates } SetWarmUp(TimeSpan.FromDays(_WarmUpPeriod)); SetBrokerageModel(BrokerageName.Bitfinex, AccountType.Margin); } private void ConsolidatorHandler(object sender, IBaseDataBar _Consolidated) { // This method will be called every time a new consolidated bar is ready //Log($"{_Consolidated.EndTime:o} {_BarPerTimeSpan}-hour bar consolidated."); } //**************************************************************************************************************************************** // 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; //Log($"O: {data[symbolData.Symbol].Open}, H: {data[symbolData.Symbol].High}, L: {data[symbolData.Symbol].Low}, C: {data[symbolData.Symbol].Close}"); //Plot($"W Bottom {symbolData.Symbol}",$"W Bottom({_Wbottom_Period})", symbolData.W_Bottom); //Log($"W Bottom | B_Low01 = {symbolData.W_Bottom.wBottom.B_Low01value}"); } } } }
namespace QuantConnect.Algorithm.CSharp { public partial class TestAlgo : QCAlgorithm { //**************************************************************************************************************************************** //USER VARIABLES //**************************************************************************************************************************************** Resolution _Res = Resolution.Hour; // Reference resolution for our custom TradeBar 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; // 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; private int _Wbottom_Period = 20; private int _Wbottom_MinBarInterval = 3; //***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 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 decimal Holding; public decimal Price; public decimal Price_P1; //***Indicator declaration*** ///public WBottom W_Bottom; //***SymbolData class constructor which initializes a new instance of SymbolData*** public SymbolData(Symbol symbol, string baseSymbol, TimeSpan barPeriod, int _windowSize) { Symbol = symbol; BaseSymbol = baseSymbol; AccountSymbol = symbol.ToString().Remove(0,3); BarPeriod = barPeriod; BarsWin = new RollingWindow<IBaseDataBar>(_windowSize); } //***Returns true if all the data in this instance is ready (indicators, rolling windows, ect...)*** public bool IsReady { get {return true;} //W_Bottom.IsReady;} } } } }
using System.Linq; namespace QuantConnect { /// <summary> /// Indicator that keeps track of the daily running volume /// </summary> public class WBottom : BarIndicator, IIndicatorWarmUpPeriodProvider { public WBottomClass wBottom; private int wBottomFlag = 0; // W Bottom Flag: 0 = false / 1 = true /// Gets a flag indicating when this indicator is ready and fully initialized public override bool IsReady => wBottom.IsReady; /// Required period, in data points, for the indicator to be ready and fully initialized. public int WarmUpPeriod { get; } /// Initializes a new instance of the "WBottom" class public WBottom(int period, int interval = 3) : this($"WBottom({period})", period, interval) { } /// Initializes a new instance of the "WBottom" class /// <param name="name">The name of this indicaor</param> public WBottom(string name, int period, int interval) : base(name) { wBottom = new WBottomClass(period, interval); WarmUpPeriod = 1 + period; } /// Computes the next value of this indicator from the given state /// "input" = The input given to the indicator /// Returns a new value for this indicator protected override decimal ComputeNextValue(IBaseDataBar input) { //wBottom.BarsWin.Update(input); ///Step 1: Identify first Low (B) wBottom.B_Low01value = wBottom.BarsWin[wBottom._Period/2 -1].Low; wBottom.B_Low01index = wBottom._Period/2 -1; for(int i = wBottom.B_Low01index; i <= wBottom._Period -1 ; i++) { decimal number = wBottom.BarsWin[i].Low; if(number < wBottom.B_Low01value) { wBottom.B_Low01value = number; wBottom.B_Low01index = i; } } ///Step 2: Identify second Low (D) wBottom.D_Low02value = wBottom.BarsWin[0].Low; wBottom.D_Low02index = 0; for(int i = 0; i < wBottom.B_Low01index - wBottom._Interval ; i++) { decimal number = wBottom.BarsWin[i].Low; if(number < wBottom.D_Low02value) { wBottom.D_Low02value = number; wBottom.D_Low02index = i; } } ///Step 3: Identify first High (A) wBottom.A_High01value = wBottom.BarsWin[wBottom.B_Low01index +1].High; wBottom.A_High01index = wBottom.B_Low01index +1; for(int i = wBottom.A_High01index; i <= wBottom._Period -1 ; i++) { decimal number = wBottom.BarsWin[i].High; if(number > wBottom.A_High01value) { wBottom.A_High01value = number; wBottom.A_High01index = i; } } ///Step 4: Identify second High (C) wBottom.C_High02value = wBottom.BarsWin[wBottom.D_Low02index +1].High; wBottom.C_High02index = wBottom.D_Low02index +1; for(int i = wBottom.C_High02index; i <= wBottom.B_Low01index -1 ; i++) { decimal number = wBottom.BarsWin[i].High; if(number > wBottom.C_High02value) { wBottom.C_High02value = number; wBottom.C_High02index = i; } } ///Step 5: Identify third High (E) wBottom.E_High03value = wBottom.BarsWin[0].High; wBottom.E_High03index = 0; for(int i = 0; i <= wBottom.D_Low02index -1 ; i++) { decimal number = wBottom.BarsWin[i].High; if(number > wBottom.E_High03value) { wBottom.E_High03value = number; wBottom.E_High03index = i; } } if(wBottom.B_Low01index - wBottom.A_High01index <= wBottom._Interval || wBottom.C_High02index - wBottom.B_Low01index <= wBottom._Interval || wBottom.D_Low02index - wBottom.C_High02index <= wBottom._Interval || wBottom.E_High03index - wBottom.D_Low02index <= wBottom._Interval) {wBottomFlag = 0;} else {wBottomFlag = 1;} return wBottomFlag; } public class WBottomClass { public int _Period; public int _Interval; public decimal A_High01value; public decimal C_High02value; public decimal E_High03value; public decimal B_Low01value; public decimal D_Low02value; public int A_High01index; public int C_High02index; public int E_High03index; public int B_Low01index; public int D_Low02index; public readonly RollingWindow<IBaseDataBar> BarsWin; //***WBottomClass constructor which initializes a new instance of the class*** public WBottomClass(int period, int interval) { BarsWin = new RollingWindow<IBaseDataBar>(period); _Period = period; _Interval = interval; } public bool IsReady { get {return BarsWin.IsReady;} } } } }