The rules to the Turtle System as implemented in Trading Blox are described in the Original Turtle rules document at the site: www.originalturtles.org. Please consult that document for a complete description of the Turtle System rules.

 

TurtleSystem

The Turtle System trades on breakouts similar to a Donchian Dual Channel system. There are two breakout figures, a longer breakout for entry, and a shorter breakout for exit. The system also optionally uses a dual-length entry where the shorter entry is used if the last trade was a losing trade.

 

The Turtle system uses a stop based on the Average True Range (ATR).

 

Note that the Turtle concept of N has been replaced by the more common and equivalent term Average True Range (ATR) in this document.

 

 

TURTLE

 

Trade Long/Short

This parameter tells Trading Blox whether or not trades in the short direction are to be taken.

 

Trade if Last is Winner

When this parameter is set to False (unchecked and disabled), Trading Blox looks back at the last entry breakout for that instrument and determines if it would have been a winner, either actually, or theoretically. If the last trade was, or would have been a winner, then the next trade is skipped, regardless of direction (long or short).

 

The last breakout is considered to be the last breakout in that market regardless of whether or not that particular breakout was actually taken, or was skipped because of this rule. (Trading Blox looks back only at "regular" breakouts, and not Entry Failsafe Breakouts.)

 

The direction of the last breakout-long or short-is irrelevant to the operation of this rule, as is the direction of the trade currently being considered. Thus, a losing long breakout or a losing short breakout, whether hypothetical or actual, would enable the subsequent new breakout to be taken as a valid entry, regardless of its direction (long or short):

 

Some traders believe that two large, consecutive wins are unlikely, or that a profitable trade is more likely to follow a losing trade. Trading Blox allows you to test this idea by setting this parameter to False.

 

Entry Breakout (days)

A trade is entered when the price hits the high or the low of the preceding X-days, as adjusted by the Entry Offset. For example, Entry Breakout = 20 means that a long position is taken if price hits the 20-day high; A short position is taken if price hits the 20-day low.

 

Entry Failsafe Breakout (days)

This parameter works in concert with Trade if Last is Winner, and is used only if Trade if Last is Winner = False (as is shown in the partial screen shot above).

 

For example, consider the following set of parameters and values:

 

With these settings, if a 20-day breakout entry was recently signaled, but was skipped because the prior trade was a winner (either actually, or theoretically), then if the price breaks out above or below the 55-day extreme high or low, an entry is initiated for that position regardless of the outcome of the prior trade.

 

Entry Failsafe Breakout keeps you from missing very strong trends due to the action of the Trade if Last is Winner rule.

 

Entry Offset (ATR)

If set to zero, this parameter has no effect. If Entry Offset in ATR is set to 1.0, a long position isn't entered until price hits the normal breakout price, plus 1.0 ATR. Likewise, a short position won't be entered until the price hits the normal breakout price, minus 1.0 ATR. Either a positive or negative value can be specified for this parameter. A positive value effectively delays entry until the specified point after the breakout threshold chosen; a negative value would enter before the breakout threshold chosen.

 

Unit Add (ATR)

This parameter defines the price at which additions to an existing position are made. The Turtles entered single Unit positions at the breakouts, and added to those positions at 1/2 ATR intervals following trade initiation. (Adding to existing positions is often referred to as "pyramiding.")

 

Following the initial breakout entry, Trading Blox will continue to add a Unit (or Units, in the case of a large price move in a single day), at each interval defined by Unit Add in ATR, as price progresses favorably, right up to the maximum permitted number of Units, as specified by the various Max Units rules (explained below).

 

During historical simulation tests, the theoretical entry price is adjusted up or down by Slippage Percent and/or Minimum Slippage, to obtain the simulated fill price. So each interval is based on the simulated fill price of the previous order. So if an initial breakout order slipped by 1/2 ATR, the new order would be moved to account for the 1/2 ATR slippage, plus the normal unit add interval specified by Unit Add in ATR.

 

The exception to this rule is when multiple Units are added in a single day during a trade in progress. For example, with Unit Add in ATR = 0.5, the initial breakout order is placed and incurs slippage of 1/2 ATR. Several days later, two more units are added on the same day. In this case, the order price of both the 2nd and 3rd Units is adjusted up by 1/2 ATR (to 1 full ATR past the breakout), based on the slippage incurred by the 1st Unit. Ordinarily, in the case where several Units have been added (each on a separate day), the order price of each Unit is adjusted by the cumulative slippage (in N) of all the Units that preceded it on the trade in progress.

 

Notes:

Users who generate orders will need to adjust the order price of any Units that are to be added, based on the cumulative slippage (in ATR) of all preceding Units. Trading Blox does not account for slippage and actual fills.

The initial Unit, as well as any Units added, are all sized based on a combination of the current value of ATR, and the current available account balance. (This differs slightly from the Original Turtle Trading Rules in that the Turtles were only given an updated value of ATR once a week). So do not be surprised, for example, if the initial Unit size of a Wheat trade is 7 contracts, and the size of the next Unit added to this trade is 5 contracts.

As per the Original Turtle Rules, the prices for stops of previous units are raised as new units are added. However, since the Unit Add in ATR parameter can be larger than the Stop in ATR parameter, it is possible that prices for stops would be raised above the entry price. In keeping with the spirit of the Turtle System Trading Blox does not allow stops to be raised above the initial entry price when adjusting stops based on the addition of new units..

 

Stop (ATR)

This parameter defines the distance from the entry price to the initial stop, in terms of ATR. Since ATR is a measure of daily volatility and the Turtle System stops are based on ATR, this means that the Turtle System equalizes the position size across the various markets based on volatility.

 

According to the original Turtle Rules, long positions were stopped out if price fell 2 ATR from the entry price. Conversely, short positions were stopped out if the price rose 2 ATR from the entry price.

 

Unlike the Exit Breakout based stop, which moves up or down with the X-day high or low, the stop defined by Stop in ATR is a "hard" stop that is fixed above or below the entry price upon entry. Once set, it does not vary throughout the course of the trade, unless Units are added, in which case the for earlier units are raised by the amount specified by Unit Add (ATR).

 

Trades are liquidated when price hits the stop defined by either the Stop in ATR, the Entry Breakout for the opposite direction, or the Exit Breakout (see above), whichever is closest to the price at the time.

 

In this system the initial entry stop for the trade entry day is based on the order price. This is for ease of placing the stop once the order is filled. Note that the stop is adjusted based on the actual fill price for the following day.

 

Exit Breakout (days)

Trades in progress are exited when the price hits the high or the low of the preceding X-days as adjusted by the Exit Offset. This concept is the identical to Entry Breakout, but the logic is reversed: Long trades are exited when price breaks out below the X-day low, and short trades are exited when price breaks out above the X-day low.

 

The Exit Breakout moves up (or down) with price. It protects against adverse price excursions, and also serves as a trailing stop that acts to lock in a profit when the trend reverses.

 

Trades are liquidated when price hits the stop defined by either the Stop in ATR, the Entry Breakout for the opposite direction, or the Exit Breakout (see above), whichever is closest to the price at the time.

 

Exit Offset (ATR)

If set to zero, this parameter has no effect. If Exit Offset in ATR is set to 1.0, a long position isn't exited until price hits the normal breakout price, minus 1.0 ATR. Likewise, a short position won't be exited until the price hits the normal breakout price, plus 1.0 ATR. Either a positive or negative value can be specified for this parameter. A positive value effectively delays exit until the specified point after the breakout threshold chosen; a negative value would exit before the breakout threshold chosen.

 

Max Instrument Units

This parameter defines the maximum number of Units that can be held at one time, in any single futures market, or any single stock. For instance, Max Instrument Units = 4 means that no more than 4 Units of Coffee may be held at one time; this includes the initial Unit, plus 3 Units added.

 

 

Entry Orders:

VARIABLES: longEntryPrice, shortEntryPrice, unitIncrementATR, unitEntryPrice TYPE: Price
VARIABLES: entryOffsetATR TYPE: Price
VARIABLES: unitsOn, unitIndex TYPE: Integer
VARIABLES: brokerPrice TYPE: Price
 
' Calculate the unit increment, stop amount, and entry offset
unitIncrementATR = unitAdd * averageTrueRange
stopWidth = stopInATR * averageTrueRange
 
'Total units currently on for this instrument
unitsOn = instrument.totalUnits
 
'----------------------------------------------------------------
'Place initial entry orders when out of the market
'----------------------------------------------------------------
' If we are not long (we are short or out) then place orders for tomorrow
' We will place orders for all potential units in case it's a big day
IF instrument.position <> LONG THEN
 
  ' Determine whether to use the regular entry high or the failsafe
   longEntryPrice = offsetAdjustedEntryHigh
  IF ( NOT tradeIfWinner ) AND ( lastTradeProfit > 0 ) THEN longEntryPrice = offsetAdjustedFailsafeHigh
   
  ' Loop over the potential units and place an order
  FOR unitIndex = 1 TO maxUnits
       brokerPrice = longEntryPrice + ( ( unitIndex - 1 ) * unitIncrementATR )
      broker.EnterLongOnStop( brokerPrice, brokerPrice - stopWidth )
  NEXT  
ENDIF
 
' If we are not short (we are long or out) then place orders for tomorrow
' We will place orders for all potential units in case it's a big day
IF instrument.position <> SHORT THEN
 
  ' Determine whether to use the regular entry low or the failsafe
   shortEntryPrice = offsetAdjustedEntryLow
  IF ( NOT tradeIfWinner ) AND ( lastTradeProfit > 0 ) THEN shortEntryPrice = offsetAdjustedFailsafeLow
   
  ' Loop over the potential units and place an order
  FOR unitIndex = 1 to maxUnits
       brokerPrice = shortEntryPrice - ( ( unitIndex - 1 ) * unitIncrementATR )
      broker.EnterShortOnStop( brokerPrice, brokerPrice + stopWidth )
  NEXT
   
ENDIF
 
'----------------------------------------------------------------
'Add additional Units when already in the market
'----------------------------------------------------------------
'If long and can add more units
IF ( instrument.position = LONG ) AND ( unitsOn < maxUnits ) THEN
 
  ' Loop over potential units to add, placing orders at maximum of regular entryHigh or unit increment
  FOR unitIndex = unitsOn + 1 TO maxUnits
       unitEntryPrice = instrument.unitEntryFill[ unitsOn ] + ( unitIndex - unitsOn ) * unitIncrementATR
       brokerPrice = max( offsetAdjustedEntryHigh, unitEntryPrice )
      broker.EnterLongOnStop( brokerPrice, brokerPrice - stopWidth)
  NEXT
ENDIF
 
'If short and can add more units
IF ( instrument.position = SHORT ) AND ( unitsOn < maxUnits ) THEN
 
  ' Loop over potential units to add, placing orders at minimum of regular entryLow or unit increment
  FOR unitIndex = unitsOn + 1 TO maxUnits
       unitEntryPrice = instrument.unitEntryFill[ unitsOn ] - ( unitIndex - unitsOn ) * unitIncrementATR
       brokerPrice = min( offsetAdjustedEntryLow, unitEntryPrice )
      broker.EnterShortOnStop( brokerPrice, brokerPrice + stopWidth )
  NEXT
ENDIF

 

 

Entry Order Filled:

VARIABLES: stopAmount, stopPrice, originalATR TYPE: Price
VARIABLES: unitFillPrice, newStopPrice TYPE:Price
VARIABLES: newUnitExitStop, originalExitStop, newExitStop TYPE: Price
VARIABLES: entryDayIndex TYPE: Integer
VARIABLES: unitsOn, unitIndex TYPE: Integer
 
'----------------------------
' Get the total number of units on now, including this new unit
unitsOn = instrument.totalUnits
 
' Calculate the new exit stop for this new unit, based on the fill price
if instrument.position = LONG then newUnitExitStop = order.fillPrice - order.entryRisk
if instrument.position = SHORT then newUnitExitStop = order.fillPrice + order.entryRisk
 
' Set exit stop for this new unit added
instrument.setExitStop( unitsOn, newUnitExitStop )
 
'------------------------------
' If more than one unit on, then
' Reset the stops for all units, except the current one, based on this new unit
' For each unit, look for the original ATR and calculate the original stop price
' Add to the original stop
'------------------------------
IF unitsOn > 1 THEN
  IF instrument.position = LONG THEN
      FOR unitIndex = 1 TO unitsOn - 1
       
          ' Compute the ATR TYPE: of the entry for this unit.
           entryDayIndex = instrument.bar - instrument.unitEntryDayIndex[ unitIndex ]
           originalATR = averageTrueRange[ entryDayIndex ]
           
          ' Get the fill price.
           unitFillPrice = instrument.unitentryfill[ unitIndex ]
           
          ' Compute the original exit stop.
           originalExitStop = unitFillPrice - stopInATR * originalATR
           
          ' Now compute the new stop based on the original ATR.
           newStopPrice = originalExitStop + ( unitsOn - unitIndex ) * unitAdd * originalATR
           
          ' Constrain the stop to the fill price or the new unit stop.
           newExitStop = min( newStopPrice, unitFillPrice, newUnitExitStop )
           
          ' Give the instrument this new stop.
          instrument.setExitStop( unitIndex, newExitStop )
      NEXT
  ENDIF
   
  IF instrument.position = SHORT THEN
      FOR unitIndex = 1 TO unitsOn - 1
       
          ' Compute the ATR TYPE: of the entry for this unit.
           entryDayIndex = instrument.bar - instrument.unitEntryDayIndex[ unitIndex ]
           originalATR = averageTrueRange[ entryDayIndex ]
           
          ' Get the fill price.
           unitFillPrice = instrument.unitentryfill[ unitIndex ]
           
          ' Compute the original exit stop.
           originalExitStop = unitFillPrice + stopInATR * originalATR
           
          ' Now compute the new stop based on the original ATR.
           newStopPrice = originalExitStop - ( unitsOn - unitIndex ) * unitAdd * originalATR
           
          ' Constrain the stop to the fill price or the new unit stop.
           newExitStop = max( newStopPrice, unitFillPrice, newUnitExitStop )
           
          ' Give the instrument this new stop.
          instrument.setExitStop( unitIndex, newExitStop )
      NEXT
  ENDIF
ENDIF
 
' ----------------------------------
' Track theoretical positions
' ----------------------------------
 
' Only run these calcs if we have to
IF ( tradeIfWinner = FALSE ) THEN
 
  ' If this is the first unit on, then set the theoretical position at this point
  IF unitsOn = 1 THEN
       theoreticalPosition = instrument.position
       theoreticalEntryPrice = order.fillprice
       theoreticalExitStop = order.stopprice
  ENDIF
ENDIF

 

 

 

Exit Orders;

VARIABLES: brokerPrice, exitPrice, unitCurrentStopPrice TYPE: Price
VARIABLES: unitsOn, unitIndex TYPE: Integer
 
unitsOn = instrument.totalUnits
 
' If long...
IF ( instrument.position = LONG ) THEN
 
  ' Get the best exit price based on exit low and entry low.
   exitPrice = max( offsetAdjustedExitLow, offsetAdjustedEntryLow )
   
  ' Loop over the units and place stop order at the best price,
  ' including current stop price.
  FOR unitIndex = 1 TO unitsOn
       unitCurrentStopPrice = instrument.unitExitStop[ unitIndex ]
       brokerPrice = max( exitPrice, unitCurrentStopPrice )
      broker.ExitUnitOnStop( unitIndex, brokerPrice )
  NEXT
ENDIF
 
' If short...
IF ( instrument.position = SHORT ) THEN
 
  ' Get the best exit price based on exit high and entry high.
   exitPrice = min( offsetAdjustedExitHigh, offsetAdjustedEntryHigh )
   
  'Loop over units and place stop order at best price,
  ' including curreen stop price.
  FOR unitIndex = 1 TO unitsOn
       unitCurrentStopPrice = instrument.unitExitStop[ unitIndex ]
       brokerPrice = min( exitPrice, unitCurrentStopPrice )
      broker.ExitUnitOnStop( unitIndex, brokerPrice )
  NEXT
ENDIF

 

 

Adjust Stops:

VARIABLES: stopPrice, bestExitPrice, unitCurrentStopPrice TYPE: Price
VARIABLES: unitsOn, unitIndex TYPE: Integer
 
' Get the total units on.
unitsOn = instrument.totalUnits
 
' If long...
IF ( instrument.position = LONG ) THEN
 
  ' Get the best exit price based on exit low and entry low.
   bestExitPrice = max( offsetAdjustedExitLow, offsetAdjustedEntryLow )
   
  ' Loop over the units and set the stop to the best price,
  ' including current stop price.
  FOR unitIndex = 1 TO unitsOn
   
      ' Get the current exit stop.
       unitCurrentStopPrice = instrument.unitExitStop[ unitIndex ]
       
      ' If the best stop is better than our current stop then
      ' exit on this stop.
      IF bestExitPrice > unitCurrentStopPrice THEN
          instrument.SetExitStop( unitIndex, bestExitPrice )
          broker.exitUnitOnStop( unitIndex, bestExitPrice )
      ENDIF
  NEXT
ENDIF
 
' If short...
IF ( instrument.position = SHORT ) THEN
 
  ' Get the best exit price based on exit high and entry high.
   bestExitPrice = min( offsetAdjustedExitHigh, offsetAdjustedEntryHigh )
   
  ' Loop over the units and set the stop to the best price,
  ' including curreen stop price.
  FOR unitIndex = 1 TO unitsOn
   
      ' Get the current exit stop.
       unitCurrentStopPrice = instrument.unitExitStop[ unitIndex ]
       
      ' If the best stop is better than our current stop then
      ' exit on this stop.
      IF bestExitPrice < unitCurrentStopPrice THEN
          instrument.SetExitStop( unitIndex, bestExitPrice )
          broker.exitUnitOnStop( unitIndex, bestExitPrice )
      ENDIF
  NEXT
ENDIF

 

 

After Instrument Day:

VARIABLES: theoreticalExitPrice TYPE: PRICE
 
' Calc stop width
stopWidth = stopInATR * averageTrueRange
 
' -----------------------------
' Track theoretical positions
' ----------------------------
 
IF ( tradeIfWinner = FALSE ) THEN
 
  ' Update theoretical profit mark to market
  IF ( theoreticalPosition = LONG ) THEN
           lastTradeProfit = ( instrument.close - theoreticalEntryPrice )
  ENDIF
 
  if ( theoreticalPosition = SHORT ) THEN
           lastTradeProfit = ( theoreticalEntryPrice - instrument.close )
  ENDIF
 
 
 
  ' If not long, then watch for long entry
  IF ( theoreticalPosition <> LONG ) THEN
      IF ( instrument.high > offsetAdjustedEntryHigh[1] ) THEN
           theoreticalPosition = LONG
           theoreticalEntryPrice = offsetAdjustedEntryHigh[1]
           theoreticalExitStop = theoreticalEntryPrice - stopWidth
      ENDIF
  ENDIF
 
 
  ' If not short, then watch for short entry
  IF ( theoreticalPosition <> SHORT ) THEN
      IF instrument.low < offsetAdjustedEntryLow[1] THEN
           theoreticalPosition = SHORT
           theoreticalEntryPrice = offsetAdjustedEntryLow[1]
           theoreticalExitStop = theoreticalEntryPrice + stopWidth
      ENDIF
  ENDIF
 
 
  ' If long, then watch for exits
  IF ( theoreticalPosition = LONG ) THEN
       theoreticalExitPrice = max( theoreticalExitStop, offsetAdjustedExitLow, offsetAdjustedEntryLow )
      IF ( instrument.low < theoreticalExitPrice ) THEN
           lastTradeProfit = ( theoreticalExitPrice - theoreticalEntryPrice )
           theoreticalPosition = OUT
      ENDIF
  ENDIF
   
   
  ' If short, then watch for exits
  IF ( theoreticalPosition = SHORT ) THEN
       theoreticalExitPrice = min( theoreticalExitStop, offsetAdjustedExitHigh, offsetAdjustedEntryHigh )
      if ( instrument.high > theoreticalExitPrice ) THEN
           lastTradeProfit = ( theoreticalEntryPrice - theoreticalExitPrice )
           theoreticalPosition = OUT
      ENDIF
  ENDIF
 
ENDIF

 


Edit Time: 2/18/2022 3:35:42 PM


Topic ID#: 230

 

Created with Help & Manual 7 and styled with Premium Pack Version 2.80 © by EC Software