| Overall Statistics |
|
Total Trades 2107 Average Win 0.35% Average Loss -0.22% Compounding Annual Return -1.097% Drawdown 24.000% Expectancy -0.040 Net Profit -5.393% Sharpe Ratio -0.068 Loss Rate 63% Win Rate 37% Profit-Loss Ratio 1.56 Alpha -0.005 Beta 0.001 Annual Standard Deviation 0.073 Annual Variance 0.005 Information Ratio -0.668 Tracking Error 0.137 Treynor Ratio -4.065 Total Fees $3370.40 |
namespace QuantConnect
{
public class FXCMBollengerBands : QCAlgorithm
{
private BollingerBands bollingerBands;
private decimal _price;
private string security = "EURUSD";
//private string security = "USDJPY";
decimal buyBBLinePct = 0.9m;
decimal sellBBLinePct = 0.9m;
private int consolidateMinutes = 30;
private int cash = 25000;
private int backtestYears = 5;
private bool wentLow = false;
private bool wentHigh = false;
int orderSize = 20000;
public override void Initialize()
{
//Start and End Date range for the backtest:
SetStartDate(DateTime.Now.Date.AddDays(-365*backtestYears));
SetEndDate(DateTime.Now.Date.AddDays(-1));
//Cash allocation
SetCash(cash);
// FXCM Brokerage
SetBrokerageModel(BrokerageName.FxcmBrokerage);
AddSecurity(SecurityType.Forex, security, Resolution.Minute);
Securities[security].SetLeverage(50.0m);
// Setup BB Indicator
bollingerBands = new BollingerBands(20, 2, MovingAverageType.Simple);
// 15 min Trade bars
var fifteenConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(consolidateMinutes));
fifteenConsolidator.DataConsolidated += OnDataFifteen;
SubscriptionManager.AddConsolidator(security,fifteenConsolidator);
// Put it all together
RegisterIndicator(security, bollingerBands, fifteenConsolidator, x => x.Value);
SetWarmup(new TimeSpan(10, 0, 0, 0, 0)); // 10 Days
}
public void OnData(TradeBars data)
{ if (IsWarmingUp) return;
if (!data.ContainsKey(security)) { return; }
// Placeholder
}
private void OnDataFifteen(object sender,TradeBar consolidated)
{
if (IsWarmingUp) return;
_price = consolidated.Close;
if (!bollingerBands.IsReady) return;
var _buyBBLine = bollingerBands.LowerBand;
var _sellBBLine = bollingerBands.UpperBand;
Plot("BB", "Price", _price);
Plot("BB", bollingerBands.UpperBand, bollingerBands.MiddleBand, bollingerBands.LowerBand);
var adjustedBuyLine = ((bollingerBands.MiddleBand - bollingerBands.LowerBand) * 0.25m) + bollingerBands.LowerBand;
var adjustedSellLine = ((bollingerBands.UpperBand - bollingerBands.MiddleBand) * 0.85m) + bollingerBands.MiddleBand;
Plot("BB", "BBSell",adjustedSellLine);
Plot("BB", "BBBuy",adjustedBuyLine);
decimal buy_signal = 0;
decimal sell_signal = 0;
// (CalculateOrderQuantity(security,1.0m) / 1000) * 1000; // FXCM Required ordering in multiples of 1000 for standard and mini accounts https://www.fxcm.com/accounts/account-types/
bool _buySignal = consolidated.Close < adjustedBuyLine;
bool _sellSignal = consolidated.Close > adjustedSellLine;
/*if(!Portfolio[security].Invested)
{
if (_buySignal) {
Order(security, orderSize);
}
if (_sellSignal){
Order(security, orderSize * -1);
}
}else{
if ((_buySignal) && (Portfolio[security].IsShort)) {
Log("Was Short Go Long Sz"+orderSize.ToString()+" + "+(Securities[security].Holdings.Quantity * -1).ToString());
Order(security, orderSize + (Securities[security].Holdings.Quantity * -1));
}
if ((_sellSignal) && Portfolio[security].IsLong){
// Order(security, orderSize * -1);
Log("Was Long Go Short Sz"+(orderSize * -1).ToString()+" + "+(Securities[security].Holdings.Quantity * -1).ToString());
Order(security, (orderSize * -1) + (Securities[security].Holdings.Quantity * -1));
}
}*/
if (Portfolio[security].IsLong && (consolidated.Close > (bollingerBands.MiddleBand * 1.1m)))
{
// Bail
Log("BAIL!");
Liquidate();
}
if (Portfolio[security].IsShort && (consolidated.Close < (bollingerBands.MiddleBand * 0.90m)))
{
// Bail
Log("BAIL!");
Liquidate();
}
if (wentLow || wentHigh)
{
if (wentLow && (consolidated.Close >=bollingerBands.MiddleBand ))
{
// Go Long
wentLow = false;
GoLong();
}
if (wentHigh && (consolidated.Close <=bollingerBands.MiddleBand ))
{
// Go Short
wentHigh = false;
GoShort();
}
}else{
if (!wentLow && consolidated.Close < bollingerBands.LowerBand)
{
Log ("Price Breached Lower BB");
wentLow = true;
}
if (!wentHigh && consolidated.Close > bollingerBands.LowerBand)
{
Log ("Price Breached Higher BB");
wentHigh = true;
}
}
}
private void GoLong()
{
if (Portfolio[security].IsLong) { return; }
Log("Go Long");
if (Portfolio[security].IsShort)
{
Order(security, orderSize + (Securities[security].Holdings.Quantity * -1));
}else{
Order(security,orderSize);
}
}
private void GoShort()
{
if (Portfolio[security].IsShort) { return; }
Log("Go Short");
if (Portfolio[security].IsLong)
{
Order(security, (orderSize * -1) + (Securities[security].Holdings.Quantity * -1));
}else{
Order(security,orderSize * -1);
}
}
}
}