Overall Statistics |
Total Trades 41 Average Win 7.15% Average Loss -5.82% Compounding Annual Return -12.323% Drawdown 69.100% Expectancy -0.220 Net Profit -25.687% Sharpe Ratio 0.158 Loss Rate 65% Win Rate 35% Profit-Loss Ratio 1.23 Alpha 0.12 Beta -0.428 Annual Standard Deviation 0.626 Annual Variance 0.392 Information Ratio 0.078 Tracking Error 0.645 Treynor Ratio -0.231 Total Fees $0.00 |
namespace QuantConnect { /* */ public class BollingerBandsAlgorithm : QCAlgorithm { //Define required variables: int quantity = 0; decimal price = 0; decimal high = 0; decimal low = 0; decimal tolerance = 0m; //0.1% safety margin in prices to avoid bouncing. string symbol = "EURUSD"; int profitTargetPercent = 1; DateTime sampledToday = DateTime.Now; //Set up the BB private AverageDirectionalIndex adx; private BollingerBands bb; private RelativeStrengthIndex rsi; //Initialize the data and resolution you require for your strategy: public override void Initialize() { SetStartDate(2015, 01, 01); SetEndDate(DateTime.Now); SetCash(1000); //Specify the Oanda Brokerage. SetBrokerageModel(BrokerageName.OandaBrokerage); //Add as many securities as you like. All the data will be passed into the event handler: AddSecurity(SecurityType.Forex, symbol, Resolution.Minute); //Forex adx = ADX(symbol, 14, Resolution.Daily); bb = BB(symbol, 20, 2, MovingAverageType.Simple, Resolution.Daily); rsi = RSI(symbol, 14, MovingAverageType.Simple, Resolution.Daily); } //Handle TradeBar Events: a TradeBar occurs on every time-interval public void OnData(TradeBars data) { //One data point per day: if (sampledToday.Date == data[symbol].Time.Date) return; //Only take one data point per day (opening price) price = Securities[symbol].Close; high = Securities[symbol].High; low = Securities[symbol].Low; sampledToday = data[symbol].Time; //Wait until SMA's are ready: if (!bb.IsReady || !rsi.IsReady) return; //Get fresh cash balance: Set purchase quantity to equivalent 10% of portfolio. decimal cash = Portfolio.Cash; int holdings = Portfolio[symbol].Quantity; quantity = Convert.ToInt32((cash * 0.5m) / price); //exit: short if (Portfolio[symbol].IsShort) { if (price > (bb.UpperBand * (1+tolerance)) && rsi > 70) { Liquidate(symbol); //Buy(symbol, (holdings + quantity)); //Log(Time.ToShortDateString() + " > Liquidate Short > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString()); } } //exit: long if (Portfolio[symbol].IsLong) { if (price < (bb.LowerBand * (1+tolerance)) && rsi < 30) { Liquidate(symbol); //Buy(symbol, (holdings + quantity)); //Log(Time.ToShortDateString() + " > Liquidate Long > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString()); } } //long if (!Portfolio.HoldStock) { if (price < (bb.LowerBand * (1+tolerance)) && rsi < 30) { LimitOrder(symbol, Math.Abs(holdings) + quantity, high); //Log(Time.ToShortDateString() + "> Go Long > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString()); } } //short if (!Portfolio.HoldStock) { if (price > (bb.UpperBand * (1+tolerance)) && rsi > 70) { LimitOrder(symbol, -(Math.Abs(holdings) + quantity), low); //Log(Time.ToShortDateString() + " > Go Short > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString()); } } /* if (holdings > 0 || holdings == 0) { //If we're long, or flat: check if EMA crossed negative: and crossed outside our safety margin: if (price > (bb.UpperBand * (1+tolerance)) && rsi > 70 ) { //Now go short: Short-EMA signals a negative turn: reverse holdings LimitOrder(symbol, -(holdings + quantity), low); //Log("compare: " + price.ToString() + " == " + low.ToString()); //Order(symbol, -(holdings + quantity)); Log(Time.ToShortDateString() + " > Go Short > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString()); } } else if (holdings < 0 || holdings == 0) { //If we're short, or flat: check if EMA crossed positive: and crossed outside our safety margin: if (price < (bb.LowerBand * (1+tolerance)) && rsi < 30) { //Now go long: Short-EMA crossed above long-EMA by sufficient margin LimitOrder(symbol, Math.Abs(holdings) + quantity, high); //Order(symbol, Math.Abs(holdings) + quantity); Log(Time.ToShortDateString() + "> Go Long > Holdings: " + holdings.ToString() + " Quantity:" + quantity.ToString()); } } */ Plot(symbol, "BB", bb); Plot(symbol, "RSI", rsi); Plot(symbol, "Close", price); Plot(symbol, "High", high); } } }