// this function is called the constructor, because it sets up the response // it is run before all the other functions, and has same name as my response. public TurtleResponse() : this(true) { //int lastTrade = -1; // account size to be updated from account query myStats.accountSize = 1000000m; myStats.accountRiskPercent = 0.01m; myStats.tradeProfit = 0m; myParams.ATRLen = 20; myParams.ATRMultiplier = 2.0m; myParams.entryLen = 20; myParams.exitLen = 10; myParams.failSafeEntryLen = 55; myParams.skipConsecutiveTrades = false; myParams.TurtleSystem = SystemType.System_One; myParams.slippagePerRoundTripDollars = 0m; tradeLog initTrade = new tradeLog(); initTrade.action = tradeType.Init; myTrades.Add(initTrade); }
void blt_GotNewBar(string symbol, int interval) { int idx = _active.getindex(symbol); BarList myBarList = blt[symbol]; Bar curBar = myBarList.RecentBar; int barCount = myBarList.Count; int lastBar = barCount - 1; decimal oneTick = tickValue; //this is hard-coded for ES contracts tradeLog curTrade = new tradeLog(); turtleSignal curSignal = new turtleSignal(); //doing manual sizing here int units = manualTradeUnit; if (myBarList.Count < myParams.ATRLen) { D("Error: waiting for more bars. or you can request more history data"); return; } // calculate the SMA using closing prices for so many bars back //decimal SMA = MyCalc.Avg(Calc.EndSlice(blt[symbol].Close(), _barsback)); //TODO: optimize this one calculation curSignal.ATR = MyCalc.AverageTrueRange(blt[symbol], myParams.ATRLen); if (curSignal.ATR < 0) { D("Error calc ATR"); return; } switch (myParams.TurtleSystem) { case SystemType.System_One: if (myTrades.Count == 0) //essentially trade.Init { lastTrade = 0; entry = 0; exit = 0; curTrade = trade.Flat; myTrades.Add(curTrade); tradeProfitPoints = 0; stop = 0; entryUnits = units; //using this for now. } break; switch (myTrades[myTrades.Count - 1]) { case trade.Init: { lastTrade = 0; } case trade.Flat: if ((curBar.High > longEntry && lastTrade == 1 && curBar.High < failSafeLongEntry) && skipConsecutiveTrades) { entry = Math.Max(longEntry + oneTick, curBar.Low); exit = 0; curTrade = trade.SkipLong; tradeProfitPoints = 0; stop = entry - ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else if (((curBar.Low < shortEntry && lastTrade == 1 && curBar.Low > failSafeShortEntry)) && skipConsecutiveTrades) { entry = Math.Min(shortEntry - oneTick, curBar.High); exit = 0; curTrade = trade.SkipShort; tradeProfitPoints = 0; stop = entry + ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else if (curBar.High > longEntry) { entry = Math.Max(longEntry + oneTick, curBar.Low); exit = 0; curTrade = trade.GoLong; tradeProfitPoints = 0; stop = entry - ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else if (curBar.Low < shortEntry) { entry = Math.Min(shortEntry - oneTick, curBar.High); exit = 0; curTrade = trade.GoShort; tradeProfitPoints = 0; stop = entry + ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else { entry = 0; exit = 0; curTrade = trade.Flat; tradeProfitPoints = 0; stop = -1.0m; entryUnits = entryUnits[1]; lastTrade = lastTrade[1]; } case trade.GoLong: entryUnits = entryUnits[1]; if (curBar.Low < longExit || curBar.Low < stop[1]) { exit = Math.Min(curBar.Open, Math.Max(longExit - oneTick, stop[1] - oneTick)); entry = entry[1]; curTrade = trade.Flat; tradeProfitPoints = exit - entry[1]; stop = -1m; lastTrade = tradeProfitPoints > 0 ? 1 : 0; } else { exit = 0; entry = entry[1]; curTrade = trade.GoLong; tradeProfitPoints = 0; stop = stop[1]; lastTrade = lastTrade[1]; } case trade.GoShort: entryUnits = entryUnits[1]; if (curBar.High > shortExit || curBar.High > stop[1]) { exit = Math.Max(curBar.Open, Math.Min(shortExit + oneTick, stop[1] + oneTick)); entry = entry[1]; curTrade = trade.Flat; tradeProfitPoints = entry[1] - exit; stop = -1m; lastTrade = tradeProfitPoints > ? 1 : 0; } else { exit = 0; entry = entry[1]; curTrade = trade.GoShort; tradeProfitPoints = 0; stop = stop[1]; lastTrade = lastTrade[1]; } case trade.SkipLong: if (curBar.Low < longExit || curBar.Low < stop[1]) { exit = Math.Min(curBar.Open, Math.Max(longExit - oneTick, stop[1] - oneTick)); entry = entry[1]; curTrade = trade.Flat; tradeProfitPoints = exit - entry[1]; stop = -1m; lastTrade = 0; entryUnits = 0; } else if (curBar.High > failSafeLongEntry) { entry = Math.Max(failSafeLongEntry + oneTick, curBar.Low); exit = 0; curTrade = trade.GoLong; tradeProfitPoints = 0; stop = Math.Max(failSafeLongEntry + oneTick, curBar.Low) - ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else { exit = 0; entry = entry[1]; curTrade = trade.SkipLong; tradeProfitPoints = 0; stop = stop[1]; lastTrade = lastTrade[1]; entryUnits = 0; } case trade.SkipShort: if (curBar.High > shortExit || curBar.High > stop[1]) { entryUnits = 0; exit = Math.Max(curBar.Open, Math.Min(shortExit + oneTick, stop[1] + oneTick)); entry = entry[1]; curTrade = trade.Flat; tradeProfitPoints = entry[1] - exit; stop = -1m; lastTrade = 0; } else if (curBar.Low < failSafeShortEntry) { entry = Math.Min(failSafeShortEntry - oneTick, curBar.High); exit = 0; curTrade = trade.GoShort; tradeProfitPoints = 0; stop = entry + ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else { exit = 0; entry = entry[1]; curTrade = trade.SkipShort; tradeProfitPoints = 0; stop = stop[1]; lastTrade = lastTrade[1]; entryUnits = 0; } } break; case SystemType.System_Two: switch (trade[1]) { case trade.Init: lastTrade = 0; entry = 0; exit = 0; curTrade = barNumber() >= 1 ? trade.Flat : trade.Init; tradeProfitPoints = 0; stop = 0; entryUnits = unit; case trade.Flat: if (curBar.High > failSafeLongEntry) { entry = Math.Max(failSafeLongEntry + oneTick, curBar.Low); exit = 0; curTrade = trade.GoLong; tradeProfitPoints = 0; stop = entry - ATRMultiplier * ATR; entryUnits = units; lastTrade = 0; } else if (curBar.Low < failSafeShortEntry) { entry = Math.Min(failSafeShortEntry - oneTick, curBar.High); exit = 0; curTrade = trade.GoShort; tradeProfitPoints = 0; stop = entry + ATRMultiplier * ATR; entryUnits = unit; lastTrade = 0; } else { entry = 0; exit = 0; curTrade = trade.Flat; tradeProfitPoints = 0; stop = -1m; entryUnits = entryUnits[1]; lastTrade = 0; } case trade.GoLong: entryUnits = entryUnits[1]; if (curBar.Low < longExit || curBar.Low < stop[1]) { exit = Math.Min(curBar.Open, Math.Max(longExit - oneTick, stop[1] - oneTick)); entry = entry[1]; curTrade = trade.Flat; tradeProfitPoints = exit - entry[1]; stop = -1m; lastTrade = 0; } else { exit = 0; entry = entry[1]; curTrade = trade.GoLong; tradeProfitPoints = 0; stop = stop[1]; lastTrade = 0; } case trade.GoShort: entryUnits = entryUnits[1]; if (curBar.High > shortExit || curBar.High > stop[1]) { exit = Math.Max(curBar.Open, Math.Min(shortExit + oneTick, stop[1] + oneTick)); entry = entry[1]; curTrade = trade.Flat; tradeProfitPoints = entry[1] - exit; stop = -1m; lastTrade = 0; } else { exit = 0; entry = entry[1]; curTrade = trade.GoShort; tradeProfitPoints = 0; stop = stop[1]; lastTrade = 0; } case trade.SkipShort: entryUnits = 0; exit = 0; entry = 0; curTrade = trade.GoShort; tradeProfitPoints = 0; stop = 0; lastTrade = 0; case trade.SkipLong: entryUnits = 0; exit = 0; entry = 0; trade = trade.GoShort; tradeProfitPoints = 0; stop = 0; lastTrade = 0; } break; } // // D("received new bar. close is "+ (blt[symbol].RecentBar.Close).ToString() +"SMA is "+SMA.ToString()); /* for the moment let me assume we always get a fill * //ensure we aren't waiting for previous order to fill * if (!_wait[symbol]) * { * * // if we're flat and not waiting * if (pt[symbol].isFlat) * { * // if our current price is above SMA, buy * if (blt[symbol].RecentBar.Close > ATR) * { * D("crosses above MA, buy"); * sendorder(new BuyMarket(symbol, EntrySize)); * // wait for fill * _wait[symbol] = true; * } * // otherwise if it's less than SMA, sell * if (blt[symbol].RecentBar.Close < ATR) * { * D("crosses below MA, sell"); * sendorder(new SellMarket(symbol, EntrySize)); * // wait for fill * _wait[symbol] = true; * } * } * else if ((pt[symbol].isLong && (blt[symbol].RecentBar.Close < SMA)) || (pt[symbol].isShort && (blt[symbol].RecentBar.Close > SMA))) || { || D("counter trend, exit."); || sendorder(new MarketOrderFlat(pt[symbol])); || // wait for fill || _wait[symbol] = true; || } || } || else || { || D("no action, waiting for previous order to fill"); || } */ // this way we can debug our indicators during development // indicators are sent in the same order as they are named above sendindicators(new string[] { time.ToString(), SMA.ToString("N2") }); // draw the MA as a line sendchartlabel(SMA, time); }