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