Using EasyLanguage Variables – Part I
How can I write code to determine when a series of conditions have been met in sequence? How do I write code to perform an action only once after a new position has been initiated? How do I write code to stop looking for a certain condition to occur N bars after the occurrence of some other condition?
All of these problems can be solved with EasyLanguage variables. However, before we delve into actual variable uses, let’s review the definition of the term “variable” and some of the characteristics of EasyLanguage variables.
A program variable is a named memory location into which values can be placed, and from which values can be retrieved. It is called a “variable” because the value stored in it can be changed. EasyLanguage variables have certain characteristics, listed below:
1) Declaration. There are two types of variables in EasyLanguage with respect to the need for declaration: pre-declared variables, and user-declared variables. Any variable that is not a pre-declared variable must be declared by the developer in a variable declaration statement before it is used. The variable declaration must appear in the code above the first use of the variable.
2) Extent. In EasyLanguage, all variables have a value at all times – there are no undefined variables. Additionally, in a given piece of code, a given variable name will always refer to the same memory location. Pre-declared numeric variables, of all data types, contain the value 0 (zero). Pre-declared Boolean variables are FALSE. There are no pre-declared string variables. All user-declared variables initially contain the value that they are assigned in the variable declaration statement, called their “initial value.”
3) Data type. A variable can hold values only of a specific data type (integer, float, double, Boolean, or string). The data type of a variable is determined automatically by EasyLanguage, but the automatic type assignment can be overridden by the user in the variable declaration statement.
Using EasyLanguage Variables – Part II
How do I determine, using EasyLanguage, whether a certain price-related condition becomes true within N bars following the occurrence of some other price-related event? We began to address questions like this in Part I of my blog on using EasyLanguage variables. Let’s continue the list we began in Part I of the characteristics of EasyLanguage variables:
4) Duration. EasyLanguage variables are stored in “volatile” memory. This means that the values stored in variables are available only when the EasyLanguage analysis technique in which the variables are declared is running. Should the code re-run, as would happen, for example, were price data to be “refreshed,” the code would re-run on the bars in the chart. Values would be assigned to variables as the code ran on each bar.
5) Scope. The scope of a variable determines to which code modules its value is available. EasyLanguage variables are generally of “local” scope. This means that the value of the variable is available for modification only in the code module in which it is declared or in code modules to which it is passed by reference. A variable of the same name that is declared in the variables declaration of a different analysis technique is a different variable, a separate memory location. Additionally, EasyLanguage variables are local to the specific application instance of an analysis technique. A given analysis technique, applied N times, has N sets of variables, each distinct from the others.
There are three exceptions to the rule that EasyLanguage variables are of local scope.
The first exception is the pre-declared “global” variables provided for use in OptionStation. There are three types of these global variables: GVValues, GBValues, and GPValues. There are 100 pre-declared variables of each of these types: GVValue0 to GVValue99, GBValue0 to GBValue99, and GPValue0 to GPValue99. The names of these global variables derive from the types of analysis techniques with which they are intended to be used: Volatility Models, Bid-Ask Models, and Pricing Models.
Using EasyLanguage Variables – Part III
How can I prevent my strategy making a trade if, sometime after conditions for initiation of a trade are met but before the trade is entered, the occurrence of other conditions indicate that the trade should not be taken? EasyLanguage variables can help us write code that answers questions like this one, as we’ve mentioned in Parts I and II of this blog.
We ended Part II of our discussion of EasyLanguage variables by noting that the first exception to the rule that EasyLanguage variables are of local scope is the built-in global variables provided for use with OptionStation.
The second exception to this rule is also provided by OptionStation. It involves some special reserved words like Bid, Ask, ModelVolatility, and the option Greeks, that can return values, in one code module, that are set in another code module. Code that makes use of reserved words of this type can be found in the built-in Bid/Ask Models, Pricing Models and Volatility Models.
The third exception to the rule that EasyLanguage variables are of local scope is provided by a certain type of TradeStation-compatible dynamic-link library (DLL) called a “global variable” DLL. Variables provided by such a DLL are available to more than one code module and more than one application window. They may even be available to more than one TradeStation application (Charting, OptionStation, and RadarScreen). Variables held in an external, user-developed application to which communication is established by a TradeStation-compatible DLL are also considered variables of this type.
Now that we’ve described EasyLanguage variables, let’s begin using them. We’ll first declare some variables, and then review some common uses of them.
In EasyLanguage, the variables declaration statement has this general form:
variables: <Data Type> <intrabarpersist> VariableName( InitialValue ) <,<Data Type> <intrabarpersist> VariableName(InitialValue ), …> ;
In this statement, the term “variables” may be abbreviated, if desired, as “var” or “vars.” Chevrons (<>) are used to denote optional items.
Using EasyLanguage Variables – Part IV
We’ll focus today on your choice of data types for variables. Through the selection of the data types of your variables, you choose the manner in which the program you’re writing will symbolically represent the information in which you’re interested. Your selection of program data types will, then, depend on the nature of the information and data of which the problem you’re solving consists. A good choice of data types for your variables will allow you to clearly and efficiently represent the information you need, and make your code easier to develop, maintain, and expand.
The data type of a variable determines the nature of the data that it can store and the operations in which it can be used. It determines the range of possible values of a variable and, for numeric variables, the level of precision with which such values are stored.
There are five “primitive” data types that can be used in a variable declaration statement in EasyLanguage: int (short for integer), float (single-precision floating point), double (double-precision floating point), bool (short for Boolean, used to store the values true and false), and string (used to store alphanumeric text characters). The following variable declaration statement creates variables of all five primitive types. Some data types are assigned explicitly. Others, those not explicitly assigned a data type in the declaration statement, will be automatically assigned a data type by the compiler:
variables: int LoopCounter( 0 ), VolUp1TickAgo( false ), double _MovAvgValueD3( 0 ), Text.Var3( "" ), float AxB( 0 ) ;
Here are a few notes for advanced developers:
(1) The addition to EasyLanguage of the ability to create abstract data types (classes) is under consideration for implementation in a future version of TradeStation. Abstract data types can currently be provided by a TradeStation-compatible EasyLanguage extension DLL.
(2) An aggregate type is provided: the EasyLanguage array. An EasyLanguage array may contain values of any of the five primitive EasyLanguage data types. All elements of a given array must be of the same data type.
(3) Values can be passed to and from user-created functions by reference without direct use of pointers in EasyLanguage, so no explicit pointer “data types” are needed.
(4) EasyLanguage is a “loosely typed” language. Type conversions are made automatically, relieving you of the need to explicitly “cast” variables from one type to another.
(5) Although the selection of the data type of a variable will control how it is stored internally in computer memory, memory is not explicitly allocated or deallocated in EasyLanguage.
Using EasyLanguage Variables – Part V
You’ve realized that you’ll need to store some values in order to perform the calculations your strategy or study requires. Therefore, you’ve begun to write a variable declaration statement based on what you’ve learned in the first four parts of this blog. You’ve chosen the data type of each of your variables. Now, to complete your variable declaration statement, you’ll need to determine whether any of your variables should be intrabarpersist. Finally, if you’re using multiple data streams, you’ll need to make one additional determination: to which data stream each of your variables should be aliased.
Here’s an example variable declaration statement in which some variables are aliased to data streams other than Data1 and in which one variable is declared as intrabarpersist.
variables: intrabarpersist int LoopCounter( 0 ), VolUp1TickAgo( false, Data2 ), double MovAvgValueD3( 0, Data3 ) ;
In EasyLanguage, every variable, function, and reserved word is aliased to one of the data streams that the chart contains. In general, the alias you choose for your variables will correspond to the alias of the functions, reserved words and data that are used to calculate the variable’s value. We’ll discuss the aliasing of data, reserved words, and functions in a future blog. For now, we’ll concentrate on the aliasing of variables.
The aliasing of non-intrabarpersist variables controls the frequency at which its value is stored and, therefore, the data stream in which bars are counted back when the variable is backreferenced using brackets notation ( [N] ).
Variables in analysis techniques used in RadarScreen and OptionStation (all panes) must be aliased to Data1. This need not be done explicitly, however, because a variable will be automatically aliased to Data1 if it is not explicitly aliased to another data stream in the variable declaration statement.
“Push back” – Intrabarpersist vs. Non-Intrabarpersist. Variables in EasyLanguage may be declared to be intrabarpersist. The values of all variables, both intrabarpersist and non-intrabarpersist, are temporarily updated every time your EasyLanguage code runs. However, the values of non-intrabarpersist variables are restored to the values they had at the close of the preceding bar before the code runs again. We call this action “push back”; the value of the variable is “pushed back” to the value it had at the close of the preceding bar. Intrabarpersist variables, on the other hand, are not pushed back. Instead, the value of the variable is retained from one tick to the next. Values that are accumulated intrabar, therefore, must be stored in intrabarpersist variables. All variables not explicitly declared to be intrabarpersist are non-intrabarpersist.