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