{ public class Toby : QCAlgorithm { string tickersString = "EURUSD,EURCAD,EURAUD,EURGBP,NZDCHF,NZDUSD,NZDSGD,USDCAD,,USDSGD,SGDJPY,SGDCHF,AUDNZD,AUDJPY,AUDCAD"; static decimal totalMarginAvailable = 42m; decimal margin = totalMarginAvailable * 0.85m; int emaPeriod = 13; int wilrPeriod = 6; int rsiPeriod = 13; int longestIndicatorPeriod = 14; decimal emaPipRange = 0.0050m; decimal buyLongRSICutoff = 30.5m; decimal buyLongWILRCutoff = -76.5m; decimal buyShortRSICutoff = 73.5m; decimal buyShortWILRCutoff = -9.8m; decimal sellLongRSICutoff = 80.5m; decimal sellLongWILRCutoff = -08m; decimal sellShortRSICutoff = 23m; decimal sellShortWILRCutoff = -69.5m; Resolution resolution = Resolution.hour; List stockDatas = new List(); public override void Initialize() { // backtest parameters SetStartDate(2016, 1, 1); SetEndDate(DateTime.Now); SetCash(25000); SetBrokerageModel(BrokerageName.OandaBrokerage); string[] tickers = tickersString.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries); foreach (string ticker in tickers) { AddSecurity(SecurityType.Forex, ticker, resolution); StockData stockData = new StockData(ticker); stockData.ema = EMA(ticker, emaPeriod, resolution); stockData.wilr = WILR(ticker, wilrPeriod, resolution); stockData.rsi = RSI(ticker, rsiPeriod, MovingAverageType.Exponential, resolution); var history = History(ticker, longestIndicatorPeriod, resolution); foreach (var tradeBar in history) { stockData.ema.Update(tradeBar.EndTime, tradeBar.Close); stockData.wilr.Update(tradeBar); stockData.rsi.Update(tradeBar.EndTime, tradeBar.Close); } stockDatas.Add(stockData); } } public override void OnData(Slice data) { decimal marginPerStock = margin / (decimal)stockDatas.Count; foreach (StockData stockData in stockDatas) { decimal price = data[stockData.ticker].Close; if (stockData.holdingLong == false & stockData.holdingShort == false) { //not holding anything //check to see if buy long requirement is met if (stockData.rsi < buyLongRSICutoff) { if (stockData.wilr < buyLongWILRCutoff) { if (stockData.ema - emaPipRange > price) { SetHoldings(stockData.ticker, marginPerStock); stockData.holdingLong = true; } } } //check to see if buy short requirement is met if (stockData.rsi > buyShortRSICutoff) { if (stockData.wilr > buyShortWILRCutoff) { if (stockData.ema + emaPipRange < price) { SetHoldings(stockData.ticker, -marginPerStock); stockData.holdingShort = true; } } } } if (stockData.holdingLong == true) { //check to see if sell long requirement is met if (stockData.rsi > sellLongRSICutoff) { if (stockData.wilr > sellLongWILRCutoff) { if (stockData.ema + emaPipRange < price) { SetHoldings(stockData.ticker, 0); stockData.holdingLong = false; } } } } if (stockData.holdingShort == true) { //check to see if sell short requirement is met if (stockData.rsi < sellShortRSICutoff) { if (stockData.wilr < sellShortWILRCutoff) { if (stockData.ema - emaPipRange > price) { SetHoldings(stockData.ticker, 0); stockData.holdingShort = false; } } } } } } class StockData { public StockData(string inTicker) { ticker = inTicker; } public string ticker; public ExponentialMovingAverage ema; public WilliamsPercentR wilr; public RelativeStrengthIndex rsi; public bool holdingLong = false; public bool holdingShort = false; } } }