An array is declared through the use of the
A structure is produced with the
To reference fields within a structure simply use the
You may store a date using the
Securities are stored using the
An expression in the macro language can include an assignment. For example
the expression:
A complete set of operators, with full precedence, is supported. The
normal mathematical operations are available using the conventional
symbols:
For comparisons the operators are:
Other operators are:
You should note that not all types will support all operators.
Constants can be included within expressions. The available constants
include integers, real numbers and strings enclosed within quotes.
A function allows you to group a number of statements together so
that you may reuse the same code in multiple ways. A function is
declared using the syntax:
In the simplest form, the arguments used by a function are declared
in the same way as normal variables but using a comma to delimit
each argument. For example, if a function requires two arguments, the
first being an integer and the second a string the declaration would
be:
When you wish to pass structures to a function, either by value or
by reference, you will need to declare the argument that is a structure
using a real type and not with the struct keyword. For example:
Functions can return values using the
The macro language provides a complete if..then..else construct:
The while construct provides the basic building block for iteration
within macros. The while construct allows a statement (including
a compound statement) to be continually executed:
Within a while (or do...while) loop, the
The for construct is based upon the while construct. The statement
The constant PI.
The NOPRICE constant gives a real number that indicates that no
valid price was available. These are used by the price database
and by the graph plotting functions to indicate no information
and in the case of graph plotting, that interpolation/extrapolation
is required.
Returns the arc cosine of x in the range of 0 to PI.
x should be in the range of -1 to 1.
Returns the arc sine of x in the range of -PI/2 to PI/2 radians.
x should be in range of -1 to 1.
Returns the arc tangent of x in the range -PI/2 to PI/2 radians.
The cos function returns the cosine of its argument x measured in radians.
The sin function returns the sine of its argument x measured in radians.
Returns the tangent of x measured in radians.
Returns the hyperbolic cosine of x.
Returns the hyperbolic sine of x.
Returns the hyperbolic tangent of x.
Returns e^x.
Returns the natural logarithm of x. Argument x must be positive.
Returns the logarithm base ten of x. Argument x must be positive.
Returns the square root of x. Argument x must be positive.
Returns the smallest integer not less than x.
Returns the absolute value of x.
Returns the largest integer not greater than x.
Returns x^y.
Returns the real remainder of the division of x by y.
Returns the arc tangent of y/x in the range of -PI to PI.
Opens a window with the title specified by name. The function
will return a value of type WINDOW and this value should be used in
future window based functions when this window is to be referenced. The
argument refreshfnc names the function that will be executed
when the window is resized and menu specifies the menus
that should be attached to the window.
Note that the information in data may be sparse. If a
value is not known and extrapolation is required then the value
in question should be set to the constant
NOPRICE
color(window,colour)
WINDOW window;
string colour,color;
Opens the file specified by name with the access permissions specified by
the access string. The access permissions are convential stdio values:
The returned value from fileopen is of type FILE and should be assigned
to a variable of FILE type. The file can be read or
written as appropriate. However before the file is accessed it is
recommended you use eof() to determine that the file is correctly open.
A typical code fragment for reading from a file would be:
Closes a previously opened file. A file for which eof() returns 2
does not need to be closed with this function.
Writes the arguments arg1 to argn to the specified file in ascii format.
The arguments can be of any type, provided they have an ascii
representation. Those that types that are appropriate include:
Returns the state of the file:
Attaches a new menu item to a bar on the main window. For example to
create a new menu option for the 'Project' menu one would use:
Allows the user to select a security from all the securities that are
known to the system. This returns a value of type SECURITY.
Displays a yes/no dialog with the message specified. The "OK" button
will be labeled with the string specified by
Displays a dialog with the message specified.
Displays a dialog where the user can edit the string given by
Allows the user to select a range of dates starting with the
date specified by
getdate(date)
DATE date;
string stringdate;
SECURITY security;
typedef real realarray[x];
realarray data;
DATE date;
int num;
Fetches the prices for the specified security. The array given by
data should be large enough to store all the prices for the given
security. The date that data[0] represents will be returned in
date and the total number of prices in the array will
be returned in num.
Language Constructs
Data Types
The macro language provides a set of basic types that you may use in
your programs:
int An integer capable of storing signed whole numbers
real A real value
string A sequence of ascii characters
char An ascii character
A variable can be declared using these types through a simple declaration
either at the start of your program (visible to the entire program) or
at the start of a function (only visible to that function). A typical
declaration is of the form:
int sharenumber;
You can build on these basic types in two ways, arrays allow you
to design storage areas that contain a sequence of data values of
a particular type and structures allow you to combine multiple
types within a larger container.
typedef
statement.
If you are used to the C language then, you should be aware that you must
use typedef
to produce arrays.
typedef real pricetype[100]
pricetype prices;
In the example above a new type called pricetype
is
created. This new
type consists of 100 reals. The program then defines the variable
prices
to be of the pricetype
type. When you
define an array in this manner, you can index each element within the
array using [x]
, where x is the member of interest. All
references start at 0.
struct
statement. This
allows any number of data types to be grouped together.
struct group {
string securityname;
real price;
};
This defines a structure named group
that has fields called
securityname
(a string) and price
(a
real). Having defined a structure you may declare a variable
newvar
that is of this type with:
struct group newvar;
You can can also combine the definition of the structure with the
declaration of the variable:
struct group {
string securityname;
real price;
} newvar;
It is also possible to use typedef with structures, for example
to create a new type groupt
that is an alias
for the group
structure you would use:
typedef struct group groupt
.
operator:
newvar.securityname="security name not set";
newvar.price=0.0;
DATE
type. The date type
is set to a specific date with
dialogdaterange and
getdate commands. Most operators are defined
on the date type and you can add a whole number of days to a date
by simply adding an integer (the number of days) to the date in question.
SECURITY
type. Typically
this is set by calling the
dialogsecurity function that prompts the
user for a valid security name. Few operators are valid on the
SECURITY
type.
Statements
A statement in the macro language is the basic building block. A statement
can consist of:
All statements should be terminated with a semicolon.
When multiple statements are combined a compound statement is produced. The
macro language uses braces to specify a compound statement:
{
statement1;
statement2;
}
Expressions
b=(a=10)+1
Will assign a to 10, b to 11 and has a value of 11.
* Multiplication
/ Division
+ Addition
- Subtraction
!= Not equal
= Equal
< Less than
> Greater than
<= Less than or equal to
>= Greater than or equal to
^ Exclusive or
& bitwise and
| bitwise or
&& logical and
|| logical or
(expr) Parenthesis
Functions
typename function_name(arguments)
{
variable_declarations
statements
}
The typename
declaration specifies the type that will
be returned by the function and can be omitted if the function
returns no values.
function_name(int num,string text)
{
......
......
}
This creates two variables for use by the function. The first
num
is
the integer and the second, text
, is the
string. So if the function
was called with:
function_name(10,"hello");
Then num
would be 10 and
text
would be "hello". Note with this syntax
the variables are strictly local so you CANNOT assign new values to them
and have the caller see those new values. The assignment will only
apply while the program is executing within the context of the function.
Frequently you may wish to return multiple values from the function and
therefore need to assign values that can be seen outside of the scope
of the function. This can be achieved with the byref
qualifier.
function_name(byref int num,byref string text)
{
num=100;
}
When arguments are declared in this manner, the function is able
to modify the actual values passed by the caller:
a=200;
function_name(a,"hello");
print(a);
In this instance the value that will be displayed will be 100 and
NOT 200. If the byref
keyword had not been included,
the value 200 would have been shown.
struct simplestruct {
.....
};
typedef simplestruct structtype;
function(byref structtype arg)
{
....
.....
}
This same method should also be employed when you wish to pass arrays
to functions.
return
command.
The type that
is to be returned should be specified in front of the function name. For
example if the macro has a function called createname
that
returns a string the function would be written:
At any point within the function, a call can be made to
string createname()
{
....
....
}
return
command passing a value that evaluates to a string. If you need to be
able to return, prior to the last statement in a function, from a function
that has no return value then you can simply use return
without an argument.
Conditional Expressions
if (expression)
statement
else
statement
The else part of the construct is entirely optional and can be omitted
when not necessary. At execution time, the expression within the if
statement is evaluated. When it is non-zero (TRUE), the first statement
will be executed. If it is zero and an else clause is specified, the
second statement following the else will be executed. Although the
expression in the if statement is treated as having boolean properties,
it can be of any integer type.
The while and do..while Constructs
while (condition) {
.....
code
.....
.....
}
The statements within the braces will be executed until the boolean
expression given by condition becomes FALSE. With most macros it
is usually that the code that is executed within the loop will
eventually result in the condition becoming FALSE. If the condition
is FALSE before the loop starts then the loop will not be executed.
If the loop should always be executed at least once, then the do..while
construct should be used:
do {
.....
code
.....
.....
} while (condition);
The loop is executed once and the condition is evaluated. If it is FALSE
the loop will be executed from the top, otherwise the statement following
the while() command will be executed.
continue
and
break
commands may be used. The continue
statement takes the point of execution back to the top of the loop.
The break
command will change the point of execution to the first statement
that follows the loop.
The for construct
for( i=0; i<100; i=i+1)
print(i,"\n");
Is equivalent to the statement:
i=0;
while (i<100) {
print(i,"\n");
i=i+1;
}
Unlike C or C++ you must specify all three expressions within the for
statement.
Builtin Constants
PI
NOPRICE
Builtin Mathematic Functions
acos(x)
asin(x)
atan(x)
cos(x)
sin(x)
tan(x)
cosh(x)
sinh(x)
tanh(x)
exp(x)
log(x)
log10(x)
sqrt(x)
ceil(x)
fabs(x)
floor(x)
pow(x,y)
fmod(x,y)
atan2(x,y)
Using Windows
windowopen(name,refreshfnc,menu)
string name;
string refreshfnc;
MENU menu;
Closes the window specified by window.
windowclose(window)
WINDOW window;
Clears the window specified by window.
clearpage(window)
WINDOW window;
Ensures the window specified by window is up to date.
drawpage(window)
WINDOW window;
Draws a line from the current position in window to
the coordinate x,y.
drawto(window,x,y)
WINDOW window;
real x,y;
Moves the current position in window to
the coordinate x,y.
moveto(window,x,y)
WINDOW window;
real x,y;
Sets width and height to the current width and
height of the window window.
size(window,width,height)
WINDOW window;
real width,height;
Draws a complete axis in the window window. On the X axis
dates will range from date1 to date2 and on the
Y axis values will go from min_y to max_y.
axis_date(window,date1,date2,min_y,max_y)
WINDOW window;
DATE date1,date2;
real min_y,max_y;
Plots the data given by
data in window using information
previously set by axis_date. The maxsize argument should
specify how many numbers are stored in data. The start
and end arguments give the range of indices within data
that should be plotted.
plot(window,data,maxsize, start, end)
WINDOW window;
typedef real realarray[x]
realarray data;
int maxsize;
int start,end;
Sets the line width for window.
linewidth(window,width)
WINDOW window;
real width;
Sets the current colour for window.
colour(window,colour)
Using Menus
menuopen(menu)
MENU menu;
Opens the specified menu. The menu can then be built and passed to
a windowopen() call:
WINDOW win;
MENU mymenu;
....
....
menuopen(mymenu);
menu(mymenu,"Project","Exit","window_exit");
menu(mymenu,"Project","Select security","selectsecurity");
win=windowopen("Prices of a security","window_refresh",mymenu);
Closes the specified menu.
menuclose(menu)
MENU menu;
Adds the menu bar and item to the specified menu that should already
have been opened with menuopen. The menu item itemname
should appear in the bar barname. The function named
functionname will be called when the menu item is selected
by the user.
menu(menu,barname,itemname,functionname)
MENU menu;
string barname;
string itemname;
string functionname
Using Files
fileopen(name,access)
string name;
string access;
r reading
w create for writing (or truncate if file already exists)
a append at end of file
r+ open for reading and writing
w+ truncate or create for update
a+ open (append) or create for update
FILE file;
string input;
....
....
file=fileopen("pricedump","r");
if ( eof(file)== 2) {
print("Could not open file");
return;
}
.....
while (eof(file)==0) {
filereadline(file,input);
print(input,"\n");
}
fileclose(file);
fileclose(file)
FILE file;
fileprint(file,arg1,...,argn)
FILE file;
(any) argi;
Writes the arguments arg1 to argn to the specified file in binary format.
Although all types can be written using this function, the output
file may not be transferable or readily readable.
filewrite(file,arg1,...,argn)
FILE file;
(any) argi;
Reads the arguments arg1 to argn from the file. The arguments can be of
any type. Typically to read ascii files you will need to use the
filereadline() command that is able to interpret files on a line by
line basis.
fileread(file,arg1,..,argn)
FILE file;
(any) argi;
Reads the arguments arg1 to argn from the file. The arguments must be of
type string. Each line in the file will be read into the relevant
argument.
filereadline(file,arg1,..,argn)
FILE file;
string argi;
eof(file)
FILE file;
This function allows one to read from a file while there is data to read:
file=fileopen("pricedump","r");
if ( eof(file)== 2) {
print("Could not open file");
return;
}
while (eof(file)==0) {
filereadline(file,input);
print(input,"\n");
}
fileclose(file);
Other Functions
mainmenu(barname,itemname,funcname)
string barname;
string itemname;
string funcname;
This will result in the function dump_prices being called whenever the
'Write prices to file' menu item is selected.
mainmenu("Project","Write prices to file","dump_prices");
dialogsecurity(title)
string title;
SECURITY security;
....
....
security=dialogsecurity("Enter a security");
int dialogyesno(message,okmsg,cancelmsg)
string message;
string okmsg;
string cancelmsg;
okmsg
and the "CANCEL" button will be labeled by cancelmsg
.
The function returns 1 if the user selects "OK", otherwise 0 will
be returned.
dialogmessage(message)
string message;
int dialogstring(windowtitle, message, stringedit,length)
string windowtitle;
string message;
string stringedit;
int length;
stringedit
. The maximum length of the string is given
by length
. The dialog will be in a window with the
title given by windowtitle
and the string edit area
will be labeled with message
.
int dialogdaterange(title,startdate,enddate)
string title;
DATE startdate;
DATE enddate;
startdate
and finishing
with enddate
. If the user hits the "OK" button
then the function returns 1, else the function returns 0
indicating the user canceled the operation. When 1 is returned
the startdate
and enddate
arguments will
be set to the new date range.
Converts a date in ascii form to a date (in the first form) or sets
a date to today (in the second form).
getdate(date,stringdate)
Converts a date to the number of days elapsed since 1st Jan 1970.
int date2days(date)
DATE date;
getprices(security,data,date,num)
Returns TRUE if the value given by price represents a
valid price. Not all real numbers are prices so as to allow
information to be held in the price database indicating that
no price exists for a given date. See the constant
NOPRICE
int isaprice(price)
real price;
Executes a shell with the commands given in cmdstring. The
return value will be 0 if the command executed correctly, otherwise
it will be -1 if a process could not be forked or -127 if the
commands could not otherwise be executed.
int system(cmdstring)
string cmdstring;