Tag Archives: EasyLanguage Code

Turn of the Month Trading Strategy [Stock Indices Only]

The System

This system has been around for several years.  Its based on the belief that fund managers start pouring money into the market near the end of the month and this creates momentum that lasts for just a few days.  The original system states to enter the market on the close of the last bar of the day if the its above a certain moving average value.  In the Jaekle and Tomasini book, the authors describe such a trading system.  Its quite simple, enter on the close of the month if its greater than X-Day moving average and exit either 4 days later or if during the trade the closing price drops below the X-Day moving average.

EasyLanguage or Multi-Charts Version

Determining the end of the month should be quite easy -right?  Well if you want to use EasyLanguage on TradeStation and I think on Multi-Charts you can’t sneak a peek at the next bar’s open to determine if the current bar is the last bar of the month.  You can try, but you will receive an error message that you can’t mix this bar on close with next bar.  In other words you can’t take action on today’s close if tomorrow’s bar is the first day of the month.  This is designed, I think, to prevent from future leak or cheating.  In TradeStation the shift from backtesting to trading is designed to be a no brainer, but this does provide some obstacles when you only want to do a backtest.

LDOM function – last day of month for past 15 years or so

So I had to create a LastDayOfMonth function.  At first I thought if the day of the month is the 31st then it is definitely the last bar of the month.  And this is the case no matter what.  And if its the 30th then its the last day of the month too if the month is April, June, Sept, and November.  But what happens if the last day of the month falls on a weekend.  Then if its the 28th and its a Friday and the month is blah, blah, blah.  What about February?  To save time here is the code:

Inputs: movAvgPeriods(50);
vars: endOfMonth(false),theDayOfWeek(0),theMonth(0),theDayOfMonth(0),isLeapYear(False);

endOfMonth = false;
theDayOfWeek = dayOfWeek(date);
theMonth = month(date);
theDayOfMonth = dayOfMonth(date);
isLeapYear = mod(year(d),4) = 0;

// 29th of the month and a Friday
if theDayOfMonth = 29 and theDayOfWeek = 5 then
endOfMonth = True;
// 30th of the month and a Friday
if theDayOfMonth = 30 and theDayOfWeek = 5 then
endOfMonth = True;
// 31st of the month
if theDayOfMonth = 31 then
endOfMonth = True;
// 30th of the month and April, June, Sept, or Nov
if theDayOfMonth = 30 and (theMonth=4 or theMonth=6 or theMonth=9 or theMonth=11) then
endOfMonth = True;
// 28th of the month and February and not leap year
if theDayOfMonth = 28 and theMonth = 2 and not(isLeapYear) then
endOfMonth = True;
// 29th of the month and February and a leap year or 28th, 27th and a Friday
if theMonth = 2 and isLeapYear then
Begin
If theDayOfMonth = 29 or ((theDayOfMonth = 28 or theDayOfMonth = 27) and theDayOfWeek = 5) then
endOfMonth = True;
end;
// 28th of the month and Friday and April, June, Sept, or Nov
if theDayOfMonth = 28 and (theMonth = 4 or theMonth = 6 or
theMonth = 9 or theMonth =11) and theDayOfWeek = 5 then
endOfMonth = True;
// 27th, 28th of Feb and Friday
if theMonth = 2 and theDayOfWeek = 5 and theDayOfMonth = 27 then
endOfMonth = True;
// 26th of Feb and Friday and not LeapYear
if theMonth = 2 and theDayOfWeek = 5 and theDayOfMonth = 26 and not(isLeapYear) then
endOfMonth = True;
// Memorial day adjustment
If theMonth = 5 and theDayOfWeek = 5 and theDayOfMonth = 28 then
endOfMonth = True;
//Easter 2013 adjustment
If theMonth = 3 and year(d) = 113 and theDayOfMonth = 28 then
endOfMonth = True;
//Easter 2018 adjustment
If theMonth = 3 and year(d) = 118 and theDayOfMonth = 29 then
endOfMonth = True;

if endOfMonth and c > average(c,movAvgPeriods) then
Buy("BuyDay") this bar on close;

If C <average(c,movAvgPeriods) then
Sell("MovAvgExit") this bar on close;
If BarsSinceEntry=4 then
Sell("4days") this bar on close;
Last Day Of Month Function and Strategy

All the code is generic except for the hard code for days that are a consequence of Good Friday.

All this code because I couldn’t sneak a peek at the date of tomorrow.  Here are the results of trading the ES futures sans execution costs for the past 15 years.

Last Day Of Month Buy If C > 50 Day Mavg

What if it did the easy way and executed the open of the first bar of the month.

If c > average(c,50) and month(d) <> month(d of tomorrow) then 
buy next bar at open;

If barsSinceEntry >=3 then
sell next bar at open;

If marketPosition = 1 and c < average(c,50) then
sell next bar at open;
Buy First Day Of Month
First Day of Month If C > 50 Day Mavg

The results aren’t as good but it sure was easier to program.

TradingSimula-18 Version

Since you can use daily bars we can test this with my TradingSimula-18 Python platform.  And we will execute on the close of the month.  Here is the snippet of code that you have to concern yourself with.  Here I am using Sublime Text and utilizing their text collapsing tool to hide non-user code:

Small Snippet of TS-18 Code

This was easy to program in TS-18 because I do allow Future Leak – in other words I will let you sneak a peek at tomorrow’s values and make a decision today.  Now many people might say this is a huge boo-boo, but with great power comes great responsibility.  If you go in with eyes wide open, then you will only use the data to make things easier or even doable, but without cheating.  Because you are only going to cheat yourself.  Its in your best interest do follow the rules.  Here is the line that let’s you leak into the future.

If isNewMonth(myDate[curBar+1])

The curBar is today and curBar+1 is tomorrow.  So I am saying if tomorrow is the first day of the month then buy today’s close.  Here you are leaking into the future but not taking advantage of it.  We all know if today is the last day of the month, but try explaining that to a computer.  You saw the EasyLanguage code.  So things are made easier with future leak, but not taking advantage of .

Here is a quick video of running the TS-18 Module of 4 different markets.

 

Super Combo Day Tradng System A 2020 Redo!

If you have some time on your hands and you want to build your own Frankenstein monster from a parts bin, here is your chance.  The Super Combo Day Trading System was originally published in my “Building Winning Trading Systems” book back in 2001.  I designed it to be more of a tutorial than a pure trading system.    You should be able to get the spare parts you need to create your own day trading system.  Back in 2001, I wanted to show how to control and monitor different entry and exit techniques in one complete algorithm.  The system was designed to day-trade the big SP and the results at the time looked promising.  Since the transition to the ES and the higher levels of volatility that we have seen over the years and the adoption of overnight trading,  the system hasn’t fared that well, but the concepts are still viable as an instructional tool today as they were 20 years ago.  EasyLanguage has been improved over this time period so the coding for the Super Combo can definitely take advantage of the new enhancements.

Here are the main premises of the logic:

  • take advantage of a buyEasier and shortEasier pattern setup
  • incorporate daily and 5-minute time frames in one chart
  • include a breakOut, failedBreakOut and reverseOnLiquidation trade entry techniques
  • monitor which signal is currently online and apply the correct exit signal
  • monitor profit and incorporate a break even stop
  • monitor time and incorporate a trailing stop
  • provide an interface into the logic via inputs

Okay here we go – there is quite a bit of code here so let’s divide an conquer by examining just one module at a time.  This first module includes the inputs and variables section plus once per day calculations.

[LegacyColorValue = true]; 

{Super Combo by George Pruitt - redo 2020
This intra-day trading system will illustrate the multiple data
handling capabilities of TradeStation. All pertinent buy and sell
calculations will be based on daily bars and actual trades will be
executed on 5-min bars. I have made most of the parameters input
variables}

Inputs:waitPeriodMins(30),initTradesEndTime(1430),liqRevEndTime(1200),
thrustPrcnt1(0.30),thrustPrcnt2(0.60),breakOutPrcnt(0.25),
failedBreakOutPrcnt(0.25),protStopPrcnt1(0.30),protStopPrcnt2(0.20),
protStopAmt(3.00),breakEvenPrcnt(0.50),avgRngLength(10);

Variables:averageRange(0),canTrade(0),buyEasierDay(FALSE),
sellEasierDay(FALSE),buyBOPoint(0),sellBOPoint(0),longBreakPt(0),
shortBreakPt(0),longFBOPoint(0),shortFBOPoint(0),barCount(0),buysToday(0),
sellsToday(0),mp(0),longLiqPoint(0),shortLiqPoint(0),
longLiqPoint1(0),shortLiqPoint1(0),intraTradeHigh(0),intraTradeLow(999999);


{Just like we did in the psuedo code -- let's start out with the daily
bar calculations. If Date <> Date[1] -- first bar of day}
if(Date <> Date[1]) then {save time by doing these calculations once per day}
begin
averageRange = Average(Range,10) of Data2; {Data 2 points to daily bars}

canTrade = 0;
if range of data2 < averageRange then canTrade = 1;

{use close of data2 - seems to be more accurate than CloseD(1)
buyEasierDay =Close of Data2 >= Close[1] of Data2;
sellEasierDay = Close of Data2 < Close[1] of Data2;

buyBOPoint = Open + thrustPrcnt1*averageRange;
sellBOPoint= Open - thrustPrcnt2*averageRange;

if(sellEasierDay) then
begin
sellBOPoint= Open - thrustPrcnt1*averageRange;
buyBOPoint = Open + thrustPrcnt2*averageRange;
end;

longBreakPt = HighD(1) + breakOutPrcnt*averageRange;
shortBreakPt= LowD(1) - breakOutPrcnt*averageRange;

shortFBOPoint = HighD(1) - failedBreakOutPrcnt*averageRange;
longFBOPoint= LowD(1) + failedBreakOutPrcnt*averageRange;

{Go ahead and initialize any variables that we may need later on in the day}

barCount = 0;
buysToday = 0;sellsToday = 0;{You can put multiple statements on one line}
end;
First Modules of SuperCombo 2020

Here I am just setting up the inputs and variables that I will need to execute the algorithm.  If you are using .D data then the code

if date <> date[1] then

is a valid test for the first bar of the day.  A new date will represent the beginning of the next day.  The code controlled by this if-then construct is only executed one time per day.  So if you can put the lion’s share of daily calculations here, then it should speed stuff up.  The first thing I do is calculate the average range of the last 10 daily bars.  I access this date from data2.  Can you build a loop and accumulate the difference between the HighD and LowD function calls?

  1. for i = 1 to 10 begin
  2.      sum = sum + (HighD(i) – LowD(i));
  3. end;

The HighD() and LowD() functions are EasyLanguage enhancements that can help eliminate the need for a multi-data chart.  However, if you do this, you will get an warning message that its not a good idea.  I have done this and it seems to work, but to be safe just use Data2.    Next I determine if there has been a narrow range or range compression by comparing yesterday’s range to the averageRange.  If so, then I allow trading.  This is an old filter that looks for range expansion after compression.  The concept of a buyDay and sellDay was originated in the 1930s by George W. Cole (correct me if I am wrong here).  I use this idea by comparing the prior two bars closing relationships.  If there has been an up close, then I consider the next day to be a buyEasier day.  If the opposite is true, then its a sellEasier day.   This system isn’t unidirectional and does allow buying  and shorting in the same session – hence the word easier.   Continuing I calculate the levels that if the market reaches will hopefully trigger a short term trend in that direction.  This is the once highly respected open range break out or ORBO.  This methodology has lost its luster over the last 10 years or so due to overnight trading and allowing pent up buying and selling to be expressed in the overnight sessions.  Twenty years ago it was still viable.  The next bit of code creates the break out levels based on the buyEasier or sellEasier days.   The thrust is calculated by multiplying the range by thrustPrcnt1 and thrustPrcnt2.

So that is method 1 – break out.  Hope the market breaks out and continues to the close.  I wish it were this easy.  Since its not, the second methodolgy, FailedBreakOut, is calculated.  This is also known as the “ClearOut” trade.   The market is pushed to take out all the buy stops and then pulled back for the professionals to feast on the amateurs.  SuperCombo tries to take advantage of this by calculating the two points to determine a failed break out.  On the long side, it is the two points the market rises up to and then falls back to.  If the market breaches the longBreakPt, then look to sellShort at the shortFBOPoint.    Here is the next module

{Now lets trade and manage on 5-min bars}

barCount = barCount + 1; {count the number of bars of intraday data}
if(barCount >= waitPeriodMins/BarInterval and canTrade = 1) then {have we waited long enough}
begin
if(MarketPosition = 1) then buysToday = 1;
if(MarketPosition =-1) then sellsToday= 1;

if(buysToday = 0 and Time < initTradesEndTime) then
Buy("LBreakOut") next bar at buyBOPoint stop;

if(sellsToday= 0 and Time < initTradesEndTime) then
SellShort("SBreakout") next bar at sellBOPoint stop;

if(highD(0) > longBreakPt and sellsToday = 0 and Time < initTradesEndTime) then
SellShort("SfailedBO") next bar at shortFBOPoint stop;
if(lowD(0) < shortBreakPt and buysToday = 0 and Time < initTradesEndTime) then
Buy("BfailedBO") next bar at longFBOPoint stop;
Monitor Market Action and Place Trades Accordingly

 

if(barCount>= waitPeriodMins/BarInterval and canTrade = 1) then

Forces the logic to flow only if canTrade is 1 and we have waited for amateur hour to be completed – well 30 minutes to be accurate.  Is the first hour really amateur hour?  I don’t think this applies, but if you think it does this is how you control trading prior to the completion of this period.  By dividing by BarInterval and counting each bar you can generalize this code for any time resolution.   If MarketPosition is 1 then you know you entered a long position and the opposite is true for short positions.  Only place the break out orders if time is less than initTradesEndTime.  If the market penetrates the long and shortBreakPts, then prepare to take advantage of a failed breakout.  Only go short if a short position has not already been entered – same for longs.  So, this logic places the breakOut and failedBreakOut orders.  Now for the last module.

{The next module keeps track of positions and places protective stops}

mp = marketPosition;
if(MarketPosition = 1) then
begin
longLiqPoint = EntryPrice-protStopPrcnt1*averageRange;
longLiqPoint = MinList(longLiqPoint,EntryPrice - protStopAmt);
longLiqPoint1 = EntryPrice - protStopPrcnt2*averageRange;
longLiqPoint1 = MinList(longLiqPoint1,EntryPrice - protStopAmt);
if Maxpositionprofit >= breakEvenPrcnt*averageRange*bigPointValue then
begin
longLiqPoint = EntryPrice; {Breakeven trade}
longLiqPoint1 = EntryPrice; {Breakeven trade}
end;
if(Time >= initTradesEndTime) then
begin
longLiqPoint = MaxList(longLiqPoint,Lowest(Low,3)); {Trailing stop}
longLiqPoint1 = MaxList(longLiqPoint1,Lowest(Low,3)); {Trailing stop}
end;
if(Time < liqRevEndTime and sellsToday = 0 and
longLiqPoint <> EntryPrice and BarsSinceEntry >= 4) then
SellShort("LongLiqRev") next bar at longLiqPoint stop;

Sell("LongLiq-BO") from entry("LBreakOut") next bar at longLiqPoint stop;
Sell("LongLiq-FBO") from entry("BFailedBO") next bar at longLiqPoint stop;
Sell("LongLiq-RLoss") from entry("ShortLiqRev") next bar at longLiqPoint1 stop;
end;
if(MarketPosition =-1) then
begin
shortLiqPoint = EntryPrice+protStopPrcnt1*averageRange;
shortLiqPoint = MaxList(shortLiqPoint,EntryPrice + protStopAmt);
shortLiqPoint1 = EntryPrice + protStopPrcnt2*averageRange;
shortLiqPoint1 = MaxList(shortLiqPoint1,EntryPrice + protStopAmt);
if maxPositionProfit >= breakEvenPrcnt*averageRange*bigPointValue then
begin
shortLiqPoint = EntryPrice; {Breakeven trade}
shortLiqPoint1 = EntryPrice;
end;
if(Time >= initTradesEndTime) then
begin
shortLiqPoint = MinList(shortLiqPoint,Highest(High,3)); {Trailing stop}
shortLiqPoint1 = MinList(shortLiqPoint1,Highest(High,3)); {Trailing stop}
end;
if(Time < liqRevEndTime and buysToday = 0 and
shortLiqPoint <> EntryPrice and BarsSinceEntry >= 4) then
Buy("ShortLiqRev") next bar at shortLiqPoint stop;

BuyToCover("ShortLiq-BO") from entry("SBreakOut") next bar at shortLiqPoint stop;
BuyToCover("ShortLiq-FBO") from entry("SFailedBO") next bar at shortLiqPoint stop;
BuyToCover("ShortLiq-RLoss") from entry("LongLiqRev") next bar at shortLiqPoint1 stop;
end;
end;
SetExitOnClose;
TradeManagement (Enter on Stop Loss or Not?)

This code looks a little hairy, but its not.  Let’s just look at the long side logic to save time here.  First let’s calculate the LongLiqPoints (1 and 2.)  Twenty years ago I thought it would be better to have a smaller stop for entries that occurred on a LiquidationReversal.  Oh yeah that code is in here to.  Back in the day I wanted to make sure the stop was at least 3 handles – ha, ha, ha – no really I am serious.  Really.  Stop laughing!! That code could be eliminated.  After calculating these two points I start to monitor profit and if it reaches a predetermined level I pull the the longLiqPoints toa  BreakEven stop.  If you are fortunate to still be in a trade after initTradesEndTime, then I start trailing the stop by the lowest low of the last 3 five minute bars – I don’t want to turn a small winner into a loser.  Now this is the fun stuff.

  1. if(Time < liqRevEndTime and sellsToday = 0 and
    longLiqPoint <> EntryPrice and BarsSinceEntry >= 4) then
  2.      SellShort(“LongLiqRev”) next bar at longLiqPoint stop;

If time is less than liqRevEndTime and BarsSinceEntry, then reverse and go short at the longLiqPoint stop.  Do this instead of liquidating.  I thought if the market reversed course quickly, then I wanted to take advantage of this counter trend move.  Eliminating this to see if it has any impact would be where I would start to play around with the template.  Okay now the liquidations based on from Entry take place next.  If I am long from a “ShortLiqRev“, then I use longLiqPoint1 instead of longLiqPoint.  Okay that last part was the kitchen sink.  Now you have enough code to make your own day trading system – really too much code, but you should be able to hobble something together from these parts.  Let me know if you can create your own Frankenstein monster.  I will update the parameters to see if there is any hope to the system as a whole.  Keep checking back for updated performance metrics.  Best to all and be safe!

 

 

How to Keep Track of BuysToday and SellsToday

The Useful MP

We all know how to use the reserved word/function MarketPosition – right?  Brief summary if not – use MarketPosition to see what your current position is: -1 for short, +1 for long and 0 for flat.  MarketPosition acts like a function because you can index it to see what you position was prior to the current position – all you need to do is pass a parameter for the number of positions ago.  If you pass it a one (MarketPosition(1)) then it will return the your prior position.  If you define a variable such as MP you can store each bars MarketPosition and this can come in handy.

mp = marketPosition;

If mp[1] <> 1 and mp = 1 then buysToday = buysToday + 1;
If mp[1] <> -1 and mp = -1 then sellsToday = sellsToday + 1;
Keeping Track of Buy and Sell Entries on Daily Basis

The code compares prior bar’s MP value with the current bar’s.   If there is a change in the value, then the current market position has changed.   Going from not 1 to 1 indicates a new long position.  Going from not -1 to -1 implies a new short.  If the criteria is met, then the buysToday or sellsToday counters are incremented.  If you want to keep the number of buys or sells to a certain level, let’s say once or twice,  you can incorporate this into your code.

If  time >= startTradeTime and t < endTradeTime and 
buysToday < 1 and
rsi(c,rsiLen) crosses above rsiBuyVal then buy this bar on close;
If time >= startTradeTime and t < endTradeTime and
sellsToday < 1 and
rsi(c,rsiLen) crosses below rsiShortVal then sellShort this bar on close;
Using MP to Keep Track of BuysToday and SellsToday

This logic will work most of the time, but it depends on the robustness of the builtin MarketPosition function Look how this logic fails in the following chart:

I didn't want entries in the same direction per day!
I only wanted 1 short entry per day!

MarketPosition Failure

Failure in the sense that the algorithm shorted twice in the same day.  Notice on the first trade how the profit objective was hit on the very next bar.  The problem with MarketPosition is that it only updates at the end of the bar one bar after the entry.  So MarketPosition stays 0 during the duration of this trade.  If MarketPosition doesn’t change then my counter won’t work.  TradeStation should update MarketPosition at the end of the entry bar.  Alas it doesn’t work this way.  I figured a way around it though.  I will push the code out and explain it later in more detail.

Input: rsiLen(14),rsiBuyVal(30),rsiShortVal(70),profitObj$(250),protStop$(300),startTradeTime(940),endTradeTime(1430);

Vars: mp(0),buysToday(0),sellsToday(0),startOfDayNetProfit(0);

If d <> d[1] then
Begin
buysToday = 0;
sellsToday = 0;
startOfDayNetProfit = netProfit;
end;

{mp = marketPosition;

If mp[1] <> 1 and mp = 1 then buysToday = buysToday + 1;
If mp[1] <> -1 and mp = -1 then sellsToday = sellsToday + 1;}

If entriesToday(date) > buysToday + sellsToday then
Begin
If marketPosition = 1 then buysToday = buysToday + 1;
If marketPosition =-1 then sellsToday = sellsToday + 1;
If marketPosition = 0 then
Begin
if netProfit > startOfDayNetProfit then
begin
if exitPrice(1) > entryPrice(1) then buysToday = buysToday + 1;
If exitPrice(1) < entryPrice(1) then sellsToday = sellsToday + 1;
end;;
if netProfit < startOfDayNetProfit then
Begin
if exitPrice(1) < entryPrice(1) then buysToday = buysToday + 1;
If exitPrice(1) > entryPrice(1) then sellsToday = sellsToday + 1;
end;
end;
print(d," ",t," ",buysToday," ",sellsToday);
end;

If time >= startTradeTime and t < endTradeTime and
buysToday < 1 and
rsi(c,rsiLen) crosses above rsiBuyVal then buy this bar on close;
If time >= startTradeTime and t < endTradeTime and
sellsToday < 1 and
rsi(c,rsiLen) crosses below rsiShortVal then sellShort this bar on close;

SetProfittarget(profitObj$);
SetStopLoss(protStop$);

SetExitOnClose;
A Better Buy and Short Entries Counter

TradeStation does update EntriesToday at the end of the bar so you can use this keyword/function to help keep count of the different type of entries.  If MP is 0 and EntriesToday increments then you know an entry and an exit has occurred (takes care of the MarketPosition snafu) – all you need to do is determine if the entry was a buy or a sell.  NetProfit is also updated when a trade is closed.   I establish the StartOfDayNetProfit on the first bar of the day (line 9 in the code) and then examine EntriesToday and if NetProfit increased or decreased.  EntryPrice and ExitPrice are also updated at the end of the bar so I can also use them to extract the information I need.   Since MarketPosition is 0  I have to pass 1 to the EntryPrice and ExitPrice functions – prior position’s prices.  From there I can determine if a Long/Short entry occurred.  This seems like a lot of work for what you get out of it, but if you are controlling risk by limiting the number of trades (exposure) then an accurate count is so very important.

An alternative is to test on a higher resolution of data – say 1 minute bars.  In doing this you give a buffer to the MarketPosition function – more bars to catch up.

 

Original Camarilla EasyLanguage Code [Correction]

Camarilla – A group of confidential, often scheming advisers; a cabal.

An attentive reader of this blog, Walter Baker,  found some typos in my code.  I have corrected them in the code section – if you have used this code make sure you copy and paste the code in its entirety into your EasyLanguage editor and replace your prior version.

I wanted to elaborate on the original version of Camarilla.  The one that users have been downloading from this website is pure reversion version.  The Camarilla Equation was by created by Nick Scott, a bond day trader, in 1989.  The equation uses just yesterday’s price action to project eight support/resistance price levels onto today’s trading action.  These levels, or advisers, as the name of the equation suggests provides the necessary overlay to help predict turning points as well as break outs.  Going through many charts with the Camarilla indicator overlay it is surprising how many times the market does in fact turn at one of these eight price levels.  The equations that generate the support/resistance levels are mathematically simple:

 

Resistance #4 = Close + Range * 1.1 / 2;

Resistance #3 = Close + Range * 1.1/4;

Resistance #2 = Close + Range * 1.1/6;

Resistance #1 = Close + Range * 1.1/12;

 

Support #1 = Close – Range * 1.1/12;

Support #2 = Close – Range * 1.1/6;

Support #3 = Close – Range * 1.1/4;

Support #4 = Close – Range * 1.1/2;

 

The core theory behind the equation and levels is that prices have a tendency to revert to the mean.  Day trading the stock indices would be easy if price broke out and continued in that direction throughout the rest of the day.  We all know that “trend days” occur very infrequently on a day trade basis; most of the time the indices just chop around without any general direction.  This is where the Camarilla can be effective.  Take a look at the following chart [ ES 5-minute day session] where the indicator is overlaid. and how the strategy was able to take advantage of the market’s indecisiveness.  This particular example shows the counter-trend nature of the Camarilla.  The original Camarilla looked at where the market opened to make a trading decision.  The chart below is an adapted version of the one I send out when one registers on for the download.   I thought it would be a good idea to show the original that incorporates a break out along with the counter trend mechanism.  I will go over the code in the next post.  You can copy the code below and paste directly into you EasyLanguage editor.

Camarilla at its Best!
Carmarilla in Reversion Mode

Original Camarilla rules:

  • If market opens between R3 and R4 go with the break out of R4.  This is the long break out part of the strategy.
  • If market opens between R3 and S3 then counter trend trade at the R3 level.  In other words, sell short at R3.  If the market moves down, then buy S3.  As you can see this is the mean reversion portion of the strategy.
  • If market open between S3 and S4 go with the break out of S4 – the short break out method.
  • Stops are placed in the following manner:
    • If long from a R4 break-out, then place stop at R3.
    • If short from a S4 break-out, then place stop at S3.
    • If long from a R3 countertrend, then place stop at R4.
    • If short from a S3 countertrend, then place stop at S4.
  • Profit objectives can be placed at opposite resistance/support levels:
    • If short from a R3 countertrend, then take profits at S1, S2, or S3.
    • If long from a S3 countertrend, then take profits at R1, R2, or R3.

Profit objectives for all trades can be a dollar, percent of price of ATR multiple.

Example of Camarilla Break Out Trade from S4
Camarilla Break Out
inputs: endTradetime(1530);
vars: R1(0),R2(0),R3(0),R4(0),S1(0),S2(0),S3(0),S4(0),pivotPoint(0),myAvg(0);
vars: buyTrig(0),sellTrig(0),waitBar(0),s3Pen(0),r3Pen(0),s4Pen(0),r4Pen(0),s2Pen(0),r2Pen(0);
vars: buysToday(0),sellsToday(0);
vars: s3_s4(0),s2_s3(0),s1_s2(0),s4_s5(0);
vars: r1_r2(0),r2_r3(0),r3_r4(0),r4_r5(0);
vars: r1_s1(0),r3_s3(0),r4_s4(0),r5_s5(0);

if date <> date[1] then
begin
buyTrig = 0;
sellTrig = 0;
waitBar = 0;

s3Pen = 0;
r3Pen = 0;
s4Pen = 0;
r4Pen = 0;
s2Pen = 0;
r2Pen = 0;

buysToday = 0;
sellsToday = 0;

r4_r5 = 0;
r3_r4 = 0;
r2_r3 = 0;
r1_r2 = 0;

r1_s1 = 0;
r3_s3 = 0;
r4_s4 = 0;
r5_s5 = 0;

s1_s2 = 0;
s2_s3 = 0;
s3_s4 = 0;
s4_s5 = 0;

end;

waitBar = waitBar + 1;

R4 = CloseD(1)+(HighD(1)-LowD(1)) * 1.1 / 2;
R3 = CloseD(1)+(HighD(1)-LowD(1)) * 1.1/4;
R2 = CloseD(1)+(HighD(1)-LowD(1)) * 1.1/6;
R1 = CloseD(1)+(HighD(1)-LowD(1)) * 1.1/12;
S1 = CloseD(1)-(HighD(1)-LowD(1)) * 1.1/12;
S2 = CloseD(1)-(HighD(1)-LowD(1)) * 1.1/6;
S3 = CloseD(1)-(HighD(1)-LowD(1)) * 1.1/4;
S4 = CloseD(1)-(HighD(1)-LowD(1)) * 1.1/2;

if openD(0)<= s4 then s4_s5 = 1;

If openD(0)> s4 and openD(0) <= s3 then s3_s4 = 1;
If openD(0)> s3 and openD(0) <= s2 then s2_s3 = 1;
If openD(0)> s2 and openD(0) <= s1 then s1_s2 = 1;

If openD(0)> s1 and openD(0) <= r1 then r1_s1 = 1;

If openD(0)> r1 and openD(0) <= r2 then r1_r2 = 1;
If openD(0)> r2 and openD(0) <= r3 then r2_r3 = 1;
If openD(0)> r3 and openD(0) <= r4 then r3_r4 = 1;

If openD(0)> r4 then r4_r5 = 1;

if openD(0) < r3 and openD(0) > s3 then r3_s3 = 1;
If openD(0) < r4 and openD(0) > s4 then r4_s4 = 1;


if time < endTradeTime and time > 930 then
begin


if r3_r4 = 1 and entriesToday(date) < 3 and c < r4 then buy("R4-BrkOut") next bar at r4 stop;
if s3_s4 = 1 and entriesToday(date) < 3 and c > s4 then sellShort("S4-BrkOut") next bar at s4 stop;

if c > r2 then r2Pen = 1;
if c > r3 then r3Pen = 1;
if c > r4 then r4Pen = 1;

if r3_s3 = 1 and r3Pen = 1 and c > r3 and entriesToday(date) < 3
then sellShort("R3Sell") next bar at r3 stop;

if r4Pen = 1 and c < r4 then r4Pen = 0;
if r3Pen = 1 and c < r3 then r3Pen = 0;
if r2Pen = 1 and c < r2 then r2Pen = 0;

if c < r1 then
begin
r2Pen = 0;
r3Pen = 0;
r4Pen = 0;
end;
if c > s1 then
begin
s2Pen = 0;
s3Pen = 0;
s4Pen = 0;
end;

if c < s2 then s2Pen = 1;
if c < s3 then s3Pen = 1;
if c < s4 then s4Pen = 1;

if r3_s3 = 1 and s3Pen = 1 and c < s3 and entriesToday(date) < 3 then
buy("S3Buy") next bar at s3 stop;

if s4Pen = 1 and c > s4 then s4Pen = 0;
if s3Pen = 1 and c > s3 then s3Pen = 0;
if s2Pen = 1 and c > s2 then s2Pen = 0;

if marketPosition = 1 then
begin
sell from entry("S3Buy") next bar at s4 stop;
sell from entry("R4-BrkOut") next bar at r3 stop;
end;

if marketPosition = -1 then
begin
buyToCover from entry("R3Sell") next bar at r4 stop;
buyToCover from entry("S4-BrkOut") next bar at s3 stop;
end;


end;

setExitOnClose;
Camarilla Strategy EasyLanguage Source

Using Strings in EL for multi-step System

This little strategy uses EasyLanguage’s string manipulation to keep track of a multi-step, mutli-criteria, multi-state trade entry. You don’t buy until the buyString is equal to “BUY”. The sell side is just the opposite. When you program a multi-step entry you also need to build a reset situation. In the case of this system you reset the string to null(“”) when the price dips back down below the 9 day moving average. After resetting the process starts over again.


{Use curly brackets for mult-line
 comments
 
 This system needs three criteria to be met
 before a trade is initiated
 Buy Criteria 1:  C > 9 day movAvg - trend Up
 Buy Criteria 2:  H = HighestHigh 10 days - break Out
 Buy Criteria 3:  C < C[2] - retracement }
 
 vars:buyString(""),sellString("");
 
 
 if marketPosition = 0 then {If flat then reset strings}
 begin
 	buyString = "";
 	sellString = "";
 end;
 
 if c >= average(c,9) then buyString = "B";  //First criteria met
 if c < average(c,9) then buyString = "";
 
 if c > average(c,9) then sellString = "";
 if c <= average(c,9) then sellString = "S"; 
 
 if buyString = "B" then
 begin
 	if h > highest(h,10)[1] then buyString = buyString + "U"; //Second Criteria met
 end;
 
 if buyString = "BU" then
 begin
 	if c < c[2] then buyString = buyString + "Y"; //Third criteria met
 end;
 
 if buyString = "BUY" then buy ("BuyString") next bar at open; //Read BUY
 
 if sellString = "S" then
 begin
 	if l > lowest(l,10)[1] then sellString = sellString + "E";
 end;
 
 if sellString = "SE" then
 begin
 	if c > c[2] then sellString = sellString + "LL";
 end;
 
 if sellSTring = "SELL" then sellShort ("sellString") next bar at open; 
 setStopLoss(1000);

 SetPercentTrailing(1000, 30);  

King Keltner Source Code

Looking for a trend follower – give this one a try!

 [LegacyColorValue = true]; 

{King Keltner Program
King Keltner by George Pruitt -- based on trading system presented by Chester Keltner
 -- an example of a simple, robust and effective strategy}

Inputs: avgLength(40),atrLength(40);
Vars: upBand(0),dnBand(0),liquidPoint(0),movAvgVal(0);

movAvgVal = Average((High + Low + Close)/3.0,avgLength);
upBand = movAvgVal + AvgTrueRange(atrLength);
dnBand = movAvgVal - AvgTrueRange(atrLength);

{Remember buy stops are above the market and sell stops are below the market
 -- if the market gaps above the buy stop, then the order turns into a market order
 vice versa for the sell stop}

if(movAvgVal > movAvgVal[1]) then Buy ("KKBuy") tomorrow at upBand stop;
if(movAvgVal < movAvgVal[1]) then Sell("KKSell")tomorrow at dnBand stop;

liquidPoint = movAvgVal;

if(MarketPosition = 1) then Sell tomorrow at liquidPoint stop;
if(MarketPosition =-1) then BuyTocover tomorrow at liquidPoint stop;