Tag Archives: TradeStation

Updated Pattern Smasher in EasyLanguage

Update To Original Pattern Smasher

What will you learn : string manipulation, for-loops, optimization

Before proceeding I would suggest reading my original post on this subject.    If you believe the relationship of the last few bars of data can help determine future market direction, then this post will be in you wheel house.  Another added benefit is that you will also learn some cool EasyLanguage.

Original post was limited to four day patterns!

This version is limitless (well not really, but pretty close).  Let’s stick with the original string pattern nomenclature (+ + – – : two up closes followed by two down closes.)  Let’s also stick with our binary pattern representation:

Pattern # 2^3 2^2 2^1 1
3 0 0 1 1
4 0 1 0 0
5 0 1 0 1
6 0 1 1 1

Remember a 0 represents a down close and a 1 represents an up close.  We will deviate from the original post by doing away with the array and stick with only strings (which are really just arrays of characters.)  This way we won’t have to worry about array manipulation.

How to create a dynamic length string pattern

This was the difficult part of the programming.  I wanted to be able to optimize 3, 4 and 5 day patterns and I wanted to control this with using just inputs.  I discovered that pattern three is different in a three day pattern than it is in a four day pattern: in a three day pattern it is 011 or – + + and in a four day pattern it is 0011 or – – + +.  Since I am counting 0’s as down closes, pattern #3 depends on the ultimate size of the pattern string.  No worries I will have eventually have another version where I utilize a different value for down closes and we can then have holes in our string patterns.  But I digress – so to differentiate the patterns based on the pattern length I included a maxPatternLen input.  So if maxPatternLen is three and we are trying to match pattern #3 then we will be looking for 011 and not 0011.  That was an easy fix.  But then I wanted to build a string pattern based on this input and the pattern number dynamically.  Here is some psuedo code on how I figured it out.


{Psuedo code to translate pattern number into binary number}
patternNumber = 3
maxPatternLen = 3

numBits = 0    						// stick with binary representation
testValue = 0						// temporary test value
numBits = maxPatternLen-1  			// how many bits will it take to get to the
									// center of - or numBits to represent max
									// number of patterns or 2^numBits
currentBit =numBits					// start wit current bit as total numBits

value1 = patternOptTest				// value1 represents current pattern number
testString = ""  					// build test string from ground up


for icnt = numBits downto 0			//building string from left to right
begin       						// notice keyword downto
	if power(2,currentBit) > value1 then  // must use power function in EL
	begin							// if the very far left bit value > 
		testString = testString + "-"	  // patten number then plug in a "-"
	end
	else
	begin							// else plug in a "+" and deccrement by
		testString = testString + "+"	 // that bits value - if its the 3rd bit
	value1 = value1 - power(2,currentBit)// then decrement by 8
	end;
	currentBit = currentBit - 1		// move onto the next bit to the right
end;
Pseudocode for Binary Representation of Pattern #

Now if you want to optimize then you must make sure your pattern number search space or range can be contained within maxPatternLen.  For example, if you want to test all the different combinations of a four day pattern, then your maxPatternLen would naturally be four and you would optimize the pattern number from 0 to 15.  Don’t use 1-16 as I use zero as the base.  A five day pattern would include the search space from 0 – 31.  The rest of the code was basically hacked from my original post.   Here is the rest of the code to do optimizations on different length pattern strings.  Notice how I use strings, for-loops and comparisons.

input: buyPattern("+++-"),sellPattern("---+"),patternOptimize(True),patternOptTest(7),maxPatternLen(3),patternOptBuySell(1),
	   stopLoss$(2000),profitTarg$(2000),holdDays(5);
vars: buyPatternString(""),sellPatternString(""),buyPatternMatch(""),sellPatternMatch(""),numBits(0),testValue(0),currentBit(0),
      remainder(0),value(0),icnt(0),testString(""),numCharsInBuyPattern(0),numCharsInSellPattern(0);
vars:okToBuy(false),okToSell(false);

buyPatternMatch = buyPattern;
sellPatternMatch = sellPattern;
numCharsInBuyPattern = strLen(buyPatternMatch);
numCharsInSellPattern = strLen(sellPatternMatch);

If patternOptimize then
begin
	numBits = 0;
    testValue = 0;
    value = maxPatternLen;
    numBits = maxPatternLen-1;  
    currentBit =numBits;
    remainder = patternOptTest;
    testString = "";
    for icnt = numBits downto 0
    begin       
        if power(2,currentBit) > value1 then
        begin
            testString = testString + "-";
        end
        else
        begin
            testString = testString + "+";
            remainder = remainder - power(2,currentBit);
        end;
        currentBit = currentBit - 1;
	end;
	numCharsInBuyPattern = maxPatternLen;
	numCharsInSellPattern = maxPatternLen;
	if patternOptBuySell = 1 then
	Begin
		buyPatternMatch = testString;
		sellPatternMatch = "0";
	end;
	If patternOptBuySell = 2 then
	Begin
		buyPatternMatch = "0";
		sellPatternMatch = testString;
	end;
end;
	

buyPatternString = "";
sellPatternString = "";

For icnt = numCharsInBuyPattern-1 downto 0
Begin
	If close[icnt] >= close[icnt+1] then buyPatternString = buyPatternString + "+";
	If close[icnt] < close[icnt+1] then buyPatternString = buyPatternString + "-";
end;
For icnt = numCharsInSellPattern-1 downto 0
Begin
	If close[icnt] >= close[icnt+1] then sellPatternString = sellPatternString + "+";
	If close[icnt] < close[icnt+1] then sellPatternString = sellPatternString + "-";
end;


okToBuy = false;
okToSell = false;

if buyPatternMatch <> "" then
	If buyPatternString = buyPatternMatch then okToBuy = true;
If buyPatternMatch = "" then
	okToBuy = true;
If sellPattern <> "" then
	If sellPatternString = sellPatternMatch then okToSell = true;
If sellPatternMatch = "" then
	okToSell = true;
	
If okToBuy then buy next bar at open;
If okToSell then sellshort next bar at open;

If marketPosition = 1 and barsSinceEntry > holdDays then sell next bar at open;
If marketPosition = -1 and barsSinceEntry > holdDays then buytocover next bar at open;

setStopLoss(stopLoss$);
setProfitTarget(profitTarg$);

If lastBarOnChart then print(d," ",buyPatternMatch);
Final Version of New Pattern Smasher

Also see how I incorporate a profit target and protective stop.  I use the built in BarsSinceEntry function to count the number of days I am in a trade so I can utilize a time based exit.  Here is an interesting equity curve I developed using a two day pattern ( – –) to go long.

Register on the website and I will email you an ELD of the improved Pattern Smasher.  Or just shoot me an email.

 

 

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.

 

A Slightly More Eloquent Approach to Programming Our Pyramiding E-Mini DayTrading Algorithm.

Okay let’s see how I was able to add some eloquence to the brute force approach to this pyramiding algorithm.  The original code included multiple entry directives and a ton of hard coded numerical values.   So let me show you how I was able to refine the logic/code and in doing so make it much more flexible.  We might lose a little bit of the readability, but we can compensate by using extra commentary.

First off, let’s add flexibility by employing input variables.  In this case, we need to inform the algorithm the distance from the open to add additional positions and the max number of entries allowed for the day.

inputs : pyramidDistance(5),maxDailyEntries(3);

Now we need to set somethings up for the first bar of the day.  Comparing the date of today with the date of yesterday is a good way to do this.

if d<>d[1] then 
begin
	canSell = true;
	sellMult = 1;
	sellStop = -999999;
	entries = 0;
end;
First bar of the day housekeeping.

Here is a neat way to keep track of the number of entries as they occur throughout the trading day.  Remember the function EntriesToday(date) will not provide the information we need.

mp = marketPosition * currentShares;

if mp[1] <> mp and mp <> 0 then entries = entries + 1;
How to track the number of entries for today.

If the last bar’s mp[1] is not equal to the current bar’s mp then and mp is not equal to zero then we know we have added on another entry.  Okay now let’s think about eliminating the “brute force” approach.

Instead of placing multiple order entry directives I  only want to use one with a variable stop level.  This stop level will be guided by the variable SellMult.  We start the day with a wacky sell stop level and then calculate it based on the SellMult variable and PyramidDistance input.

if low <= sellStop  then
begin
	sellMult = sellMult + 1;
end;

sellStop = openD(0) - sellMult * pyramidDistance;
Calculate and adapt sell stop level as we go along.

So on the first bar of the day the sellStop = openD(0) – sellMult * pyramidDistance or sellStop = openD(0) – 1 * 5.  Or 5 handles below the open.  Note you an change the pyramidDistance input and make it three to match the previous examples.

if entries = maxDailyEntries then canSell = false;
if time < sess1EndTime and canSell then sellShort 1 contract next bar at sellStop stop;
if mp <=-1 {and barsSinceEntry > 0} then buyToCover next bar at sellStop + 2* pyramidDistance stop;

setexitonclose;
That's it! Pretty simple isn't it?

Ok, we need to tell the computer to turn off the ability to place orders if one of two things happens:  1) we have reached the maxDailyEntries or 2) time >= sess1EndTime.    You could make the time to stop entering trades an input as well.  If neither criteria applies then place an order to sellShort at our sellStop level.   If price goes below our sell stop level then we know we have been filled and the new sellStop level needs to be recalculated.  See how we use a calculation to adapt the stop level with a single order placement directive?  This is where the eloquence comes into play.  QED.

Now you code the opposite side and then see if you can make money  (hypothetically speaking of course) with it.  If you think about it, why does this not work.  And the not so obvious reason is that it trades too much.  Other than trading too much it makes perfect sense – buy or sell by taking a nibbles at the market.  If the market takes off then take a big bite.  The execution costs of the nibbles are just way too great.  So we need to think of a filtering process to determine when it is either better to buy or sell or when to trade at all.  Good Luck with this ES [emini S&P ]day trading algorithm!

inputs : pyramidDistance(5),maxDailyEntries(3);
vars: mp(0),icnt(0),sellStop(0),sellMult(0),canSell(true),entries(0);

if d<>d[1] then 
begin
	canSell = true;
	sellMult = 1;
	sellStop = -999999;
	entries = 0;
end;

mp = marketPosition * currentShares;

if mp[1] <> mp and mp <> 0 then entries = entries + 1;
if mp[1] = -1 and mp[0] = 0 then canSell = false;
if time > 1430 then canSell = false;

if low <= sellStop  then
begin
	sellMult = sellMult + 1;
end;

sellStop = openD(0) - sellMult * pyramidDistance;
if entries = maxDailyEntries then canSell = false;
if time < sess1EndTime and canSell then sellShort 1 contract next bar at sellStop stop;
if mp <=-1 {and barsSinceEntry > 0} then buyToCover next bar at sellStop + 2* pyramidDistance stop;

setexitonclose;
Much More Flexible Code

EasyLanguage Code for Pyramiding a Day-Trading System w/video [PART-2]

 

Check out the latest video on Pyramiding.

Here is the finalized tutorial on building the pyramiding ES-day-trade system that was presented in the last post.

I will admit this video should be half as long as the end result.  I get a bit long-winded.  However, I think there are some good pointers that should save you some time when programming a similar system.

EasyLanguage Source:

Here is the final code from the video:

vars: mp(0),lastTradePrice(0),canSell(true);

mp = marketPosition * currentContracts;

if date[0] <> date[1] then
begin
	canSell = true;  // canSell on every day
end;

if mp = -1 then canSell = false; // one trade on - no more
if time > 1430 then canSell = false; //no entries afte 230 central

if mp = 0 and canSell = true then sellShort next bar at OpenD(0) - 3 stop;

if mp = -1 then sellShort next bar at OpenD(0) - 6 stop; //add 1
if mp = -2 then sellShort next bar at OpenD(0) - 9 stop; //add 2

if mp = -1 then lastTradePrice = OpenD(0) - 3; //keep track of entryPrice
if mp = -2 then lastTradePrice = OpenD(0) - 6;
if mp = -3 then lastTradePrice = OpenD(0) - 9;


if mp <> 0 then buyToCover next bar at lastTradePrice + 3 stop; // 3 handle risk on last trade

// next line provides a threshold prior to engaging trailing stop
if mp = -3 and barsSinceEntry > 0 and lowD(0) < lastTradePrice - 3 then buyToCover next bar at lowD(0) + 3 stop;

setExitOnClose;
EasyLanguage for Pyramiding and Day-Trading ES

What we learned here:

  • can’t use entriesToday(date) to determine last entry price
  • must use logic to not issue an order to execute on the first bar of the next day
  • mp = marketPosition * currentContracts is powerful stuff!

In the next few days, I will publish the long side version of this code and also a more eloquent approach to the programming that will allow for future modifications and flexibility.

Let me know how it works out for you.

Take this code and add some filters to prevent trading every day or a filter to only allow long entries!

Don’t Fool Yourself – Limitations of Back Testing with Daily Data [EasyLanguage]

Which equity curve do you like best? (created with EasyLanguage script) This one…

Or this one?

Obviously the first one.  Even though it had a substantial draw down late in the test.  What if I told you that the exact same system logic generated both curves?  Here is the EasyLanguage code for this simple system.

Buy next bar at open of next bar + .25 *avgTrueRange(10) stop;
Sellshort next bar at open of next bar - .25*avgTrueRange(10) stop;

setStopLoss(500);
setProfitTarget(1000);
Open Range Break Out with Profit and Loss Objective

This algorithm relies heavily on needing to know which occurred first: the high or the low of the day.   The second chart tells the true story because it looks inside the daily bar to see what really happened.  The first chart uses an algorithm to try to determine which happened first and applies this to the trades.  In some instances,  the market looks like it opens then has a slight pull back and then goes up all day.  As a result the system buys and holds the trade through the close and onto the next day, but in reality the market opens, goes up and triggers a long entry, then retraces and you get stopped out.  What was a nice winner turns into a bad loss.  Here is an example of what might have happened during a few trades:

Nice flow – sold, bought, sold, bought, sold again and finally a nice profit.  But this is what really happened:

Sold, bought, reversed short on same day and stopped out on same day.  Then sold and reversed long on same day and finally sold and took profit.   TradeStation’s Look Inside Bar feature helps out when your system needs to know the exact path the market made during the day.  In many cases, simply clicking this feature to on will take care of most of your testing needs.  However, this simple algorithm needs to place or replace orders based on what happens during the course of the day.  With daily bars you are sitting on the close of the prior day spouting off orders.  So once the new day starts all of your orders are set.  You can’t see this initially on the surface, because it seems the algorithm is so simple.   Here is another consequence of day bar testing when the intra-day market movement is paramount:

Here the computer is doing exactly what you told it!  Sell short and then take a profit and sell short 25% of the ATR below the open.  Well once the system exited the short it realized it was well below the sell entry point so it immediately goes short at the exact same price (remember TS doesn’t allow stop limit orders).  You told the computer that you wanted to be short if the market moves a certain amount below the open.  These were the orders that were place on yesterday’s close  This may not be exactly what you wanted, right?  You probably wanted to take the profit and then wait for the next day to enter a new trade.  Even if you did want to still be short after the profit level was obtained you wouldn’t want to exit and then reenter at the same price (practically impossible) and be levied a round-turn slip and commission.   You could fiddle around with the code and try to make it work, but I guarantee you that a system like this can only be tested properly on intra-day data.  Let’s drop down to a lower time frame, program the system and see what the real results look like:

Looks very similar to the daily bar chart with Look Inside Bar turned on.  However, it is different.  If you wan’t to gauge a systems potential with a quick program, then go ahead and test on daily bars with LIB turned on.  If it shows promise, then invest the time and program the intra-day version just to validate your results.  What do you mean spend the time?  Can’t you simply turn your chart from daily bars to five minute bars and be done with it.  Unfortunately no!  You have to switch paradigms and this requires quite a bit more programming.  Here is our simple system now in EasyLanguage:

Vars:stb(0),sts(0),atr(0),icnt(0);
Vars:buysToday(0),sellsToday(0),mp(0);

{Use highD() and XXXXD(0)  functions to capture the highs, lows, and closes for the past 10 days.  
 I could have just used a daily bar as data2.  
 I am looking at five minute bars so we know how the market flows through the day.
}

{This loop kicks out a warning message, but seems to work
 Just do this once at the beginning of the day - faster}

{remember true range is either the higher of todays high
 Or yesterdays close minus the lower of todays low or 
 yesterdays close}

{ tradeStation time stamps at the close of the bar so
 we capture the opening of the open time plus the bar interval - 
 in this case 5 minute - so at 1800 + 5 (1805) I capture the open
 of the day}

if time = sess1StartTime + barInterval then  
begin
	Value1 = 0.0;
	for icnt = 1 to 10
	begin
		Value1 = value1 + maxList(closeD(icnt-1),highD(icnt)) - minList(closeD(icnt-1),lowD(icnt));
	end;
	atr = value1/10.0;
	stb = open + .25* atr;
	sts = open - .25* atr;
	buysToday = 0;
	sellsToday = 0;
end;

mp = marketPosition; {The ole mp trick}

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

if buysToday = 0  and time < sess1EndTime and close <= stb then buy next bar at stb stop;
if sellsToday = 0 and time < sess1EndTime and close >= sts then sellshort next bar at sts stop;

setStopLoss(500);
setProfitTarget(1000);
Open Range Break Out Utilizing Five Minute Bars

Here is a validation that Look Inside Bar does work:

This is the trade from June 1st.  Scroll back up to the second chart where LIB is turned on.

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);