| 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;}
}
}
}
}