| Overall Statistics |
|
Total Trades 468 Average Win 4.99% Average Loss -1.56% Compounding Annual Return 648.350% Drawdown 22.200% Expectancy 0.791 Net Profit 1128.959% Sharpe Ratio 2.475 Loss Rate 57% Win Rate 43% Profit-Loss Ratio 3.19 Alpha 0.645 Beta 0.335 Annual Standard Deviation 0.637 Annual Variance 0.405 Information Ratio -1.316 Tracking Error 0.915 Treynor Ratio 4.707 Total Fees $0.00 |
namespace QuantConnect
{
public static class RollingWindowExtensions
{
public static bool CrossAbove(this RollingWindow<decimal> window1, RollingWindow<decimal> window2, decimal tolerance = 0m)
{
return window1[0] > window2[0] * (1 + tolerance) && window1[1] < window2[1] * (1 - tolerance);
}
public static bool CrossBelow(this RollingWindow<decimal> window1, RollingWindow<decimal> window2, decimal tolerance = 0m)
{
return window1[0] < window2[0] * (1 - tolerance) && window1[1] > window2[1] * (1 + tolerance);
}
public static bool Rising(this RollingWindow<decimal> window, int lookback = 1, decimal tolerance = 0m)
{
return window[0] > window[lookback] * (1 + tolerance);
}
public static bool Falling(this RollingWindow<decimal> window, int lookback = 1, decimal tolerance = 0m)
{
return window[0] < window[lookback] * (1 - tolerance);
}
}
}namespace QuantConnect
{
public class EmaCrossesAlgorithm : QCAlgorithm
{
// private const string Market = "fxcm";
// private const int DefaultQuantity = 25000;
private const int PeriodFast = 20;
private const int PeriodSlow = 8;
private Symbol _symbol = QuantConnect.Symbol.Create("ETHUSD", SecurityType.Crypto, Market.GDAX);
private ExponentialMovingAverage _emaFast;
private ExponentialMovingAverage _emaSlow;
private RollingWindow<decimal> _emaFastHistory = new RollingWindow<decimal>(PeriodFast + 1);
private RollingWindow<decimal> _emaSlowHistory = new RollingWindow<decimal>(PeriodSlow + 1);
decimal leverage = 0.95m;
string stockHeld="";
public override void Initialize()
{
SetStartDate(2017, 1, 1);
SetEndDate(2018, 3, 31);
SetCash(10000);
SetBenchmark(_symbol);
AddCrypto(_symbol, Resolution.Hour);
_emaFast = EMA(_symbol, PeriodFast);
_emaSlow = EMA(_symbol, PeriodSlow);
}
public override void OnData(Slice data)
{
// Add ema values to rolling windows, so we can access previous ema values
_emaFastHistory.Add(_emaFast);
_emaSlowHistory.Add(_emaSlow);
if (!_emaSlow.IsReady) return;
var bar = data[_symbol] as TradeBar;
if (bar == null) return;
if (Portfolio[_symbol].IsLong)
{
// Long exit: EmaSlow is falling
if (_emaSlowHistory.Falling(PeriodSlow))
{
Liquidate();
}
}
// else if (Portfolio[_symbol].IsShort)
// {
// // Short exit: EmaSlow is rising
// if (_emaSlowHistory.Rising(PeriodSlow))
// {
// Order(_symbol, 0.95m);
// }
else
{
// Long entry: EmaFast crosses above EmaSlow and EmaSlow not falling
if (_emaSlowHistory.CrossAbove(_emaFastHistory) )
{
SetHoldings(_symbol, leverage);
stockHeld=_symbol;
}
// Short entry: EmaFast crosses below EmaSlow and EmaSlow not rising
if (_emaSlowHistory.CrossBelow(_emaFastHistory) && !_emaSlowHistory.Rising(PeriodSlow))
{
Liquidate();
}
}
}
}
}