September 28

2 comments

Implementing Finite State Machine Functionality with EasyLanguage

By George Pruitt

September 28, 2020

EasyLanguage, Finite State Machine Functionality, George Pruitt

Last Trade Was a Loser Filter – To Use or Not To Use

Premise

A major component of the Turtle algorithm was to skip the subsequent 20-day break out if the prior was a winner. I guess Dennis believed that the success/failure of a trade had an impact on the outcome of the subsequent trade. I have written on how you can implement this in EasyLanguage in prior posts, but I have been getting some questions on implementing FSM in trading and thought this post could kill two birds with one stone: 1) provide a template that can be adapted to any LTL mechanism; and 2) provide the code/structure of setting up a FSM using EasyLanguage’s Switch/Case structure.

Turtle Specific LTL Logic

The Turtle LTL logic states that a trade is a loser if a 2N loss occurs after entry. N is basically an exponential-like moving average of TrueRange. So if the market moves 2N against a long or short position and stops you out, you have a losing trade. What makes the Turtle algorithm a little more difficult is that you can also exit on a new 10-day low/high depending on your position. The 10-day trailing exit does not signify a loss. Well at least in this post it doesn’t. I have a code that says any loss is a loss, but for this explanation let’s just stick to a 2N loss to determine a trade’s failure.

How To Monitor Trades When Skipping Some of Them

This is another added layer of complexity. You have to do your own trade accounting behind the scenes to determine if a losing trade occurs. Because if you have a winning trade you skip the next trade, and if you skip it how do you know if it would have been a winner or a loser. You have to run a theoretical system in parallel with the actual system code.

Okay let’s start out assuming the last trade was a winner. So we turn real trading off. As the bars go by we look for a 20-Day high or low penetration. Assume that a new 20-Day high is put in and a long position is established at the prior 20-Day high. At this point you calculate a 2N amount and subtract it from the theoretical entry price to obtain the theoretical exit price. So you have a theoMP (marketPosition) and a theoEX (exit price). This task seems pretty simple, so you move on and start looking for a day that either puts in a new 10-Day low or crosses below your theoEX price. If a new 10-Day low is put in then you continue on looking for a new entry and a subsequent 2N loss. If a 2N loss occurs, then you turn trading back on and continue monitoring the trades – turning trading off and then back on when necessary. In the following code I use these variables:

  • state – 0: looking for an entry or 1: looking for an exit
  • lep – long entry price
  • sep– short entry price
  • seekLong – I am seeking a long position
  • seekShort – I am seeking a short position
  • theoMP – theoretical market position
  • theoEX – theoretical exit price
  • lxp – long exit price
  • sxp – short exit price

Let’s jump into the Switch/Case structure when state = 0:

   Switch(state)
   Begin
       Case 0:
           lep = highest(h[1],20) +                            minMove/priceScale;
           sep = lowest(l[1],20) -                            minMove/priceScale;
           If seekLong and h >= lep then
           begin
               theoMP = 1;
               theoEX = maxList(lep,o) - 2 * atr;
//             print(d," entered long >> exit at                  ",theoEX," ",atr);
           end;
           If seekShort and l <= sep then
           begin
              theoMP = -1;
              theoEX = minList(sep,o) + 2 * atr;
           end;
           If theoMP <> 0 then
           begin
              state = 1;
              cantExitToday = True;
           end;

State 0 (Finite State Set Up)

The Switch/Case is a must-have structure in any programming language. What really blows my mind is that Python doesn’t have it. They claim its redundant to an if-then structure and it is, but it's so much easier to read and implement. Basically you use the Switch statement, and a variable name and based on the value of the variable will flow to whatever case the variable equates to. Here we are looking at state 0. In the CASE: 0 structure the computer calculates the lep and sep values – long and short entry levels. If you are flat then you are seeking for a long or a short position. If the high or low of the bar penetrates its respective trigger levels, then theoMP is set to 1 for long or -1 for short. TheoEX is then calculated based on the atr value on the day of entry. If theoMP is set to either 1 or -1, then we know a trade has just been triggered. The Finite State Machine then switches gears to State 1. Since State = 1 the next Case statement is immediately evaluated. I don’t want to exit on the same bar as I entered (wide bars can enter and exit during volatile times) so I use a variable cantExitToday. This variable delays the Case 1: evaluation by one bar.

State = 1 code:

   Case 1:
       If not(cantExitToday) then
       begin
          lxp = maxList(theoEX,lowest(l[1],10)-             minMove/priceScale);
          sxp =          minList(theoEX,highest(h[1],10)+minMove/priceScale);
          If theoMP = 1 and l <= lxp then
          begin
              theoMP = 0;
              seekLong = False;
              if lxp <= theoEX then
                   ltl = True
              Else
              ltl = False;
          end;
          If theoMP =-1 and h >= sxp then
          begin
              theoMP = 0;
              seekShort = False;
              if sxp >= theoEX then
                  ltl = True
              else
                  ltl = False;
          end;
          If theoMP = 0 then state = 0;
      end;
      cantExitToday = False;
end;

State = 1 (Switching Gears)

Once we have a theoretical position, then we only examine the code in the Case 1: module. On the subsequent bar after entry, the lxp and sxp (long exit and short exit prices) are calculated. Notice these values use maxList or minList to determine whichever is closer to the current market action – the 2N stop or the lowest/highest low/high for the past 10-daysLxp and sxp are assigned whichever is closer. Each bar’s high or low is compared to these values. If theoMP = 1, then the low is compared to lxp. If the low crosses below lxp, then things are set into motion. The theoMP is immediately set to 0 and seekLong is turned to False. If lxp <= a 2N loss, then ltl (last trade loser) is set to true. If not, then ltl is set to False. If theoMP = 0, then we assume a flat position, and switch the FSM back to State 0 and start looking for a new trade. The ltl variable is then used in the code to allow a real trade to occur.

Strategy Incorporates Our FSM Output

vars:N(0),mp(0),NLossAmt(0);
If barNumber = 1 then n = avgTrueRange(20);
if barNumber > 1 then n = (n*19 + trueRange)/20;

If useLTLFilter then
Begin
    if ltl then buy next bar at highest(h,20) +       minMove/priceScale stop;
    if ltl then sellShort next bar at lowest(l,20)     -minMove/priceScale stop;
end
Else
Begin
    buy next bar at highest(h,20) +                   minMove/priceScale stop;
    sellShort next bar at lowest(l,20) -               minMove/priceScale stop;
end;

mp = marketPosition;

If mp <> 0 and mp[1] <> mp then NLossAmt = 2 * n;

If mp = 1 then
Begin
    Sell("LL10-LX") next bar at lowest(l,10) -         minMove/priceScale stop;
    Sell("2NLS-LX") next bar at entryPrice -          NLossAmt stop;
end;
If mp =-1 then
Begin
    buyToCover("HH10-SX") next bar at                  highest(h,10) + minMove/priceScale stop;
    buyToCover("2NLS-SX") next bar at entryPrice+      NLossAmt stop;
end;

Strategy Code Using ltl filter

This code basically replicates what we did in the FSM, but places real orders based on the fact that the Last Trade Was A Loser (ltl.)

Does It Work – Only Trade After a 2N-Loss

Last Trade Loser In Action

Without Filter on the last 10-years in Crude Oil

With Filter on the last 10-years in Crude Oil

I have programmed this into my TradingSimula-18 software and will show a portfolio performance with this filter a little later at www.trendfollowingsystems.com.

I had to do some fancy footwork with some of the code due to the fact you can exit and then re-enter on the same bar. In the next post on this blog I will show you those machinations. With this template you should be able to recreate any last trade that was a loser mechanism and see if it can help out with your own trading algorithms. Shoot me an email with any questions.

George Pruitt

About the author

I have a degree in computer science from UNC-Asheville. I was the Director of Research for Futures Truth (magazine and CTA) for 31 years and have authored many articles in magazines and trade journals. I have written and co-written eight books: The Easing into EasyLanguage Series (four books): Foundation, Hi-Res, Advanced Topics and DayTrade edition. Older books published by John Wiley: The Ultimate Trading Guide, Building Winning Trading Systems with TradeStation (two editions), The Ultimate Algorithmic Trading System Toolbox, Trend Following Systems-A DIY Project: Batteries Included! My research is now focused on day-trading and longer-term trend following systems.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Learn To Code & Build Strategies
Using EasyLanguage. 

>