Methods are wonderful tools that are just like functions, but you can put them right into your Analysis Technique and they can share the variables that are defined outside the Method. Here is an example that I have posted previously. Note: This was in response to a question I got on Jeff Swanson’s EasyLanguage Mastery Facebook Group.
{'(' Expected line 10, column 12 } //the t in tradeProfit. // var: double tradeProfit;
vars: mp(0); array: weekArray[5](0);
method void dayOfWeekAnalysis() {method definition} var: double tradeProfit; begin If mp = 1 and mp[1] = -1 then tradeProfit = (entryPrice(1) - entryPrice(0))*bigPointValue; If mp = -1 and mp[1] = 1 then tradeProfit = (entryPrice(0) - entryPrice(1))*bigPointValue; weekArray[dayOfWeek(entryDate(1))] = weekArray[dayOfWeek(entryDate(1))] + tradeProfit; end;
Buy next bar at highest(high,9)[1] stop; Sellshort next bar at lowest(low,9)[1] stop;
mp = marketPosition; if mp <> mp[1] then dayOfWeekAnalysis(); If lastBarOnChart then Begin print("Monday ",weekArray[1]); print("Tuesday ",weekArray[2]); print("Wednesday ",weekArray[3]); print("Thursday ",weekArray[4]); print("Friday ",weekArray[5]); end;
PowerEditor Cannot Handle Method Syntax
Convert Method to External Function
Sounds easy enough – just remove Method and copy code and put into a new function. This method keeps track of Day Of Week Analysis. So what is the function going to return? It needs to return the performance metrics for Monday, Tuesday, Wednesday, Thursday and Friday. That is five values so you can’t simply assign the Function Name a single value – right?
tradeProfit = -999999999; If mp = 1 and mp[1] = -1 then tradeProfit = (entryPrice(1) - entryPrice(0))*bigPointValue; If mp = -1 and mp[1] = 1 then tradeProfit = (entryPrice(0) - entryPrice(1))*bigPointValue; if tradeProfit <> -999999999 then weekArray[dayOfWeek(entryDate(1))] = weekArray[dayOfWeek(entryDate(1))] + tradeProfit; print(d," ",mp," ",mp[1]," ",dayOfWeek(entryDate(1)),tradeProfit," ",entryDate," ",entryDate(1)," ",entryPrice(0)," ",entryPrice(1));
DayOfWeekAnalysis = 1;
Simple Function - What's the Big Deal
Looks pretty simple and straight forward. Take a look at the first line of code. Notice how I inform the function to expect an array of [n] length to passed to it. Also notice I am not passing by value but by reference. Value versus reference – huge difference. Value is a scalar value such as 5, True or a string. When you pass by reference you are actually passing a pointer to actual location in computer memory – once you change it – it stays changed and that is what we want to do. When you pass a variable to an indicator function you are simple passing a value that is not modified within the body of the function. If you want a function to modify and return more than one value you can pass the variable and catch it as a numericRef. TradeStation has a great explanation of multiple output functions.
Multiple Output Function per EasyLanguage
Some built-in functions need to return more than a single value and do this by using one or more output parameters within the parameter list. Built-in multiple output functions typically preface the parameter name with an ‘o’ to indicate that it is an output parameter used to return a value. These are also known as ‘input-output’ parameters because they are declared within a function as a ‘ref’ type of input (i.e. NumericRef, TrueFalseRef, etc.) which allows it output a value, by reference, to a variable in the EasyLanguage code calling the function.
I personally don’t follow the “O” prefacing, but if it helps you program then go for it.
Series Function – What Is It And Why Do I Need to Worry About It?
A series function is a specialized function that refers to a previous function value within its calculations. In addition, series functions update their value on every bar even if the function call is placed within a conditional structure that may not be true on a given bar. Because a series function automatically stores its own previous values and executes on every bar, it allows you to write function calculations that may be more streamlined than if you had to manage all of the resources yourself. However, it’s a good idea to understand how this might affect the performance of your EasyLanguage code.
Seems complicated, but it really isn’t. It all boils down to SCOPE – not the mouthwash. See when you call a function all the variables inside that function are local to that particular function – in other words it doesn’t have a memory. If it changes a value in the first call to the function, it has amnesia so the next time you call the function it forgets what it did just prior – unless its a series function. Then it remembers. This is why I can do this:
If mp = 1 and mp[1] = -1 then tradeProfit = (entryPrice(1) - entryPrice(0))*bigPointValue; If mp = -1 and mp[1] = 1 then tradeProfit = (entryPrice(0) - entryPrice(1))*bigPointValue;
I Can Refer to Prior Values - It Has A Memory
Did you notice TradeProfit = -99999999 and then if it changes then I accumulate it in the correct Day Bin. If I didn’t check for this then the values in the Day Bin would be accumulated with the values returned by EntryPrice and ExitPrice functions. Remember this function is called on every bar even if you don’t call it. I could have tested if a trade occurred and passed this information to the function and then have the function access the EntryPrice and ExitPrice values. This is up to your individual taste of style. One more parameter for readability, or one less parameter for perhaps efficiency?
This Is A Special Function – Array Manipulator and Series Type
When you program a function like this the EasyLanguage Dev. Environment can determine what type of function you are using. But if you need to change it you can. Simply right click inside the editor and select Properites.
Function Properties – AutoDetect Selected
How Do You Call Such a “Special” Function?
The first thing you need to do is declare the array that you will be passing to the function. Use the keyword Array and put the number of elements it will hold and then declare the values of each element. Here I create a 5 element array and assign each element zero. Here is the function wrapper.
Buy next bar at highest(high,9)[1] stop; Sellshort next bar at lowest(low,9)[1] stop; mp = marketPosition; newTrade = False; //if mp <> mp[1] then newTrade = true;
value1 = dayOfWeekAnalysis(weekArray); If lastBarOnChart then Begin print("Monday ",weekArray[1]); print("Tuesday ",weekArray[2]); print("Wednesday ",weekArray[3]); print("Thursday ",weekArray[4]); print("Friday ",weekArray[5]); end;
Wrapper Function - Notice I only Pass the Array to the Function
Okay that’s how you convert a Method from EasyLanguage into a Function. Functions are more re-uasable, but methods are easier. But if you can’t use a method you now know how to convert one that uses Array Manipulation and us a “Series” type.
Many Times It Takes Multiple Tools to Get the Job Done
Just like a mechanic, a Quant needs tools to accomplish many programming tasks. In this post, I use a toolbox to construct an EasyLanguage function that will test a date and determine if it is considered a Holiday in the eyes of the NYSE.
Why a Holiday Function?
TradeStation will pump holiday data into a chart and then later go back and take it out of the database. Many times the data will only be removed from the daily database, but still persist in the intraday database. Many mechanical day traders don’t want to trade on a shortened holiday session or use the data for indicator/signal calculations. Here is an example of a gold chart reflecting President’s Day data in the intra-day data and not in the daily.
Holiday Data Throws A Monkey Wrench Into the Works
This affects many stock index day traders. Especially if automation is turned on. At the end of this post I provide a link to my youTube channel for a complete tutorial on the use of these tools to accomplish this task. It goes along with this post.
First Get The Data
I searched the web for a list of historical holiday dates and came across this:
Historic List of Holidays and Their Dates
You might be able to find this in a easier to use format, but this was perfect for this post.
Extract Data with Beautiful Soup
Here is where Python and the plethora of its libraries come in handy. I used pip to install the requests and the bs4 libraries. If this sounds like Latin to you drop me an email and I will shoot you some instructions on how to install these libraries. If you have Python, then you have the download/install tool known as pip.
Here is the Python code. Don’t worry it is quite short.
url = 'http://www.market-holidays.com/' page = requests.get(url) soup = BeautifulSoup(page.text,'html.parser') print(soup.title.text) all_tables = soup.findAll('table') #print (all_tables) print (len(all_tables)) #print (all_tables[0]) print("***") a = list() b = list() c = list() #print(all_tables[0].find_all('tr')[0].text) for numTables in range(len(all_tables)-1): for rows in all_tables[numTables].find_all('tr'): a.append(rows.find_all('td')[0].text) b.append(rows.find_all('td')[1].text)
for j in range(len(a)-1): print(a[j],"-",b[j])
Using Beautiful Soup to Extract Table Data
As you can see this is very simple code. First I set the variable url to the website where the holidays are located. I Googled on how to do this – another cool thing about Python – tons of users. I pulled the data from the website and stuffed it into the page object. The page object has several attributes (properties) and one of them is a text representation of the entire page. I pass this text to the BeautifulSoup library and inform it to parse it with the html.parser. In other words, prepare to extract certain values based on html tags. All_tables contains all of the tables that were parsed from the text file using Soup. Don’t worry how this works, as its not important, just use it as a tool. In my younger days as a programmer I would have delved into how this works, but it wouldn’t be worth the time because I just need the data to carry out my objective; this is one of the reasons classically trained programmers never pick up the object concept. Now that I have all the tables in a list I can loop through each row in each table. It looked liker there were 9 rows and 2 columns in the different sections of the website, but I didn’t know for sure so I just let the library figure this out for me. So I played around with the code and found out that the first two columns of the table contained the name of the holiday and the date of the holiday. So, I simply stuffed the text values of these columns in two lists: a and b. Finally I print out the contents of the two lists, separated by a hyphen, into the Interpreter window. At this point I could simply carry on with Python and create the EasyLanguage statements and fill in the data I need. But I wanted to play around with Excel in case readers didn’t want to go the Python route. I could have used a powerful editor such as NotePad++ to extract the data from the website in place of Python. GREP could have done this. GREP is an editor tool to find and replace expressions in a text file.
Use Excel to Create Actual EasyLanguage – Really!
I created a new spreadsheet. I used Excel, but you could use any spreadsheet software. I first created a prototype of the code I would need to encapsulate the data into array structures. Here is what I want the code to look like:
Arrays: holidayName[300](""),holidayDate[300](0);
holidayName[1]="New Year's Day "; holidayDate[1]=19900101;
Code Prototype
This is just the first few lines of the function prototype. But you can notice a repetitive pattern. The array names stay the same – the only values that change are the array elements and the array indices. Computers love repetitiveness. I can use this information a build a spreadsheet – take a look.
Type EasyLanguage Into the Columns and Fill Down!
I haven’t copied the data that I got out of Python just yet. That will be step 2. Column A has the first array name holidayName (notice I put the left square [ bracket in the column as well). Column B will contain the array index and this is a formula. Column C contains ]=”. Column D will contain the actual holiday name and Column E contains the ; These columns will build the holidayName array. Columns G throuh K will build the holidayDates array. Notice column H equals column B. So whatever we do to column B (Index) will be reflected in Column H (Index). So we have basically put all the parts of the EasyLanguage into Columns A thru K.
Excel provides tools for manipulating strings and text. I will use the Concat function to build my EasyLanguage. But before I can use Concat all the stuff I want to string together must be in a string or text format. The only column in the first five that is not a string is Column B. So the first thing I have to do is convert it to text. First copy the column and paste special as values. Then go to your Data Tab and select Text To Columns.
Text To Columns
It will ask if fixed width or delimited – I don’t think it matters which you pick. On step 3 select text.
Text To Columns – A Powerful Tool
The Text To Columns button will solve 90% of your formatting issues in Excel. Once you do this you will notice the numbers will be left justified – this signifies a text format. Now lets select another sheet in the workbook and past the holiday data.
Copy Holiday Data Into Another Spreadsheet
New Year's Day - January 1, 2021 Martin Luther King, Jr. Day - January 18, 2021 Washington's Birthday (Presidents' Day) - February 15, 2021 Good Friday - April 2, 2021 Memorial Day - May 31, 2021 Independence Day - July 5, 2021 Labor Day - September 6, 2021 Thanksgiving - November 25, 2021 Christmas - December 24, 2021 New Year's Day - January 1, 2020 Martin Luther King, Jr. Day - January 20, 2020 Washington's Birthday (Presidents' Day) - February 17, 2020 Good Friday - April 10, 2020 Memorial Day - May 25, 2020
Holiday Output
Data Is In Column A
Text To Columns to the rescue. Here I will separate the data with the “-” as delimiter and tell Excel to import the second column in Date format as MDY.
Text To Columns with “-” as the delimiter and MDY as Column B Format
Now once the data is split accordingly into two columns with the correct format – we need to convert the date column into a string.
Convert Date to a String
Now the last couple of steps are really easy. Once you have converted the date to a string, copy Column A and past into Column D from the first spreadsheet. Since this is text, you can simply copy and then paste. Now go back to Sheet 2 and copy Column C and paste special [values] in Column J on Sheet 1. All we need to do now is concatenate the strings in Columns A thru E for the EasyLanguage for the holidayName array. Columns G thru K will be concatenated for the holidayDate array. Take a look.
Concatenate all the strings to create the EasyLanguage
Now create a function in the EasyLanguage editor and name it IsHoliday and have it return a boolean value. Then all you need to do is copy/paste Columns F and L and the data from the website will now be available for you use. Here is a portion of the function code. Notice I declare the holidayNameStr as a stringRef? I did this so I could change the variable in the function and pass it back to the calling routine.
holidayName[1]="New Year's Day "; holidayDate[1]=19900101; holidayName[2]="Martin Luther King, Jr. Day "; holidayDate[2]=19900115; holidayName[3]="Washington's Birthday (Presidents' Day) "; holidayDate[3]=19900219; holidayName[4]="Good Friday "; holidayDate[4]=19900413; holidayName[5]="Memorial Day "; holidayDate[5]=19900528; holidayName[6]="Independence Day "; holidayDate[6]=19900704; holidayName[7]="Labor Day "; holidayDate[7]=19900903; holidayName[8]="Thanksgiving "; holidayDate[8]=19901122; holidayName[9]="New Year's Day "; holidayDate[9]=19910101; holidayName[10]="Martin Luther King, Jr. Day "; holidayDate[10]=19910121; holidayName[11]="Washington's Birthday (Presidents' Day) "; holidayDate[11]=19910218;
// There are 287 holiays in the database. // Here is the looping mechanism to compare the data that is passed // to the database
vars: j(0); IsHoliday = False; For j=1 to 287 Begin If testDate = holidayDate[j] - 19000000 then Begin holidayNameStr = holidayName[j] + " " + numToStr(holidayDate[j],0); IsHoliday = True; end; end;
A Snippet Of The Function - Including Header and Looping Mechanism
This was a pretty long tutorial and might be difficult to follow along. If you want to watch my video, then go to this link.
I created this post to demonstrate the need to have several tools at your disposal if you really want to become a Quant programmer. How you use those tools is up to you. Also you will be able to take bits and pieces out of this post and use in other ways to get the data you really need. I could have skipped the entire Excel portion of the post and just did everything in Python. But I know a lot of Quants that just love spreadsheets. You have to continually hone your craft in this business. And you can’t let one software application limit your creativity. If you have a problem always be on the lookout for alternative platforms and/or languages to help you solve it.
In the Pascal programming language you have Procedures and Functions. Procedures are used when you want to modify multiple variables within a sub-program. A function is a sub-program that returns a single value after it has been modified by say a formula. EasyLanguage combines procedures and functions into one sub-program called a function. Functions and procedures both have a formal parameter definition – a list that describes the type of parameters that are being received by the calling program. In Pascal procedures, you pass the address of the value that you want changed. By modifying the contents of the address you can pass the value back and forth or in and out of the procedure. In functions you pass by value. Remember the parameter in a normal function call is used to instruct something within the body of the function and is not altered (e.g. the number 19 in value1 = average(c,19)). This value doesn’t need to be modified it’s just used. Look at the following code:
Here I am modifying mav1, mav2 and mav3 within the function and then passing the values back to the calling strategy/indicator/paintbar. All functions must return a value so I simply assign the value 1 to the function name. The key here is the keyword numericRef, once I change the values located in the addresses of mav1, mav2 and mav3 (address are provided by the keyword numericRef), they will be made available to the calling program. This code allows the function to return more than just one value.
Backtesting with [Trade Station,Python,AmiBroker, Excel]. Intended for informational and educational purposes only!
Get All Four Books in the Easing Into EasyLanguage Series - The Day Trade Edition is now Available!
Announcement – A Day Trade Edition will be added to my Easing Into EasyLanguage Series this year! This edition will be the fourth installment and will utilize concepts discussed in the Hi-Res and Advanced Topics editions. I will show how to develop and program algorithms that will enter after the open of the day and get out before the market closes. Hence, no overnight exposure. Most examples will be carried out on the mini Dow, Nasdaq, S&P500 and Russel. The programming skills that you will learn can be carried to any market that provides enough bang for the buck to day trade. Look for this edition later this year. But get geared up for it by reading the first three editions in the series now. Get your favorite QUANT the books they need!
The Cover of my latest book. The first in the series.
Hello to All! The Easing Into EasyLanguage Series is now complete with the publication of the Advanced Topics Edition. This series includes three educational editions. Start out with the Foundation Edition. It is designed for the new user of EasyLanguage or for those you would like to have a refresher course. There are 13 tutorials ranging from creating Strategies to PaintBars. Learn how to create your own functions or apply stops and profit objectives. Ever wanted to know how to find an inside day that is also a Narrow Range 7 (NR7?) Now you can, and the best part is you get over 4 HOURS OF VIDEO INSTRUCTION – one for each tutorial. All source code is available too, and if you have TradeStation, so are the workspaces. Plus you can always email George for any questions. george.p.pruitt@gmail.com.
Hi-Res Edition Cover
This book is for those that have read the Foundation Edition or have some experience working with EasyLanguage and the various functions that help make a trading decision. This book’s audience will be those programmers that want to take an idea, that requires an observation of intraday market movements to make a trading decision, and program it accurately. If you have programmed daily bar systems, and you want to drill down and add some components that require additional market information (like what came first – the high or the low), then you have come to the right place. If you want to buy and sell short in the same day and use trade management principles such as profit targets and stop losses then The Hi-Res Edition is the book you need. There are two paradigms that EasyLanguage covers: daily and intraday bar programming. It’s the same language, but the move from daily to intraday programming can be quite difficult. Learn all the essentials and shortcuts with this edition. 5 HOURS OF VIDEO INSTRUCTION in this Hi-Res edition – one for each tutorial. All source code is available too, and if you have TradeStation, so are the workspaces. Plus you can always email George for any questions. george.p.pruitt@gmail.com.
Advanced Topics Cover
Advanced Topics (AT) could cover a vast amount of ideas and concepts and be the length of “War and Peace” on steroids. Since this book is part of the series, I wanted to cover a handful of concepts that included the follow programming constructs. Arrays and their manipulation. Buffers (fixed length arrays) and the tools to maintain buffer elements with formulas for extraction and sorting. Finite State Machines using the switch-case construct and range based case values. Using original text graphic objects and retrieving and analyzing their properties to determine X and Y coordinate values of text location. Seasonality: The Ruggiero/Barna Universal Seasonal and the Sheldon Knight Seasonal methods. In AT, you will also find an introduction to EasyLanguage’s Project Concept and the steps to create one by adding/deleting component files. TradeStation now provides access to fundamental data such as Commitment of Traders – learn how to convert the Net Change indicator into a strategy utilizing the FundValue functionality. If you wanted to find out how to merge multiple time frames into a single indicator, you are in luck! Create a MTF indicator for yourself.
Get Day Trading Edition Today!
Day Trading (DT) – This is a surprise installment in my Easing into EasyLanguage Series, as I had only intended on three books. However, I think it will fit well with the other books. Daytrading is a very popular approach as overnight risk is eliminated. Don’t worry there is plenty of risk during the day too! However, it can be very difficult to accurately program a trading idea on higher resolution data such as five- or one-minute bars. Like my other books, there is no “Holy Grail” included. And if you are looking for a book that gets in and out of a trade in a few seconds, this is not the one for you. I discourage trading more than a handful of trades per day – this is best left up to the professionals. But, if you want to learn about volatility-based break outs, pyramiding, scaling out, zone-based trading, accurate trade accounting and having a peek at algorithms that once ruled the systematic daytrading industry, then this is the book for you. A beginner might have a little difficulty in following along with the tutorials. If you have read the first two books (Foundation and Hi-Res) in this series, you are good to go. Or if you have some experience working with EasyLanguage and minute data, you will be OK as well.
Pick up your copies today – e-Book or paperback format – at Amazon.com