| 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 class TestMAcrossCount : QCAlgorithm
{
//USER VARIABLES
Resolution _Res = Resolution.Daily; // Reference resolution for our custom TradeBar
public static int _BarPerTimeSpan = 1; // Number of block of data per custum TradeBar
public readonly TimeSpan _BarPeriod = TimeSpan.FromHours(_BarPerTimeSpan); // Set the size of our custum TradeBar
private int _EMA_Period = 20;
// PROGRAM VARIABLES
Dictionary <string, SymbolData> _DataDico = new Dictionary <string, SymbolData>();
List <string> _MySymbolList = new List <string>
{
"BTCUSD",
//"ETHUSD",
//"LTCUSD",
//"BCHUSD"
};
//****************************************************************************************************************************************
// INITIALIASE BLOCK
//****************************************************************************************************************************************
public override void Initialize()
{
SetStartDate(2019, 1, 1);
SetEndDate(2019, 3, 30);
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));
}
// Loop through the dictionary
foreach (var _key in _DataDico) // Loop going through each entry in our data dictionary
{
var _symbolData = _key.Value; // Assign each value associated with the keywords to a new variable name '_symbolData'
var _Consolidator = new TradeBarConsolidator(_BarPeriod);
_symbolData._EMA = new ExponentialMovingAverage(_symbolData._Symbol, _EMA_Period);
_Consolidator.DataConsolidated += (sender, _baseData) =>
{
// '_bar' here is our newly consolidated data
var _bar = (IBaseDataBar)_baseData;
// Update the indicators
_symbolData._EMA.Update(_bar.Time, _bar.Close);
_symbolData._ConsolidatorFlag = true;
};
_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(200));
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; }
_symbolData._Price_P1 = _symbolData._Price; //Store previous period price
_symbolData._Price = data[_symbolData._Symbol].Close;
//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;
//Work out MA cros count
_symbolData._EMA_P1 = _symbolData._EMA_P0;
_symbolData._EMA_P0 = _symbolData._EMA.Current;
if((_symbolData._Price > _symbolData._EMA_P0 && _symbolData._Price_P1 <= _symbolData._EMA_P1)
|| (_symbolData._Price < _symbolData._EMA_P0 && _symbolData._Price_P1 >= _symbolData._EMA_P1))
{_symbolData._EMA_CrossCount = 0;}
else {_symbolData._EMA_CrossCount++;}
Plot($"Price {_symbolData._Symbol}",$"Price", _symbolData._Price);
Plot($"Price {_symbolData._Symbol}",$"EMA({_EMA_Period})", _symbolData._EMA_P0);
Plot($"EMA cross count {_symbolData._Symbol}",$"EMA cross count", _symbolData._EMA_CrossCount);
}
}
//****************************************************************************************************************************************
//CUSTOM CLASS SymbolData
//****************************************************************************************************************************************
public class SymbolData
{
public readonly Symbol _Symbol;
public readonly string _BaseSymbol;
public readonly string _AccountSymbol;
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 int _EMA_CrossCount;
public decimal _Holding;
public decimal _Price;
public decimal _Price_P1;
//***Indicator declaration***
public ExponentialMovingAverage _EMA;
public decimal _EMA_P0;
public decimal _EMA_P1;
//***SymbolData class constructor which initializes a new instance of SymbolData***
public SymbolData(Symbol _symbol, string _baseSymbol, TimeSpan _barPeriod)
{
_Symbol = _symbol;
_BaseSymbol = _baseSymbol;
_AccountSymbol = _symbol.ToString().Remove(0,3);
_BarPeriod = _barPeriod;
}
//***Returns true if all the data in this instance is ready (indicators, rolling windows, ect...)***
public bool IsReady
{
get {return _EMA.IsReady;}
}
}
}
}