Built-in Scripting Language Reference Guide for Neural Networks computations and data analysis

Visibility is very important for this site. If you like it please link to this URL or use our online form to add your reciprocal link. Learn more about reciprocal links


SLANG: Built-in Scripting Language Reference Guide

(C) S Projects. Any distribution of any parts of this site is strictly prohibited, unless explicitly stated in text.

All contents of this site is provided strictly on the AS IS basis. The author should not be held responsible for any negative effects that may result from reading or applying the information or using software provided here. The author does not make any medical, financial or other claims - all statements are author's opinions ONLY. Use your own judgment.

Introduction

Some programs on this site have their own built-in Scripting Language (SLANG). This language can be used to create tasks, that can run in the automated mode, to import and export data, to draw charts and much more.

See the Reference guide for the complete list of functions.

In this tutorial we will walk through couple of examples, each designed both as a tutorial and a starting point for your own programs.

Your first SLANG program

From the FILE menu select New Script File. A text editor window will open. Select File-Save(or Save As) and save this file as sample_01.tsc. Alternatively, you may open existing sample_01.tsc file that comes with the program, it is located in data\samples\scripts subdirectory.

Type in the following code:

void main()
{
    PRINT("%s\r\n", "Hello, World!");
}

Click "Run" icon (the exclamation mark) on the Toolbar. The script you have just created will automatically be saved, and executed. A new (Output) window will open, and the "Hello, World!" text will be printed in it.

The first line of our script contains the "main" function. Script may have more then one function, but when you run it, it will always look for the function called "main", as a starting point.

Note, that currently main() function (as well as timer(), init() and any other function that is called by the system, rather than from your script) can't have arguments (parameters).

The "void" in front of the function name stands for its return type. We will discuss it later.

The body of the function is embraced with the figure brackets { and }. When the "}" of the "main" function is reached, the scripting engine knows, that the program is over.

The PRINT is one of the built-in functions of the scripting language, it is used to produce output to the Output text window.

The "%s\r\n" is a format string. %s stands for "string" (as opposed, for example, to a number), it states, that the information to be printed (in our case, the "Hello, World!) is a string.

The "\r\n" part is not required for the script to work, what it does is adding a new line to the output. Try running the script few times with and without it, to see the difference.

See the Reference guide for a complete list of functions.

Save your file as sample_02.tsc, or open the existing one in the samples/scripts directory. Modify the code, to introduce an error in it:

void main()
{
    XPRINT("%s\r\n", "Hello, World!");
}

When you run it, instead of the "Hello, World!" you will see an error message, something like
"line: 3, C:\S_Projects\CortexPro\data\samples\scripts\_sample_02.tsc, Undefined subroutine"

Cycles

Often, we need to do the same operation more than once. For example, we may want to do something for ALL records in the file. Or just to print few lines, each with its own line number.

Save your work in the sample_03.tsc file, and add the following modifications:

void main()
{
    for(double i = 0; i < 10; i = i + 1)
    {
        PRINT("Line number = %.0f", i + 1, ", 
            %s\r\n", "Hello, World!");
    }
}

The output will look like this:

Line number = 1, Hello, World!
Line number = 2, Hello, World!
Line number = 3, Hello, World!
Line number = 4, Hello, World!
Line number = 5, Hello, World!
Line number = 6, Hello, World!
Line number = 7, Hello, World!
Line number = 8, Hello, World!
Line number = 9, Hello, World!
Line number = 10, Hello, World!

Lets walk through this example, as there are some important little details here.

First of all, the for(...) construction is called the "for cycle". The code within the figure brackets after it is called the cycle's BODY.

The "double" stands for numbers. People familiar with C may expect the "int" instead, but there are no integers, at least in this version of the scripting language.

Any variable ("i" is a variable in our example) need to be DECLARED. We can declare a numeric variable, by placing the "double" in front of is. We only need to do it once, for the first time. For example:

double i;
for(i = 0; i < 10; i = i + 1)
....

for(double j = 0; ...

Note, that in the example above, "i" was declared before the cycle, so we don't have to do it in the cycle.

At the beginning of the processing of the "for" directive, the program assigns "i" (a cycle variable) the initial value of 0: for(double i = 0; ...

Then, every cycle, its value is increased by 1 (i = i + 1), until it reaches 10 ("i < 10;" part). It means, that the cycle's body will be executed 10 times, with i equal to 0, then 1, and so on. When the value of i becomes 10, the program leaves the cycle, and goes to the next command.

Therefore, the maximum value of i is 9, not 10. However, we wanted line numbers to begin from 1 and to end at 10, so we printed not i, but i + 1: PRINT("Line number = %.0f", i + 1, ", %s\r\n", "Hello, World!");

Also notice the way we used format strings, to make the output of the PRINT function "readable". The first format string contains not only "%f" (that stands for "printing numeric data"), but also some text ("Line number = "). The second format string, in addition to "%s", contains the comma and extra space, to separate the output from the preceding text.

See the Reference guide for a complete list of format specifiers.

Conditions

Let's say we need to count from one to ten, just as in the previous example. However, we need to find out if the value is even or odd. Create a new file, save it as sample_04.tsc, or use the existing sample:

void main()
{
    for(double i = 0; i < 10; i = i + 1)
    {
        PRINT("Line number = %.0f", i + 1);

        if((i + 1) % 2 != 0)
        {
            PRINT(" %s\r\n",  " is odd");
        }
        else
        {
            PRINT(" %s\r\n",  " is even");
        }
    }
}

The if(condition) ... else construction is used to execute different parts of the code, depending on the condition. In our example, the condition is if((i + 1) % 2 != 0), where % is an operation of taking the remainder after the division, and != means "not equal". Therefore our condition reads as "if the remainder of i + 1 divided by 2 is not zero".

If the condition is satisfied, the part of the code that is located in the figure brackets right after "if" will be executed, otherwise, the code located in the figure brackets right after "else". If thete if no "else" part (just "if"), the control will be passed to the code AFTER the body of the "if" statement.

Note, that you can make complex "if" statements, by nesting one "if" inside another. As was mentioned in the previous paragraph, you can also use a simplified form, without the "else" part.

Also note, that conditions can be combined, for example, the "if i is odd and i is less then 5" looks like if((i % 2) != 0 && i < 5)

Here && stands for "and", you can also use || (or) and ! (not).

More cycles

Now we can check for conditions within the cycle, and if necessary, break from the cycle. We can also skip particular cycles. For example, lets say we are reading data from the file. If the data is not numeric, we skip it. If the data IS numeric, we process it. And finally, if there is no more data to read, we break from the cycle, even if the cycle variable is still too small.

For our next example, let's type first ten odd numbers.

sample_05.tsc

for(double i = 1; i < 100; i = i + 1)
{
    if((i % 2) != 0)
    {
        continue i;
    }
    else
    {
        if(i >= 20)
        {
            break i;
        }
    }
    PRINT("Line number = %.0f\r\n", i);
}

First of all, we have the cycle limit equal 100, but we don't need that many numbers to be printed, so we break at i more or equal 20 (>=).

Second, we don't use (i + 1) anymore, instead, we started from i = 1. You can, as a mater of fact, have more control over the way cycle is evaluated. In its full form, it looks like for(FROM; CONDITION; STEP) Here "FROM" is the initial value, "CONDITION" is the exit check, and "STEP" is the code that is altering the cycle variable every cycle. So you can write for(i = 100; i >= 1; i = i - 1), and i will decrease, until it reaches 1. Be careful, it is possible to create infinite cycles, for example, for(i = 10; i < 2; i = i + 1) will never end, unless, of course, you break it from within, using the "break" statement.

The "break" and "continue" commands take one parameter, which is a cycle variable. It is very convenient, when you need to get out from nested cycles.

Variables

There are four types of variables in SLANG: number, string, array of numbers and array of strings. We need to declare them, before we use them:

double x;
double y = 0;
string str = "Hello";
array arr = CREATE_ARRAY(0);
array_ arr_s = CREATE_ARRAY_S(0);

Notice, that we can create numeric or string variables, and later assign the values to them.

As for arrays, they have to be created by calling the CREATE_ARRAY or CREATE_ARRAY_S functions. The reason for it is rather simple - in our scripting language we have three different types of arrays: not sorted, sorted and sorted with no duplicated values. We create them by passing 0, 1 and 2 to the CREATE_... function.

Be careful with the sorted arrays - there are things you can not do with them. Let's say, you want to alter 5th element of an array:
arr[5] = 3;

It is OK if an array is not sorted, but what if it was sorted? For example, what if it had 10, 20, 30, and 40? By inserting "3" into the 5th array's element, you will ruin the sorting!

To avoid these sort of problems, use the following approach. If the array is unsorted (0 was passed when it was created), you can assign values to its elements using assignment, like in arr[5] = 3;

If an array is sorted, you have to use built-in functions of the scripting language. For example, you can add an element to the sorted array by calling double nPos = ARRAY_ADD(arr, dValue);

This function will add dValue to the correct (according to sorting) position, and return the index of a new element in array. For example, if we want to insert 3 into the sorted array that already has elements 2, 4, 5, the resulting array will be 2, 3, 4, 5 and the nPos, returned by the ARRAY_ADD function will be equal 1 (indices in arrays are zero-based, 0, 1, 2...).

An important advantage of using arrays is the fact that you can use them in cycle, using the cycle variable as an array index.

for(i = 0; i < 10; i = i + 1)
{
    arr[i] = 2 * i;
}

Functions

Sometimes the same code is called from more than one part of your program. In this case, you can move it to the FUNCTION, and use function calls, rather than retyping the code many times. Also, by passing the so-called parameters to the function, you can alter the way it behaves.

Let's say you need to print the list of odd numbers, in the left column, and even numbers in the right (this is just an example, and NOT an easiest way to do it).

sample_06.tsc

void main()
{
    for(double i = 0; i < 10; i = i + 2)
    {
        PrintTable(i);
    }
}
// ---------------------
void PrintTable(double n)
{
    if((n % 2) != 0)
    {
        PRINT("%.0f", i - 1, "    %.0f\r\n", i);
    }
    else
    {
        PRINT("%.0f", i, "    %.0f\r\n", i + 1);
    }
}

Generally speaking, we didn't do anything new. Before we had one user-defined function, called "main", now we have added another one, called "PrintTable".

Our new function takes one parameter, and does some printing.

Note, that the string after // is not part of a program, it is called a comment, and the program will ignore it. There are two types of comments in SLANG, one to comment the remaining part of a line, and another one to comment a block of code, possibly with many lines. This second type of comment looks like /* ... */, the code between the /* and */ is commented.

It is possible to return values from the user-defined functions, and to use them in expressions. For example:

void main()
{
    double dSum = 0;
    for(double i = 0; i < 10; i = i + 2)
    {
        dSum = dSum + GetFive();
    }

    PRINT("%.0f\r\n", dSum);
}
// ---------------------
double GetFive()
{
    return 5;
}

This function has a non-void (double) return value. It RETURNS the numeric value, using a "return" operator. Of course, it can take parameters and perform calculations, too.

Charts

In this chapter we will discuss SLANG's charting. Open the sample_07.tsc and run it. In addition to the output window, that you have already seenbefore, the program will open a new window, called Draw Panel. Same way as text output goes to Output Panel, the Draw Panel is for graphics.

Let's walk through the code of this sample. It is not necessary to assign values to the variables in the beginning of the program, you may do it later, when you need them. But I think it is a good style, sometimes.
First thing, we are creating some variables. Some of them - most of them, actually, are for convenience only. For example, I know (from the SLANG reference guide, perhaps) that to draw a bar chart I have to pass 2 as a parameter to some function. I have a choice - either to pass 2, or to pass a variable with a meaningfull name and with value 2. The second approach will produce a much more readable code.

Pay attantion to the comments in the code below:

sample_07.tsc, part 1

void main()
{
    OUT_CLEANUP();
    
    PRINT("%s\r\n", 
        "Performing initialization of useful variables");

    double marker_non = 0;    
    double marker_rect = 1; 
    double marker_circle = 2; 
    double marker_triangle = 3; 
    double marker_s_5 = 4; 
    double marker_s_6 = 5; 
    double marker_cross = 6; 
    double marker_cross_x = 7; 
    double marker_diamond = 8; 
    double marker_triangle2 = 9;
    double marker_bar2 = 10; 
    double marker_circle2 = 11; 
    double marker_arrow_up = 12; 
    double marker_arrow_dn = 13; 
    double marker_bar = 14;
    double marker_bar3d = 15; 
    double marker_s_bar = 16; 
    double marker_s_bar3d = 17;

    double con_none = 0; 
    double con_line = 1; 
    double con_bar = 2;     
    double con_stack = 3;

    double horiz_axe_1 = 1; 
    double vert_axe_1 = 2; 
    double horiz_axe_2 = 4; 
    double vert_axe_2 = 8;

    double horiz_axe = 0; 
    double vert_axe = 1;

    double horiz_text = 0; 
    double vert_text = 1;

    double graf_no_just = 0; 
    double graf_bar_just = 1;

    double black = 0;     
    double blue = 1; 
    double green = 2; 
    double cyan = 3; 
    double red = 4; 
    double magenta = 5; 
    double brown = 6; 
    double lightgray = 7; 
    double darkgray = 8; 
    double lightblue = 9; 
    double lightgreen = 10;
    double lightcyan = 11; 
    double lightred = 12;     
    double lightmagenta = 13; 
    double yellow = 14; 
    double white = 15;

    double ps_solid = 0; 
    double ps_dash = 1; 
    double ps_dot = 2; 
    double ps_dashdot = 3; 
    double ps_dashdotdot = 4;

    double true = 1; 
    double false = 0;

    double nNumbersX = 0;
    double nDateX = 1;


Once again, there is only one reason for these variables - our convenience. Compare
DRAW_AXES(2, 4, 2, 2, 1, 4, 0 + 1 + 2 + 3);
and
DRAW_AXES(blue, red, ps_dot, green, 1, 4, horiz_axe_1 + vert_axe_1 + horiz_axe_2 + vert_axe_2);
In which case you have less problems ubderstanding the code?

Next thing we need is some data to plot on our charts. Using what we already know about arrays, lets create few and fill them with numbers.

sample_07.tsc, part 2

PRINT("%s\r\n", "Performing initialization of arrays of demo data");

array arr_x = CREATE_ARRAY(0);
arr_x[0] = 0; arr_x[1] = 1; arr_x[2] = 2; 
    arr_x[3] = 3; arr_x[4] = 4; 
arr_x[5] = 5; arr_x[6] = 6; arr_x[7] = 7; 
    arr_x[8] = 8; arr_x[9] = 9;

array arr_y = CREATE_ARRAY(0);
arr_y[0] = 0; arr_y[1] = 1; arr_y[2] = 2; 
    arr_y[3] = 3; arr_y[4] = 4; 
arr_y[5] = 5; arr_y[6] = 4; arr_y[7] = 3; 
    arr_y[8] = 2; arr_y[9] = 3;

array arr_y1 = CREATE_ARRAY(0);
arr_y1[0] = 0; arr_y1[1] = 2; arr_y1[2] = 4; 
    arr_y1[3] = 8; arr_y1[4] = 16; 
arr_y1[5] = 16; arr_y1[6] = 8; arr_y1[7] = 4; 
    arr_y1[8] = 2; arr_y1[9] = 0;

array arr_shifts = CREATE_ARRAY(0);
for(double i = 0; i < 20; i = i + 1)
{
    arr_shifts[i] = 0;
}
.......

In the code above, the arr_shifts array is very important. When we create bars (one bar is displayed on top of another, or side to side), we need to tell the function, where the previous bar was! So we pass this array to the function every time we plot another dataset on the same chart (only when we do bar charts). For example, let's say, we need to plot 3 datasets on a bar chart. It means, that bars of the first dataset (1,1; 2, 2; 3,1) will look like bars, with X coordinates 1, 2 and 3, and height 1, 2 1nd 1. Then, to draw the second dataset, we need to draw bars (perhaps, of the different colors) side to side to the first bars. How should the program know what shift to use? For the bars of the first dataset, the shift is 0, for the second - it is the width of the bars of the first dataset, for the third - double width (width of the bar of the first dataset plus width of the bar of the second dataset) and so on. These shifts are kept in an extra parameter, arr_shifts, all you need to do is to create an empty array, fill it with zeros, and pass it to the corresponding function. After the first time, it will contain shifts for the bars of the second array, and so on.

Next, we need to decide what colors to use. We can use default colors, but it is not necessarily the best choice.

sample_07.tsc, part 3

PRINT("%s\r\n", "Performing initialization of 
    arrays of demo colors and styles for 
    markers and connectors");

ADD_SERIES_STYLE(marker_rect, con_line);
MARKER_SET_COLOR(red, red, 1);
CONNECTOR_SET_COLOR(red, red, 1);

ADD_SERIES_STYLE(marker_circle, con_line);
MARKER_SET_COLOR(green, green, 1);
CONNECTOR_SET_COLOR(green, red, 1);

ADD_SERIES_STYLE(marker_non, con_line);
MARKER_SET_COLOR(magenta, magenta, 1);
CONNECTOR_SET_COLOR(magenta, magenta, 1);

ADD_SERIES_STYLE(marker_bar, con_bar);
MARKER_SET_COLOR(red, yellow, 1);
CONNECTOR_SET_COLOR(green, cyan, 1);

ADD_SERIES_STYLE(marker_bar, con_bar);
MARKER_SET_COLOR(green, cyan, 1);
CONNECTOR_SET_COLOR(green, cyan, 1);

ADD_SERIES_STYLE(marker_bar3d, con_bar);
MARKER_SET_COLOR(red, yellow, 1);
CONNECTOR_SET_COLOR(red, yellow, 1);

ADD_SERIES_STYLE(marker_bar3d, con_bar);
MARKER_SET_COLOR(lightred, lightblue, 1);
CONNECTOR_SET_COLOR(lightred, lightblue, 1);

ADD_SERIES_STYLE(marker_s_bar, con_bar);
MARKER_SET_COLOR(red, yellow, 1);
CONNECTOR_SET_COLOR(red, yellow, 1);

ADD_SERIES_STYLE(marker_s_bar, con_bar);
MARKER_SET_COLOR(lightred, lightblue, 1);
CONNECTOR_SET_COLOR(lightred, lightblue, 1);

ADD_SERIES_STYLE(marker_s_bar3d, con_bar);
MARKER_SET_COLOR(red, yellow, 1);
CONNECTOR_SET_COLOR(red, yellow, 1);

ADD_SERIES_STYLE(marker_s_bar3d, con_bar);
MARKER_SET_COLOR(lightred, lightblue, 1);
CONNECTOR_SET_COLOR(lightred, lightblue, 1);

The preparation is complete, here goes our first chart

sample_07.tsc, part 4

PRINT("%s\r\n", "Line and Markers chart, automatic 
    labels calculation");

SET_CHART_CLIP(40, 40, 240, 240);

CALC_SCALE(arr_x, horiz_axe, true, graf_no_just);
CALC_SCALE(arr_y, vert_axe, true, graf_no_just);
CALC_SCALE(arr_y1, vert_axe, false, graf_no_just);

SET_AXE(horiz_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(horiz_axe_2, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_2, 5, horiz_text, nNumbersX);

DRAW_AXES(blue, red, ps_dot, green, 1, 4, 
    horiz_axe_1 + vert_axe_1 + horiz_axe_2 
    + vert_axe_2);

DRAW_CROSS();

PLOT(0, arr_x, arr_y, 10);
PLOT(1, arr_x, arr_y1, 10);

First, we have specified the size of a chart, by calling the SET_CHART_CLIP.

Then, we calculated the scale, for one x array and two y arrays (we are going to plot two datasets that share the same X data, just in this example).

Then we specify text layout, style and number of ticks for axes.

Then we draw axes, the cross (two lines intersecting in 0,0) and two datasets.

Note how the poor choice of number of ticks and type of grid made the chart look "bad". Later, we will produce better examples.

The second chart is using the "manual scaling", giving you more control over the axes.

sample_07.tsc, part 5

PRINT("%s\r\n", "Line and Markers chart, manual 
    scaling, automatic labels calculation");

SET_CHART_CLIP(300, 40, 500, 240);

CALC_SCALE(arr_x, horiz_axe, true, graf_no_just);

SET_CHART_SCALE(-1, -2, 12, 17);

SET_AXE(horiz_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(horiz_axe_2, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_2, 5, horiz_text, nNumbersX);

DRAW_AXES(blue, red, ps_dot, green, 1, 4, 
    horiz_axe_1 + vert_axe_1 + horiz_axe_2 + 
    vert_axe_2);

DRAW_CROSS();

PLOT(0, arr_x, arr_y, 10);
PLOT(1, arr_x, arr_y1, 10);

In the next example, we are drawing line and bars on the same chart. We do it using SERIES_STYLE of different types.

sample_07.tsc, part 6

PRINT("%s\r\n", "Combined Bar and Line chart, 
    automatic labels calculation, 2 axes only");

SET_CHART_CLIP(580, 40, 780, 240);

CALC_SCALE(arr_x, horiz_axe, true, graf_no_just);
CALC_SCALE(arr_y, vert_axe, true, graf_bar_just);
CALC_SCALE(arr_y1, vert_axe, false, graf_bar_just);

SET_AXE(horiz_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(horiz_axe_2, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_2, 5, horiz_text, nNumbersX);

DRAW_AXES(blue, red, ps_dot, green, 1, 4, 
    horiz_axe_1 + vert_axe_1);

DRAW_CROSS();

PLOT(3, arr_x, arr_y, 10, arr_shifts); 
PLOT(4, arr_x, arr_y1, 10, arr_shifts);
PLOT(2, arr_x, arr_y, 10);

Let's create bar3d charts, which is, generally, the same as in the example above, just with the 3d shadows.

sample_07.tsc, part 7

PRINT("%s\r\n", "Combined Bar3d and Line chart, 
    automatic labels calculation, 2 axes only");

SET_CHART_CLIP(40, 280, 300, 480);

for(i = 0; i < 20; i = i + 1)
{
    arr_shifts[i] = 0;
}

CALC_SCALE(arr_x, horiz_axe, true, graf_no_just);
CALC_SCALE(arr_y, vert_axe, true, graf_bar_just);
CALC_SCALE(arr_y1, vert_axe, false, graf_bar_just);

SET_AXE(horiz_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(horiz_axe_2, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_2, 5, horiz_text, nNumbersX);

DRAW_AXES(blue, red, ps_dot, green, 1, 4, 
    horiz_axe_1 + vert_axe_1);

DRAW_CROSS();

PLOT(5, arr_x, arr_y, 10, arr_shifts); 
PLOT(6, arr_x, arr_y1, 10, arr_shifts);
PLOT(2, arr_x, arr_y, 10);

Note, that at the moment there is no scrolling in the Draw Panel, you will have wi resize it, to see all charts.

Stacked bar charts are a bit more difficult (note the way we keep passing arr_shifts array):

sample_07.tsc, part 8

PRINT("%s\r\n", "Combined Stacked Bar and Line chart, 
    automatic labels calculation, 2 axes only");

SET_CHART_CLIP(340, 280, 560, 480);

array arr_delta = CREATE_ARRAY(0);
for(i = 0; i < 20; i = i + 1)
{
    arr_shifts[i] = 0;
    arr_delta[i] = 0;
}

GET_STACKED(arr_y, 10, arr_delta);
GET_STACKED(arr_y1, 10, arr_delta);

CALC_SCALE(arr_x, horiz_axe, true, graf_no_just);
CALC_SCALE(arr_delta, vert_axe, true, graf_bar_just);

SET_AXE(horiz_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(horiz_axe_2, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_2, 5, horiz_text, nNumbersX);

DRAW_AXES(blue, red, ps_dot, green, 1, 4, 
    horiz_axe_1 + vert_axe_1);

DRAW_CROSS();

PLOT(7, arr_x, arr_y, 10, arr_shifts); 
PLOT(8, arr_x, arr_y1, 10, arr_shifts);
PLOT(2, arr_x, arr_y, 10);

As before, we can add the 3d effect to our bars:

sample_07.tsc, part 9

PRINT("%s\r\n", "Combined Stacked Bar3d and Line chart, 
    automatic labels calculation, 2 axes only");

SET_CHART_CLIP(600, 280, 840, 480);

for(i = 0; i < 20; i = i + 1)
{
    arr_shifts[i] = 0;
    arr_delta[i] = 0;
}

GET_STACKED(arr_y, 10, arr_delta);
GET_STACKED(arr_y1, 10, arr_delta);

CALC_SCALE(arr_x, horiz_axe, true, graf_no_just);
CALC_SCALE(arr_delta, vert_axe, true, graf_bar_just);

SET_AXE(horiz_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_1, 5, horiz_text, nNumbersX);
SET_AXE(horiz_axe_2, 5, horiz_text, nNumbersX);
SET_AXE(vert_axe_2, 5, horiz_text, nNumbersX);

DRAW_AXES(blue, red, ps_dot, green, 1, 4, 
    horiz_axe_1 + vert_axe_1);

DRAW_CROSS();

PLOT(9, arr_x, arr_y, 10, arr_shifts);
PLOT(10, arr_x, arr_y1, 10, arr_shifts);
PLOT(2, arr_x, arr_y, 10);

Finally, we need to "close" the drawing session, so that the result appears on screen:

sample_07.tsc, part 10

    END_DRAWING();

More charts, XML and IE

There is another way of drawing charts, that also allows you to perform some other useful tasks. To do it, we will use the third type of output window Cortex has (first two were text output and draw panel): the Web Browser Window.

To practice, let's load a file from the disk, containing stock quotes for Genzyme (the file comes with the Cortex archive). Then we will draw a chart of daily closing prices against dates.

sample_08.tsc

void main()
{
    string strDataPath = 
    "C:\\S_Projects\\CortexPro\\data\\samples\\stocks\\genz.txt";
    double bIsPathRelative = 0;

    array arrDate = CREATE_ARRAY(0);
    array arrClose = CREATE_ARRAY(0);

    TABLE_LOADER(strDataPath, bIsPathRelative, 1, "", 1, 
        "<!-- chart1.", 0, arrDate, 6, arrClose);

    Chart();
}
// -------------------------------------------
void Chart()
{
    string strXML = "";
    strXML = strXML + "<stocks>";

    string strPath = 
        "c:\\S_Projects\\CortexPro\\data\\samples\\images\\";
    string strStockName = "genz";

    string strFullPath = strPath + strStockName + ".png";    

    strXML = strXML + "<symbol>";
    strXML = strXML + "<symbol>";
    strXML = strXML + strStockName;
    strXML = strXML + "</symbol>";

    strXML = strXML + SAVE_CHART(400, 200, 1, strFullPath, 
        arrDate, arrClose);

    strXML = strXML + "</symbol>";
    strXML = strXML + "</stocks>";

    SAVE_XML(strPath, "chart_dayend", "chart_dayend", 
        "root", strXML);
    SHOW_XML(strPath + "chart_dayend.xml");
}

The SAVE_CHART function is a bit less flexible then tools you have with direct drawing on Draw Panel, but it can save pictures on disk in form of PNG files (for all practical reasons, PNG is the same as GIF).

In the code, we are building the strXML string, one that we later save using SAVE_XML, to produce the file, that can be displayed using Internet Explorer. The SHOW_XML does just that - brings up a window with IE control.

Note, that XML files use XSL files, ones that you can either take from the samples\images directory, or create yourself. To learn basics of XML, visit Free XML tutorial web page.

Files

To work with a file, you need to OPEN it. If the file was opened successfully, you get a handler - number, that you can use to represent a file. If the open operation failed, you get -1.

After the file is opened, you can write to it, using either F_PRINT function (same as PRINT, except the first argument need to be a file handler), or by calling F_WRITE function.

You can read from file, using the F_READ function.

sample_09.tsc

void main()
{
    OUT_CLEANUP();

    // Open a file for writing in binary mode (wb)
    double hFile = F_OPEN(
        "c:\\s_projects\\CortexPro\\data\\test.txt", "wb");
    F_PRINT(hFile, "%s", "This is a test\r\n");

    double bResult = F_WRITE(hFile, "This is a write test\r\n");
    
    F_CLOSE(hFile);

    // At this point you can open TEST.TXT in text editor to 
    //    take a look at the result

    // Open file for reading
    hFile = F_OPEN("
        c:\\s_projects\\CortexPro\\data\\test.txt", "rb");
    
    // Move a point from which we will start reading
    bResult = F_SEEK(hFile, 3, 0);

    string str;

    // Read up to 20 characters
    bResult = F_READ(hFile, str, 20);
    
    // Read one line of text
    string str_1 = F_GETS(hFile);
    
    // Get file cursor position
    double nPos = F_GETPOS(hFile);
    PRINT("%s", str, ", %s", str_1, ", %2.0f\r\n", nPos);

    F_CLOSE(hFile);

    // Rename a file
    bResult = F_RENAME(
        "c:\\s_projects\\CortexPro\\data\\test.txt", 
        "c:\\s_projects\\CortexPro\\data\\test_1.txt");

    // Copy a file
    bResult = F_COPY(
        "c:\\s_projects\\CortexPro\\data\\test_1.txt", 
        "c:\\s_projects\\CortexPro\\data\\test_2.txt");

    // Delete a file
    bResult = F_UNLINK(
        "c:\\s_projects\\CortexPro\\data\\test_1.txt");
}

Notice the use of OUT_CLEANUP(); function - this way we always begin with the clean output window.

Internet

The way we work with the Internet is very simple. First, we need to open the Internet session with OPEN_HTTP_SESSION function. Then we can download one or more files, using calls to GET_HTTP function. Finally, when done, we need to close the Internet session by calling CLOSE_HTTP_SESSION.

sample_10.tsc

void main()
{
    OUT_CLEANUP();

    // Open the Internet session
    double bResult = OPEN_HTTP_SESSION();

    if(bResult == 1)
    {
        // Download a file
        string strBuffer = GET_HTTP(
            "http://snowcron.com/index.html", bResult);

        if(bResult == 1)
        {
            // Save the result to local disk
            string strFileName = 
                "c:\\s_projects\\CortexPro\\data\\samples\\test.htm";
            double hFile = F_OPEN(strFileName, "wb");
            if(hFile == -1)
            {
                PRINT("%s", "Unable to create file\r\n");
            }
            else
            {
                F_PRINT(hFile, "%s", strBuffer);
                F_CLOSE(hFile);
            }
            
            // Show the result
            SHOW_XML(strFileName);
        }
        else
        {
            PRINT("%s", "Unable to download the file\r\n");
        }
    }
    else
    {
        PRINT("%s", "Unable to open the Internet session\r\n");
    }
}

In the example above, we have downloaded the file from the Internet, and then opened its copy, one that we created on a local disk.

See Stock Downloader for another example of the use of Cortex's Internet access functions. Stock Downloader is a SLANG script that runs by a timer, as the result, we have up to date stock or Forex quotes, downloaded from the Internet sources.

Also, Internet access functions allow you to download files, containing any data (HTML is a good example) and then, to analyze these files, using SLANG as a data analysis tool. Stock Downloader is just one example.

Neural Networks

Working with Neural Networks from SLANG programs is similar to working with files. As with files, you need to open a Neural Network, in order to receive a handle. This handle can be passed to other NN-related functions.

sample_nn_01.tsc, part 1

void main()
{
    array arrNN = CREATE_ARRAY(0);
    double dMA_1 = 14;
    string strStockPath = 
        "c:\\S_Projects\\CortexPro\\data\\samples\\stocks\\genz.txt";
    double bIsPathRelative = 0;
    array arrLags = CREATE_ARRAY(0);

    array arrDate = CREATE_ARRAY(0);
    array arrClose = CREATE_ARRAY(0);

    TABLE_LOADER(strStockPath, bIsPathRelative, 0, "", 1, 
        "<!-- chart1", 0, arrDate, 6, arrClose);

The code above downloads the data from the file genz.txt, one of the sample files that are included in Cortex archive.

sample_nn_01.tsc, part 2

    double hNN = OPEN_NN(
        "c:\\S_Projects\\CortexPro\\data\\samples\\nn\\genz.nn",
        0);

    for(double i = 0; i < 9; i = i + 1)
    {
        arrLags[i] = i + 1;
    }

    APPLY_NN(hNN, 1000, 1.0, 1, arrClose, arrLags, 1, arrNN);

    CLOSE_NN(hNN);

    ....
}
....

The code above opens the NN (previously created one), creates lags (we use simple lags, so instead of calling built-in function, we do it in cycle), applies NN to the data and closes NN.

There are few functions that allow you to do from script all things you can do by hand from the Cortex GUI. For example, you can create an empty NN, set number of layers, neurons, inputs, outputs and so on.

You can start the NN learning session, and specify at what conditions it should stop...

sample_nn_02.tsc

...
    CREATE_NN(strNnFileName, bIsPathRelative,
        strLagFileName, bIsPathRelative, nSkipBefore, 
        nSkipAfter, strStartLine, strEndLine, bReverseArrays, 
        arrInputColumns, arrInputColumnNames, arrOutputColumns, 
        arrOutputColumnNames, nExtractRecords, dStopError, 
        nStopEpoch, nNeuronsLayer1, nNeuronsLayer2, 
        nNeuronsLayer3, nNeuronsLayer4, nLayers, nActivation, 
        nAdjustRange, arrOutTabInputColumns, 
        arrOutTabInputColumnNames, arrOutTabOutputColumns, 
        arrOutTabOutputColumnNames);

        string strSeparator = ",;";

    CREATE_LAG_FILE(strStockFileName, bIsPathRelative, 
        strLagFileName, bIsPathRelative, nSkipBefore, 
        nSkipAfter, strStartLine, strEndLine, strSeparator, 
        bReverseArrays, arrColumns, arrColumnNames, 
        arrLags, nNumOfInputColumns);

    OPEN_NN_FILE(strNnFileName, 0, 1, 1, 1);
}

Sometimes, we process data as they arrive (a real time trading is a good example). To process all 10,000 records every time is very inconvenient. To handle this case, Cortex's scripting language has a function, that allows record-by record (or, to be more accurate, pattern-by-pattern) processing.

sample_nn_03.tsc

....
    double hNN = OPEN_NN(
        "c:\\S_Projects\\CortexPro\\data\\samples\\nn\\genz.nn",
        0);

    for(i = 9; i < ARRAY_SIZE(arrClose); i = i + 1)
    {
        for(double j = 0; j < 9; j = j + 1)
        {
            arrPattern[j] = arrCloseNorm[i - j - 1];
        }

        PATTERN_NN(hNN, arrPattern, dExtendRange);
        arrNN[i] = arrPattern[9];
    }

    CLOSE_NN(hNN);

....

In the code above, we opened the NN, and then feed it data, pattern by pattern. Pattern (for this particular network) is an array of the last 9 values of Close.


Often, we want to create and teach Neural Networks using Cortex, and then to use the results from some other packages. A good example is stock / Forex trading. Let's say, you have created the NN, that you would like to use from, say, Srade Station, MetaStock or MetaTrader.

First choice is to learn C++ and to use Cortex API, however it is not necessarily the best choice. All, or almost all trading packages have their own scripting languages - can we use our results (NN configuration) there, without fighting our way through C++ and DLLs? After all, when the NN is created and teached, all heavy computations are done, and you could have do the rest even using relatively slow scripting engines of your favorite trading package - if you had access to the weights of a fully trained NN, and knew what to do with them.

That is why the GET_NN_WEIGHTS function was created.

The function itself returns weights for a specified layer:
array arrWeights = GET_NN_WEIGHTS(hNn, nLayer);

Let's say, we are retrieving weights for the 1st layer, and there are 5 neurons in the previous, 0th layer. Then array elements 0 - 4 will contain weights for the 1st neuron, and so on.

Below, we have two examples. The first one is to show, how to retrieve weights of the fully trained NN (sample_nn_05), and the second one (sample_nn_06) is to "emulate" the NN without Cortex-specific calls.

It means, that, having "some other trading package", with "some other scripting language", you will be able to port this code from SLANG to that scripting language, and to have NN functionality in your favorite trading package, without the need to learn this packages API and Cortex's API.

sample_nn_05.tsc

void main()
{
    // Clean the output window
    OUT_CLEANUP();

    // Here we are going to keep images and XML
    string strImagePath = 
        "c:\\S_Projects\\CortexPro\\data\\samples\\images\\";

    // FOREX symbol we use in this example
    string strForexName = "EURUSD_H1";    
    
    // Name of the image file we will produce
    string strImageFileName = strImagePath + 
        strForexName + "_05.png";

    // Name of the NN
    string strNnPath = 
        "c:\\S_Projects\\CortexPro\\data\\samples\\nn\\";
    string strNnFileName = strNnPath + strForexName + "_05.nn";

    // ------------

    // Name of the FOREX quotes file (comes with Cortex)
    string strDataFileName = 
        "c:\\S_Projects\\CortexPro\\data\\samples\\forex\\"
        + strForexName + ".TXT";

    // Name of the lag file we will create
    string strLagFileName = 
        "c:\\S_Projects\\CortexPro\\data\\samples\\nn\\"
        + strForexName + "_05.lgg";
    
    // We are going to use absolute path to file(s)
    double bIsPathRelative = 0;

    // Arrays to store quotes
    array     arrDate = CREATE_ARRAY(0);
    array arrTime = CREATE_ARRAY(0);
    array arrOpen = CREATE_ARRAY(0);
    array arrHigh = CREATE_ARRAY(0);
    array arrLow = CREATE_ARRAY(0);
    array arrClose = CREATE_ARRAY(0);

    // Load the quotes from the quotes file
    TABLE_LOADER(strDataFileName, bIsPathRelative, 
        0, "", 0, "", 0, arrDate, 1, arrTime, 2, arrOpen, 
        3, arrHigh, 4, arrLow, 5, arrClose);

    // Interval for CLV indicator (that's what NN will predict)
    double nInterval = 64;
    // MA to smooth the CLV indicator
    double nMa = 3;
    
    // Create CLV indicator and apply MA to it
    array arrClv = CreateClv(nInterval);
    array arrClvSmooth = EXP_MVAVG(arrClv, nMa);

    // We are going to predict it 2 bars (2 hours) into future
    double nOutLag = 2;
    double nRemoveFirst = 200;
    array arrLags = CREATE_ARRAY(0);
    
    // ATTN: These lags are based on nOutLag. 
    // Example: nWinLag = 2, then each number 
    // should be increased by 2
    // The first number (9) is the total number of elements in the
    // lags array (there are 9 numbers after 9 in this string)
    string strLagBuf = "9,0,1,2,3,4,8,12,16,20";

    // Create the lag file, save it to disk
    CreateLagFile(strLagBuf, nRemoveFirst);

    // We are going to use the first 70% of the records as 
    // "learning set", and the rest as "testing set"
    double nExtractRecords = 0.7 * ARRAY_SIZE(arrClose);

    // Additional parameters of the NN we want to create
    double nNeurons = 5;
    double dStopError = 0;
    double nStopEpoch = 5000;

    // The output (predicted) array
    array arrNn = CREATE_ARRAY(0);

    // Create a new NN
    NewNn(arrLags, dStopError, nStopEpoch, nNeurons);
    
    // Bring up the dialog, teach the NN
    TeachNn();

    // We are ready to use the NN. First, obtain the handler
    double hNn = OPEN_NN(strNnFileName, bIsPathRelative);
    
    // Apply NN. We don't really need it to get weights, but 
    // as, just for this example, we are drawing a chart, 
    // we may want to plot predicted values as well.
    APPLY_NN(hNn, nExtractRecords, 1.0, 1, arrClvSmooth, 
        arrLags, 1, arrNn);

    // Get and print the values of the NN weights

    PRINT("%s\r\n", "Layer 1");

    array arrWeights = GET_NN_WEIGHTS(hNn, 0); 
    
    // "9" is number of lags, same as number of inputs of the 1st layer
    // It is also number of neurons in the 1st layer
    for(double nNeuron = 0; nNeuron < 9; nNeuron = nNeuron + 1)
    {
        PRINT("Neuron %.0f: ", nNeuron);

        for(double nInput = 0; nInput < 9; nInput = nInput + 1)
        {
            PRINT("%f, ", arrWeights[9 * nNeuron + nInput]);
        }

        PRINT("%s", "\r\n");
    }

    PRINT("%s\r\n", "Layer 2");

    array arrWeights = GET_NN_WEIGHTS(hNn, 1); 
    
    // "nNeurons" is number of neurons in the 2nd (hidden) layer
    // "9" is number of inputs (same as number of neurons in the 
    // previous (1st) layer
    for(double nNeuron = 0; nNeuron < nNeurons; nNeuron = nNeuron + 1)
    {
        PRINT("Neuron %.0f: ", nNeuron);

        for(double nInput = 0; nInput < 9; nInput = nInput + 1)
        {
            PRINT("%f, ", arrWeights[nNeurons * nNeuron + nInput]);
        }

        PRINT("%s", "\r\n");
    }

    PRINT("%s\r\n", "Layer 3");

    array arrWeights = GET_NN_WEIGHTS(hNn, 2); 
    
    // 1 neuron
    // "nNeurons" is number of inputs (same as number of neurons in the 
    // previous (2nd) layer

    for(double nInput = 0; nInput < nNeurons; nInput = nInput + 1)
    {
        PRINT("%s", "Neuron 1: ");

        PRINT("%f, ", arrWeights[nInput]);

        PRINT("%s", "\r\n");
    }

    CLOSE_NN(hNn);

    PRINT("%s\r\n", "Done");
}

// ---------------

// This indicator is included with "Indicators pack",
// that comes with Cortex Scripting Language

array CreateClv(double nInterval)
{    
    PRINT("%s\r\n", "Creating CLV indicator");

    array arrClv = CREATE_ARRAY(0);
    array arrPeriodLow = CREATE_ARRAY(0);
    array arrPeriodHigh = CREATE_ARRAY(0);

    double nArraySize = ARRAY_SIZE(arrClose);

    array arrPeriodLow = MVMIN(arrLow, nInterval);
    array arrPeriodHigh = MVMAX(arrHigh, nInterval);

    for(double i = 0; i < nInterval; i = i + 1) 
    {
        arrClv[i] = 0;
    }
    
    double dClose;
    double dLow;
    double dHigh;
    for(i = nInterval; i < nArraySize; i = i + 1)
    {
        dClose = arrClose[i];
        dLow = arrPeriodLow[i];
        dHigh = arrPeriodHigh[i];

        // / 2 + 1 to confine to 0...1 instead of -1...1
        arrClv[i] = (((dClose - dLow) - (dHigh - dClose))
            / (dHigh - dLow)) / 2 + 0.5; 
    }

    return arrClv;
}

// ----------------

// Create file with lags on disk, see Introduction to 
// neural networks (neural_networks.htm) for details 
//    on what lags are and why we need them

void CreateLagFile(string strLags, double nRemoveFirst)
{
    double hFile = F_OPEN(strLagFileName, "wb");

    F_PRINT(hFile, "%s", "No,Clv");

    ARRAY_REMOVE(arrLags, -1);
    string strToken = GET_TOKEN(strLags, ",");
    double nNumOfLags = STR2NUM(strToken);
    
    for(double i = 0; i < nNumOfLags; i = i + 1)
    {
        strToken = GET_TOKEN(strLags, ",");
        arrLags[i] = STR2NUM(strToken) + nOutLag;
    }

    double nFullLag;
    for(i = 0; i < ARRAY_SIZE(arrLags); i = i + 1)
    {
        nFullLag = arrLags[i];
        F_PRINT(hFile, ",ClvMa%.0f", nMa, "-%.0f", nFullLag); 
    }

    F_PRINT(hFile, "%s\r\n", "");

    double nNum;
    for(i = nRemoveFirst; i < ARRAY_SIZE(arrClose); i = i + 1)
    {
        nNum = i - nRemoveFirst + 1;
        F_PRINT(hFile, "%.0f", nNum, ",%f", arrClvSmooth[i]);     

        for(double j = 0; j < ARRAY_SIZE(arrLags); j = j + 1)
        {
            F_PRINT(hFile, ",%f", arrClvSmooth[i - arrLags[j]]);     
        }

        F_PRINT(hFile, "%s\r\n", "");
    }

    F_CLOSE(hFile);
}

// --------------

// Create a new NN on disk. This code have already been
// explained in this tutorial

void NewNn(array arrLags, double dStopError, 
    double nStopEpoch, double nNeuronsLayer2)
{
    double nSkipBefore = 0;
    double nSkipAfter = 0;
    string strStartLine = "";
    string strEndLine = "";
    double bReverseArrays = 0;

    // Inputs
    array arrInputColumns = CREATE_ARRAY(0);
    array_s arrInputColumnNames = CREATE_ARRAY_S(0);
    
    // 0  - Number, 1 - Clv, our input begins at column No 2

    for(double nInputCol = 0; nInputCol < ARRAY_SIZE(arrLags); 
        nInputCol = nInputCol + 1) 
    {
        arrInputColumns[nInputCol] = nInputCol + 2;
        arrInputColumnNames[nInputCol] = 
            "Clv-" + NUM2STR(arrLags[nInputCol], "%.0f"); 
    }

    array arrOutputColumns = CREATE_ARRAY(0);
    arrOutputColumns[0] = 1;    // Clv

    array_s arrOutputColumnNames = CREATE_ARRAY_S(0);
    arrOutputColumnNames[0] = "Clv";

    // To do: Modify if more than one indicator is used
    double nNeuronsLayer1 = ARRAY_SIZE(arrLags);
//    double nNeuronsLayer2 = 7;
    double nNeuronsLayer3 = 1;
    double nNeuronsLayer4 = 0;
    double nLayers = 3; 
    double nActivation = 0;
    double nAdjustRange = 1.0;

    array arrOutTabInputColumns = CREATE_ARRAY(0);
    arrOutTabInputColumns[0] = 0;    // Number

    array_s arrOutTabInputColumnNames = CREATE_ARRAY_S(0);
    arrOutTabInputColumnNames[0] = "No";

    array arrOutTabOutputColumns = CREATE_ARRAY(0);
    // Desired output and NN output will be added to the 
    // same list, right after inputs
    arrOutTabOutputColumns[0] = ARRAY_SIZE(arrLags) + 2;    
    arrOutTabOutputColumns[1] = ARRAY_SIZE(arrLags) + 3;

    array_s arrOutTabOutputColumnNames = CREATE_ARRAY_S(0);
    arrOutTabOutputColumnNames[0] = "Clv"; 
    arrOutTabOutputColumnNames[1] = "NN: Clv" ;

    CREATE_NN(strNnFileName, bIsPathRelative, strLagFileName, 
        bIsPathRelative, nSkipBefore, nSkipAfter, strStartLine, 
        strEndLine, bReverseArrays, arrInputColumns, 
        arrInputColumnNames, arrOutputColumns, 
        arrOutputColumnNames, nExtractRecords, dStopError, 
        nStopEpoch, nNeuronsLayer1, nNeuronsLayer2, 
        nNeuronsLayer3, nNeuronsLayer4, nLayers, 
        nActivation, nAdjustRange, arrOutTabInputColumns, 
        arrOutTabInputColumnNames, arrOutTabOutputColumns, 
        arrOutTabOutputColumnNames);
}

// ----------------

void TeachNn()
{
    PRINT("%s\r\n", "Opening NN dialog, teaching the NN");

    double bStartLearning = 1; 
    double bResumeScript = 1;
    double bReset = 1;

    OPEN_NN_FILE(strNnFileName, bIsPathRelative, 
        bStartLearning, bResumeScript, bReset);
}

// -------------

void Chart(string strForexName)
{
    string strXML = "<forex>\r\n";

    strXML = strXML + 
        "\t<symbol>\r\n\t\t<symbol>\r\n";

    strXML = strXML + "\t\t</symbol>\r\n";

    strXML = strXML + "\t\t" + SAVE_CHART(400, 300, 
        0, strImageFileName, 
        arrDate, arrClvSmooth, arrNn);
    strXML = strXML + "\t</symbol>\r\n";

    strXML = strXML + "</forex>\r\n";
    SAVE_XML(strImagePath, "chart_forex_nn_05", 
        "chart_forex_nn", "root", strXML);
    SHOW_XML(strImagePath + "chart_forex_nn.xml");

}

In this example you will find a working system that is created, step by step, and then moved from Cortex to the trading platform, capable to place real trades with the real brocker.

sample_nn_05.tsc


Conclusion

In the SLANG Scripting language Reference guide you will find a complete list of built-in functions, with return types, parameters and so on.

Link to us and make 20% commissions through our affiliate program

Free Stock trading Course

The course consists of five E.mails and covers all essentials of Technical Analysis approach to Stock Trading. Compare to $$$ that you will have to pay elsewhere. All you need to do is to enter your name (nickname will do) and E.mail address in the form below.

Name: E-Mail:


Free intros:

State of Power Tutorial

Hypnosis Tutorial

NLP Tutorial

Working with the Future Tutorial

Hypnotic Inductions

Working with Money

Working with Habits

Manipulation Tutorial


Karate online tutorial

Chi Gun online tutorial

Tai Chi 24 forms online tutorial

Tai Chi 40 forms online tutorial

Tai Chi 108 forms online tutorial

Tai Chi Chi Gun 18 forms online tutorial

Chi Gun (Dao In) Heart and Blood Vessels 8 forms online 
tutorial

Chi Gun (Dao In) Kidneys 8 forms online tutorial

Joints Gymnastics, Chi Gun warm-up online tutorial

Chi Gun tao of Dr. Shi online tutorial


Sore back treatment

Headache Relief Pressure Points Tutorial


Stock trading - technical analysis

Making a small profitable web site

Neural Networks

Flow Charts and decision trees for web sites and 
presentations

Another powerfull Flow Charts Designer

Site Downloader

Thumbnails Generator

Calendar Creator

Touch Typing


Photo gallery


Jewelry: Pearl. How to choose, price estimation,
					take care, history, legends, classification Pearl. How to choose, price estimation, take care, history, 
legends, classification Artifficial Pearl. Links to: How to choose pearl, estimate price, 
take care, history, legends, classification Buying Pearl. Links to: How to choose, estimate price, take care, 
history, legends, classification Jewelry: Pearl. Taking care. Links to: How to choose, estimate 
price, history, legends, classification Jewelry: Classification of Pearl. Links to: How to choose, 
estimate price, take care, history, legends Jewelry: Cultivated Pearl. Links to: How to choose, estimate 
price, take care, history, legends, classification Jewelry: Pearl. History and legends. Links to: How to choose, 
estimate price, take care, classification Jewelry: Pearl. Price estimation. Links to: How to choose, take 
care, history, legends, classification Jewelry: Pearl. What is it? Links to: How to choose, estimate 
price, take care, history, legends, classification


NLP, Hypnosis, Power, Manipulation Tai Chi, Chi Gun Neural Networks
Joints Gymnastics Photo album generator
Habit Management Karate tutorial Flow charts for Presentations and Web

Sore back treatment Calendar Creator
Building a small profitable site
Another powerfull Flow Charts Designer
Profitable web site in 9 days Web programming : Perl, XML Site Downloader
Web positioning Shareware Directory


Touch Typing
Stock and FOREX Trading Stock Photo Gallery

Keywords:

review software stock trading
The Stock Downloader program allows you to automatically download free live stock quote files from the yahoo historical stock quote server.
Both historical intraday stock data and yahoo historical stock quote files can be downloaded.

day trading e book
A free e.mail trading course containing 5 e.mails with stock day trading tip information is available from this site. In this e.mails, the basics of computer system trading is covered.
The links in the left column can be used as a day trading tutorial, containing multiple day trading how to stock day trading tips for the technical investment analysis.

atr breakout
This article covers the Advanced True Range indicator. It includes the basic information, formulas and an example case study.

investing quote stock
This site offers tutorials for both day profit trading and day end trading.
Software available for downloading includes stock downloader for historical intraday data and yahoo historical stock quote files with day end quotes.

archive quote stock
The yahoo historical stock quote archives can be downloaded from the Internet automatically using the Stock Downloader software.

current quote stock yahoo
Yahoo server provides stock market quote historical data, available for downloading from the Internet as CSV (comma separated) files. These files are updated daily, after the markets close.
Yahoo server also provides 15 minutes delayed intraday quotes that can be downloaded by the Stock Downloader as they appear online.

commodity market system trading
The tutorials available from this site can be used for online day trading education.
The Trader trading simulator can produce trading signals based on the indicators. You can use indicators, that come with the program, or create your own using Trader's built-in scripting language.

stock trend chart
The Trader trading simulator is an example of chart pattern recognition software - it can detect price trends, plot them and use them to generate trading signals.

stock day trading tip
The trading course, available as five e.mails contains trading tips and well-known (but mostly ignored) common sence trading rules.

sp 500 trading system
To create your own indicators, for example, as part of sp 500 trading system, use Trader's built-in scripting language.

The language resembles the Basic, and gives you the access to many functions, such as convergence divergence test, chart pattern recognition, point figure charting and much more.

historical market quote stock
Use the Stock Downloader to download both intraday and day end stock quotes from the Yahoo stock server.
The program provides you with high degree of flexibility, it is designed in such way, that you can leave it unattended for extended periods of time (months).

history market quote stock
Historical quotes available from the yahoo historical stock quote server are adjusted for splits.
The split files are available together with the stock quotes. However, downloading them is a much more difficult task.
The Stock Downloader will take care of it for you.

free system trading
Use the Stock Downloader together with the Trader program, to download free stock quotes and produce trading signals.
On this site you will find tutorials about stock trading, that will help you to buils your own trading systems.

day profit trading
The day trading uses the last moment information, and decisions have to be made FAST. That's why we use computers to make automatic decisions.
To do a successfull day living trading, you will need to practice on some kind of sample data first. This data can be obtained using the Stock Downloader program.
Note, that the quotes on Yahoo server are 15 minutes delayed.

day living trading
Can the day trading be profitable for you, and not just for your broker?
Read our trading course to learn the common sence tips and tricks.

convergence divergence test
When two lines come closer, it is called convergence. When they go in the opposite directions (one up, one down) - it is a divergence.
The thing is - the convergence / divergence test usually works faster than the convergence divergence indicator itself, providing predictive signals.

historical intraday stock data
When you use the Stock Downloader to get the intraday data, you will be connected to the Yahoo server. The 15 minutes delayed data are extracted from the Yahoo pages, together with the split information, if any.

definition ppo
This article covers the Percenmtage Price Oscillator indicator. It includes the basic information, formulas and an example case study.

formula macd
MACD stands for the Moving Average Convergence Divergence.
As you can guess from the title, the moving averages are calculated for the stock price, and the points of their intersections are used as trading signals.

screen stochastic
Stochastic indicators are trying to determine the buying and selling pressure. If the security is under the pressure, then sooner or later the price will adjust.
Mostly, these are range indicators.

real time day trading signal
The stock quotes from the Yahoo stock server are 15 minutes delayed. You can take this fact into consideration whan creating your own trading system, or simply use the downloaded data to learn the technical investment analysis before doing "the real thing".

downloader stock
The Stock Downloader is a program that uses Yahoo stock server to download stock quotes.
It will also download split information.

chart pattern recognition software
The Trader day trading simulation program is an example of the chart pattern recognition software. It can find the beginning and end of the price trend, and to generate trading signals using the convergence and divergence of the trendlines.

wmt stock quote
One of the stocks used as an example in the Trader tutorials is the WMT.


free live stock quote

The Stock Downloader works as a front end for any software taht can use it's files. It creates the free live stock quote files on the disk, and as the new information becomes available, appends it to these files.


past stock quote
The Stock Downloader makes the past stock quote information available as it will download historical quote files from the Yahoo for you.
As there is no historical intraday data files at the yahoo finance stock quote server, the Stock Downloader queries Yahoo once a minute, saving the data to the historical file of its own.

computer system trading
There is a number of free educational files on this site, containing free information on creating the trading system using computer.

historical stock quote free
Historical stock quotes can be downloaded from the Yahoo using the Stock Downloader program. The downloading process is automated.

day trading simulation
The Trader day trading simulation program works with the indicators, providing you with the free charts, including point figure charting, trading signals and pattern analysis.

download historical quote
When we use the Stock Downloader to download historical quote files from the Yahoo site, we have to keep in mind, that this quotes are delayed. Normally, it is a 15 minutes delay for the intraday quotes, and up to few hours delay for the day end stocks (they update their data after the markets are closed, and it takes some time).

day trading pattern
Read the free online tutorials, available from our site, to learn about creating the indicators, using trading patterns.

stock index trading system
The index can be treated same way you treat the individual stock. You can buy it, sell it, download its quotes, and create the indicator, that takes full advantage of this particular index's behaviour.

yahoo finance stock quote
This service provides day end files, available for downloading. The Stock Downloader program can do it automatically for you.
Also, the intraday data can be extracted from some pages on the yahoo finance stock quote server. The Stock Downloader can do this for you, too.

simulator trading
The Trader day trading simulation program provides you with the power of technical analysis. It performs charting, applies the indicators to produce the trading signals, and even can analyze the chart patterns.
Also, you can use the predictive power of the neural networks, together with this program, as part of the custom indicators.

moving average trading system
The use of moving averages extends from the simple data smoothing, to the complex indicators, based on convergence, divergence and pattern analysis.
On one side, the moving average is always behind. On the other side, the derived indicators can sometimes "look forward", predicting the future values.

trading indicator
Indicators can be used to produce trading signals.

free intraday charts
Use the data, obtained using Stock Downloader program, to create free intraday charts

day trading simulator
We strongly advice, that you use some kind of the day trading simulator, before doing the "real thing", risking the real money.

intraday quotes
The Stock Downloader creates two files for each stock, one with the intraday quotes, and one with the split information.

technical analysis stock screen
Using the Trader's built-in scripting language, you can write your own stock screen. However, try the stock screens available online, first.

yahoo historical stock quote
This service provides day end files, available for downloading. The Stock Downloader program can do it automatically for you.
Also, the intraday data can be extracted from some pages on the yahoo finance stock quote server. The Stock Downloader can do this for you, too.

macd convergence divergence
This is one of the most commonly used trading indicators. It is simple, reasonably reliable and can be implemented using computers.

technical indicator macd
The difference between two moving averages is used to test for the buy and sell signals.

point figure charting
The "timeless" indicator, making possible to perform pattern analysis in a fast and elegant way.

technical analysis of stock trend
The Trader program has built-in functions for the trend analysis, particularly, it can check, if the trends for two lines (like MACD and price) go in the different directions.

day trading techniques
Read our free introductions on the trading techniques.

technical analysis formula
The technical analysis takes into consideration the past price history of the security.

day trading tutorial
Read our free introductions on the trading techniques.

day trading how to
Grab the stock quotes using the Stock Downloader program.

macd formula
MACD indicator can be used on stock price. However, it can also be applied to the other indicators, providing us with the information on the direction and speed of changes.

trading system
Usually, one indicator is not enough to build a complete trading system. You need at least momentum indicator, stochastic indicator and stop criteria.

historical intraday data
When downloading the historical intraday data, you may leave the Stock Downloader unattended for couple of months. It will keep the system clock correct, reboot, if you select this option, and reconnect to the Internet at the beginning of the trading session.

technical investment analysis
The technical investment analysis doe not care about company - all it uses is the stock price history.

online day trading education
Subscribe to our 5 e.mails trading course

day trading faq
Check them, before spending any money.

stock market quote historical
Historical quotes can be downloaded for you automatically with the Stock Downloader program.

trading course
Subscribe to our 5 e.mails trading course

historical daily stock quote
There are many online sources, offering historical daily stock quotes. You need, however, to be aware of possible problems with data, some providers offer, such as gaps, spikes etc.

free real time streaming stock quote
There are also providers, offering free real time streaming stock quotes. Usually it comes with the "free trial" of their software packages. Some of these sources are reliable and accurate enough.

day profit trading
Day trading is at the borderline between profit and risk. Some people say it is impossible to consistently win at such short time frame, while some other say - it is.

previous stock quote
You can not possibly trade based only on thecurrent stock price. You need to analyze the history, at least, the previous stock price. Quote history should be always at hand.

ppo software
There are some companies, offering it. We do not have enough experience in that area.

current quote stock yahoo
Yahoo is one of the most known public data providers. Both current stock quotes, and stock history is available on most securities.

archive quote stock
It has to be mentioned, that stock quote archives, available online, are often of very high quality. Sometimes you may see them offered for a fee, usually, it means minute time frame and large (> 600 mb) amount of data.

historical market quote stock
Both historical stock quotes and last minute market information should be studied, as any trading system may produce errors, and it is the last minute information, that allows us to catch them.

review software stock trading
Stock and Forex trading software does not necessarily have to be expansive. As many reviews suggest, the most convenient packages include "free time unlimited demo account", and free trading client as well. A good example is www.metaquotes.net - a company, that has one of the best FOREX trading platforms, which is completely free.

stock trend chart
Stock prices move in trends, which can be analyzed on charts. This is one of the cornerstones of technical analysis.

quick quote stock
The time delay is inacceptable, when you do intraday trading. There are many data providers, offering free or almost free stock quotes, without a delay.

day living trading
Can you live off the day trading? There are many examples, supporting this point of view, however, it seems that most of the day traders loose.

history market quote stock
There are many reviews available on the history of the stock market. Some of them are based on the Dow theory, some - on the waves, and so on.

sp 500 trading system
SP 500 is an index, and as such, it contains much less noise. It makes it a perfect trading instrument, and you can use all tools from the technical and fundamental analysis.

formula macd
MACD indicator is described in details, with formulas, Cortex scripting code and charts, on this site, in the corresponding article.

free system trading
There are many trading forums online, and almost all of them offer free trading systems. Some of them are half-tested, while some are market-ready.

stock day trading tip
The most important day trading tip is to learn as much as you can, before you risk your money, rather than start as soon as you can.

commodity market system trading
The trading - in any market, including commodity market - requires a system. It means you need to know in advance, what to do in any situation, so that you don't have to waste time, desiding.

definition ppo
See online sources.

best system trading
What trading system is the best? As trading is a balance between the risk and the reward, the best system is case-dependent. It is up to you to figure out your risk tolerance.

investing quote stock
Using stock quotes to trade as a mean of an investment is not a single approach, but rather many different approaches, involving different methods of analysis, and different paradigmas.

free software stock trading
It is our belief, that a trading platform must be free. Only this way, the trader can get used to it before he invests.

day trading tool
As an example of a day trading tool, consider a MetaTrader. Note: this site does not represent MT. We just like the tool.

free live stock quote
The situation with free live stock quotes is constantly changing to the best. To find the best available offer, do a research on the Internet trading forums.

free streaming stock quote
When you do a day end trading, you don't need a streaming data feed. However, it is required for intraday.

stochastic definition
On this site, you will find both the definition of stochastic indicator, and the source code to implement it.

simulator trading
There are some fine simulators available free of charge, one example is a MetaTrader. However, a real time trading is always different, and the difference is often to the worse.

wmt stock quote
See finance.yahoo.com

day trading simulation
As an example, consider MetaTrader simulator. It emulates intraday ticks, creating reasonably accurate testing environment.

day trading pattern
Patterns are widely used in day trading, as the mater of fact, as price charts are fractal, any time frame can benefit from this approach.

stock quote download
Stock quotes can be downloaded from Yahoo (one possible way to automate this task is to use a free script that comes with Cortex).

historical stock quote free
Yahoo is probably the first thing that comes to mind, unless you need something very specific.

download historical quote
To download, simply go to their site, enter the ticket and select the time frame.

stock index trading system
Indexes are similar to the stocks, exept two things. First, thei have much less "noise". Second, the liquidity is much better. So by all means, they are good instruments.

current own quote stock yahoo
Yahoo is a well known stock quotes provider, they are delayed, though.

yahoo finance stock quote
Also, day end information at Yahoo is delayed, too.

past stock quote
Historical (past) stock quotes are used for technical analysis.

day trading simulator
Simulators can be used to test day trading systems, however, nothing can replace a real time demo account.

free stock trading system
There are many stock trading systems in the Internet, available free of charge.

best stock trading system
The best stock trading system is the one that suits your risk - reward ideas.

stock trading simulator
There are many stock trading simulators available online, some of them are free.

yahoo stock quote
Yahoo stock quote is one of the well known and reliable free services.

historical stock quote
Historical stock quotes can be obtaines from many sources, from free Yahoo, to commercial Reuters.

trading indicator
There are many trading indicators, available on this site. It includes both the description, and the source code.