TradeStation 8 Solutions   
TradeStation Solutions   
MetaStock Solutions   
Bloomberg Solutions   
Historical data tools   
Trading tools   
Genetic Optimizer   
Real-Time Portfolio Analyzer   
TradeStation to Excel Link   
Wavelet Transform   
TradeStation   
TradeStation to MatLab Link   
Trendiness   
DDE over Network   
Custom software development   
Customer support   
Our partners   
About us   
Publications   
Discussion Forum   

    RT Soft Trading tools Wavelet Transform 



eSignal Wavelet Transform

eSignal Solutions eSignal Solutions, Wavelet Transform

Trading Strategies with Powerful Software.

The complete indicator-based technical analysis without magic and profanation.


Anyone who uses the history of the prices change of anyhow deals with the technical analysis. The formalized part of the technical analysis appears to be so-called "indicators". The indicator, by definition of Mr. Akelis, the creator of the popular program MetaStock, is "a mathematical calculation which is applied to the price and - or volume of the securities. The result is value which is used for expectation of the future change of the prices ".

Babylonian does not decline to speculative operations.
He honours verdicts of a case, consigns them his life, hope and panic fear.
However he does not consider an investigation neither the confusing
laws of a case nor the movement of rotating spheres which open it to him.

Borches

There are thousand indicators which to an essence are, in fact, the same as minimal variations. They are often different only by theirs names. New "magic" indicators are created for two reasons: 1) poor knowledge of the underlying subject which can lead to the second invention; 2) the intentional profanation. The majority of indicator users accept them like the absolute and do not think of their physical meanings and properties. Moreover, popular books give the indicators such properties which they don’t have. Looking inside the indicators the curious can discover that it is nothing but elementary digital filters. Its theory and methods exists more than hundred years and they are used in engineering everywhere. For example, a simple moving average is a low frequencies filter with the finite impulse characteristic, an exponential moving average is a low frequencies filter with the infinite impulse characteristic, MACD is a band pass filter. Stochastic and CCI are the same as price normalized by different ways etc. the filtration can be prodused either in the state space like moving average or in frequency domain where one operates by Fourier transformed initial data etc. All filters have attributes such as smoothing degree of an input signal and delay degree of the smoothed signal in relation to an input signal. Classical indicators were created before computer age when the main requirement to the indicator was easy computing it “by hands", and smoothing and delay quality were estimated later. The classical indicators under these characteristics are varied from bad up to worse. For example, 200-day's moving average that popular among technical analytics delays neither much nor a little for a half of a window of averaging, or for 100 days, at very poor quality of smoothing.

From the point of view of the filtration theory oscillators are band pass filters or differentiating filters. Their physical analogue is a velocity of prices. Take a look to the popular technical analysis tool "divergence" meaning that the price and an oscillator have different directions. It is the analog of necessary extremum condition of a smooth function. It is good to emphasize that sufficient extremum condition does not follow from anywhere, i.e. extremum of a smooth function should be followed by divergence, but it does not follow from divergence that extremum is reached there. Use of this approach of the technical analysis, as well as many others, is based on a logic mistake of substitution of a sufficient condition by necessary one. The turn of the prices follows by divergence is similar to the fact that eating of cucumbers before death follows that the cucumbers are the reason of death.

The computerization and digital signal processing development let improve classical indicators essentially due to application of modern methods of information processing to prices. Indicators began to smooth better and to delay less. However Holy Grail has failed. First, the prices are non stationary, i.e. the characteristics of filters are varied during the time. Second, as different from technical problems, the kind of a signal and noise distributions for the price are unknown, i.e. nobody know what to filter actually. Third, being filtered by means of Fourier and similar methods prices change the previous values to the addition of the new data: we receive ideal trends under a history data but we can only trade them from right hand to left hand.

Fourier transformation is based on representation of initial series by the infinite sum of sinusoids with a various phase, amplitude and frequency. Recently wavelet transformations was widely adopted in various areas of data processing in which initial series are represented as the sum of some locally defined functions named wavelets. They are constructed by shifting and vertical and horizontal scaling of certain the prototype function. Wavelet transformation, in essence, is fractal that allows the effective using it in the technical analysis. First, it allows to carry out the multiscale analysis of prices, objectively identify trends on various scales by duration and amplitude, separate traders to various groups: scalpers, day traders, swing traders, position traders and long-term investors. The multiscale analysis can be interpreted as the analysis on various time frames. Second, it allows determine noise as the insufficient for reception of the profit amplitude and frequency movement of the prices that effectively allows filter the price series simply subtracting the lowest scale wavelets from it. Third, the additional filtration of white noise without delay is possible. Fourth, long-term trends are defined objectively. Fifth, wavelets do not contain optimized parameters in construct to standard indicators. Sixth, the used wavelets type is adapted to deal with the time ordered data and does not distorted on the last price values. Seventh, the used wavelet transformation is very effective computationally that allows use it in real time for the large massives of tick data. Eighth, it is effective to use wavelets as input data for neural networks and other methods of forecasting and recognition.

We use Redundant Haar wavelet transformation that represents an initial price series by the sum of the band pass filters named wavelets, and the residual low-frequency filter:

Price = + Residual,

Where N – - number of examined scales. It is necessary to say that the number of the used data values (i.e. the lookback period),on which wavelets compute is equal , therefore the greatest possible scale . 512 previous price values are more than enough for any practical problems. Waveleti i are similar to oscillators with consistently growing lookback periods while Residual term is similar to moving average. It is possible to read about Redundant Haar wavelets at http://www.multiresolution.comin more details.

The white noise filtration is made as follows. A signal or noise is defined on every scale. If noise is identified then the appropriate wavelet has zero value. If the signal is identified then the appropriate wavelet remains without change. Then we make inverse wavelet transformation and we receive the filtered signal.

Trend is determined as a significant movement on the considered scale, i.e. the signal / noise ratio for trend identification should be more than the given threshold of sensitivity. As noise is Gaussian by supposition, it is possible to apply statistical " Sigma rule " by setting a threshold in a range of 2 to 3.

The Application is realized as the dynamic library dll. The interaction with the library is carried out by means of two functions:

    Function RUNWVL

    var d = newDLL("tsewvl.dll");

    d.addFunction("runwvl", DLL.FLOAT, DLL.STDCALL,"RUNWVL", DLL.FLOATARRAY,DLL.INT,DLL.FLOAT);

    Returns value DeNoise

     

    DLL.FLOATARRAY  - Defines the block (should be formed using eSignal)

    DLL.INT  - Number of scales (inside dll number of bars are calculated using formula Lookback = Power(2, Scales); )

    DLL.FLOAT  - TraceHoldConstat (for example 3)

     

    Function GETALLVALUES

    var d = new DLL("tsewvl.dll");

    d.addFunction("getallvalues", DLL.FLOAT, DLL.STDCALL,"GETALLVALUES", DLL.INT,DLL.INT);

     

    Depending on parameters (I) returns value of Redundant Haar, Noise Sigma or filtered coefficients.

    I. Coefficients number

    1.       Redundant Haar

    2.       Noise Sigma

    3.       Filtered coefficients (often is similar to Redundant Haar(I) or has value 0 )

    II. Value number of coefficient in a row, 1, 2, etc. depending on number of scales, if 8 scales then rows of values will be:

    1.       (Redundant Haar) 8 scales + residue = 9.

    2.       (Noise Sigma) 8 values

    (Filtered coefficients) like with Redundant Haar 8 scales + residue = 9.

    To work with library dll it is necessary

    1. To define Dll:

    2. eSignal Formula Script:

       /* Defining DLL */
       var d = new DLL("tsewvl.dll");
       
    3. To define functions dll,
    4. eSignal Formula Script:

       /* Functions Declaration */
       d.addFunction("runwvl", DLL.FLOAT, DLL.STDCALL,"RUNWVL", DLL.FLOATARRAY,DLL.INT,DLL.FLOAT); 
       d.addFunction("getallvalues", DLL.FLOAT, DLL.STDCALL,"GETALLVALUES", DLL.INT,DLL.INT); 
       
    5. To define the parametrs
    6. eSignal Formula Script:

       function preMain() {
           setPriceStudy(true);
           setStudyTitle("Wavelet Smoothing");
           setCursorLabelName("Smoothing", 0);
           setDefaultBarStyle(PS_SOLID, 0);
           
           /* defining colors for different charts */
           setDefaultBarFgColor(Color.red, 0);
           setDefaultBarFgColor(Color.blue, 1);
           setDefaultBarFgColor(Color.cyan, 2);
           setDefaultBarFgColor(Color.white, 3);
           setDefaultBarFgColor(Color.green, 4);
           setDefaultBarFgColor(Color.lightyellow, 5);
           setDefaultBarFgColor(Color.purple, 6);
           setDefaultBarFgColor(Color.olive, 7);
           
           setDefaultBarThickness(1, 0);
           setPlotType(PLOTTYPE_LINE, 0);
           ArrayPrice = new Array(256);
           
              /* threshold value signal / noise */
           var fp1 = new FunctionParameter("NSigma", FunctionParameter.NUMBER);
           fp1.setLowerLimit(1);
           fp1.setUpperLimit(4);        
           fp1.setDefault(2)
       }
       
    7. To create array and call dll functions
    8. eSignal Formula Script:

       function main(NSigma) {
          if (NSigma==null) NSigma=2;
          lookback=256;
          aSource=getValue("Close",0,-lookback);
          nBarIndex = getNumBars()+getCurrentBarIndex();
          if (nBarIndex >lookback) {
            for (x=0; x<lookback; x++) {
              ArrayPrice[x] = aSource[x];   
            }
            /* call dll function */
            v = d.call("runwvl",ArrayPrice,8,NSigma);
            
            
            v1 = v - d.call("getallvalues",3,1);
            v2 = v1 - d.call("getallvalues",3,2);
            v3 = v2 - d.call("getallvalues",3,3);
            v4 = v3 - d.call("getallvalues",3,4);
            v5 = v4 - d.call("getallvalues",3,5);
            v6 = v5 - d.call("getallvalues",3,6);
            v7 = v6 - d.call("getallvalues",3,7);
            v8 = v7 - d.call("getallvalues",3,8);
       
            
          } else {
          v=0
          }
       
    9. To receive output values:
    10. eSignal Formula Script:

       /* return values for charting */
          return new Array (v1,v2,v3,v4,v5,v6,v7,v8);
       }
       

    Example 1. The indicator displaying a filtered price series and a residual term of wavelet transformation:

    Denoised & Residual

    In the Figure above one can see that the wavelet filtration deletes outliers on non-trending periods but leaves the prices on trend periods the same. Also the residual term of wavelet transformation can be used similarly to long-term moving average.

    eSignal Formula Script:

     /******************************************************** 
     Name: TSE.Wavelet.Denoised.Residual 
     Analysis Type: Indicator 
     Description: Non-decimated Haar Wavelet Denoised & Residual Indicator  
     Used: tsewvl.dll 
     Provided By: Trade Smart Research (c) Copyright 2001 - 2004 
              www.tsresearch.com 
     *******************************************************/

     
     var c,v1,v2,v3,lookback;
     
     
     /* Defining DLL */
     var d = new DLL("tsewvl.dll"); 
     
     /* Functions Declaration */
     d.addFunction("runwvl", DLL.FLOAT, DLL.STDCALL,"RUNWVL", DLL.FLOATARRAY,DLL.INT,DLL.FLOAT); 
     d.addFunction("getallvalues", DLL.FLOAT, DLL.STDCALL,"GETALLVALUES", DLL.INT,DLL.INT); 
     
     /* Preparing parameters and array*/
     function preMain() {
         setPriceStudy(true);
         setStudyTitle("Wavelet Denoised & Residual");
         setCursorLabelName("Denoised", 0);
         setDefaultBarStyle(PS_SOLID, 0);
         setDefaultBarFgColor(Color.red, 0);
         setDefaultBarFgColor(Color.blue, 1);
         
         
         setDefaultBarThickness(1, 0);
         setPlotType(PLOTTYPE_LINE, 0);
         ArrayPrice = new Array(512);
         
            
         var fp1 = new FunctionParameter("Scales", FunctionParameter.NUMBER);
         fp1.setLowerLimit(1);
         fp1.setUpperLimit(8);        
         fp1.setDefault(6);
         
         var fp2 = new FunctionParameter("NSigma", FunctionParameter.NUMBER);
         fp2.setLowerLimit(1);
         fp2.setUpperLimit(4);        
         fp2.setDefault(2)
         
     }
     
     function main(Scales,NSigma) {
        if (NSigma==null) NSigma=2;
        if (Scales==null) Scales=6;
        
        /* calculation of quantity of elements of a Array */
        lookback=Math.pow(2,Scales);
        
        /* determinig source */
        aSource=getValue("Close",0,-lookback);
        
        /* filling array */
        nBarIndex = getNumBars()+getCurrentBarIndex();
        if (nBarIndex >lookback) {
          for (x=0; x<lookback; x++) {
            ArrayPrice[x] = aSource[x];   
          }
          /* the smoothed series */
          v1 = d.call("runwvl",ArrayPrice,Scales,NSigma);
          v2 = Scales + 1;
          v3 = d.call("getallvalues",3,v2);
          
          
        } else {
        v=0
        }
        return new Array (v1,v3);
     }
     

    Example 2. Example 2 shows sumarized noise on all Wavelet coeficients. It can be assumed that price = signal + noise. Wavelet decomposition from price = decomposition of signal + decomposition of noise. Summarized noise on all wavelet coeficients is showen on the chart. As follows signal is price with subtracted noise. This example shows advantage of Wavelet transform from other methods as Wavelet transform eliminate different components of signal, noise and etc.

    Noise

    eSignal Formula Script:

     /******************************************************************* 
     Name: TSE.Wavelet.Noise 
     Analysis Type: Indicator 
     Description: Example Indicator for Wavelet Transform DLL 
     Used: tsewvl.dll 
     Provided By: Trade Smart Research (c) Copyright 2001 - 2004 
              www.tsresearch.com 
     *******************************************************************/

     
     
     var v,lookback;
     
     /* Defining DLL */
     var d = new DLL("tsewvl.dll"); 
     
     /* Function Declaration */
     d.addFunction("runwvl", DLL.FLOAT, DLL.STDCALL,"RUNWVL", DLL.FLOATARRAY,DLL.INT,DLL.FLOAT); 
     
     
     /* Preparing parameters and array*/
     function preMain() {
         setPriceStudy(false);
         setStudyTitle("Wavelet Noise");
         setCursorLabelName("Noise", 0);
         setDefaultBarStyle(PS_SOLID, 0);
         setDefaultBarFgColor(Color.red, 0);
         setDefaultBarThickness(1, 0);
         setPlotType(PLOTTYPE_LINE, 0);
         ArrayPrice = new Array(512);
             
         var fp1 = new FunctionParameter("Scales", FunctionParameter.NUMBER);
         fp1.setLowerLimit(1);
         fp1.setUpperLimit(8);        
         fp1.setDefault(4);
         
         var fp2 = new FunctionParameter("Source", FunctionParameter.STRING);
         fp2.setName("Source");
         fp2.addOption("Close");
         fp2.addOption("High");
         fp2.addOption("Low");
         fp2.addOption("Open");
         fp2.setDefault("Close");  
     }
     
     function main(Scales,Source) {
     
        if (Scales==null) Scales=4;
        if (Source==null) Source="Close";
        
        /* determinig length of array */
        lookback=Math.pow(2,Scales);
        
        /* determinig source */
        aSource=getValue(Source,0,-lookback);
        nBarIndex = getNumBars()+getCurrentBarIndex();
        
        /* filling array */
        if (nBarIndex >lookback) {
          for (x=0; x<lookback; x++) {
            ArrayPrice[x] = aSource[x];   
          }
          /* calling functoin in dll */
          v = d.call("runwvl",ArrayPrice,Scales,3);
        } else {
        v=0
        }
        return v;
     }
     

    Example 3. Indicator Nowcast Trend assumes value 1 and -1 if trend is identified. On the base of this indicator strategy "Nowcast signal" is created.

    Nowcast Trend

    eSignal Formula Script:

     /********************************************************* 
     Name: TSE.Wavelet.Nowcast.Trend 
     Analysis Type: Indicator
     Description: Non-decimated Haar Wavelet Trend Nowcast Indicator 
     Used: tsewvl.dll 
     Provided By: Trade Smart Research (c) Copyright 2001 - 2004 
              www.tsresearch.com 
     *********************************************************/

     
     var c,v,lookback,Trend, Wavelet, Sigma;
     
     /* Defining DLL */
     var d = new DLL("tsewvl.dll"); 
     
     /* Functions Declaration */
     d.addFunction("runwvl", DLL.FLOAT, DLL.STDCALL,"RUNWVL", DLL.FLOATARRAY,DLL.INT,DLL.FLOAT); 
     d.addFunction("getallvalues", DLL.FLOAT, DLL.STDCALL,"GETALLVALUES", DLL.INT,DLL.INT); 
     
     /* Preparing parameters and array*/
     function preMain() {
         setPriceStudy(false);
         setStudyTitle("Wavelet Nowcast Trend");
         setCursorLabelName("Nowcast", 0);
         setDefaultBarStyle(PS_SOLID, 0);
         setDefaultBarFgColor(Color.red, 0);
         
        
         
         setDefaultBarThickness(1, 0);
         setPlotType(PLOTTYPE_LINE, 0);
         ArrayPrice = new Array(256);
         
        /* wavelet scale */ 
        var fp1 = new FunctionParameter("Scales", FunctionParameter.NUMBER);
         fp1.setLowerLimit(1);
         fp1.setUpperLimit(8);        
         fp1.setDefault(5);
         
         /* threshold value signal / noise */
         var fp2 = new FunctionParameter("NSigma", FunctionParameter.NUMBER);
         fp2.setLowerLimit(1);
         fp2.setUpperLimit(4);        
         fp2.setDefault(3);
        
         
     }
     
     function main(Scales,NSigma) {
        if (Scales==null) Scales=5;
        if (NSigma==null) NSigma=3;
        lookback=256;
        aSource=getValue("Close",0,-lookback);
        nBarIndex = getNumBars()+getCurrentBarIndex();
        
        /* filling array */
        if (nBarIndex >lookback) {
          for (x=0; x<lookback; x++) {
            ArrayPrice[x] = aSource[x];   
          }
          
          /* calling functoin in dll */
          v = d.call("runwvl",ArrayPrice,8,NSigma);
          
          Wavelet =d.call("getallvalues",1,Scales);
          Sigma =d.call("getallvalues",2,Scales);
          
          /* Determinig trend */
          if (Wavelet > NSigma * Sigma) {
            Trend = 1 
          } else { 
            if (Wavelet < - NSigma * Sigma) {
              Trend = -1  
            } else {
              Trend=0
            }
          }
          
        } else {
        v=0
        }
        return Trend;
     }
     

    Example 4. The indicator shows the family of low-frequency filters, derived by consecutive subtraction of the filtered wavelet coefficients from the filtered price (see figure):

    Smoothing

    eSignal Formula Script:

     /******************************************************** 
     Name: TSE.Wavelet.Smooth 
     Analysis Type: Indicator 
     Description: Non-decimated Haar Wavelet Smoothing Indicator Family  
     Used: tsewvl.dll 
     Provided By: Trade Smart Research (c) Copyright 2001 - 2004 
              www.tsresearch.com 
     ********************************************************/

     
     var c,v,v1,v2,v3,v4,v5,v6,v7,v8,lookback;
     
     /* Defining DLL */
     var d = new DLL("tsewvl.dll"); 
     
     /* Functions Declaration */
     d.addFunction("runwvl", DLL.FLOAT, DLL.STDCALL,"RUNWVL", DLL.FLOATARRAY,DLL.INT,DLL.FLOAT); 
     d.addFunction("getallvalues", DLL.FLOAT, DLL.STDCALL,"GETALLVALUES", DLL.INT,DLL.INT); 
     
     
     function preMain() {
         setPriceStudy(true);
         setStudyTitle("Wavelet Smoothing");
         setCursorLabelName("Smoothing", 0);
         setDefaultBarStyle(PS_SOLID, 0);
         
         /* defining colors for different charts */
         setDefaultBarFgColor(Color.red, 0);
         setDefaultBarFgColor(Color.blue, 1);
         setDefaultBarFgColor(Color.cyan, 2);
         setDefaultBarFgColor(Color.white, 3);
         setDefaultBarFgColor(Color.green, 4);
         setDefaultBarFgColor(Color.lightyellow, 5);
         setDefaultBarFgColor(Color.purple, 6);
         setDefaultBarFgColor(Color.olive, 7);
         
         setDefaultBarThickness(1, 0);
         setPlotType(PLOTTYPE_LINE, 0);
         ArrayPrice = new Array(256);
         
            /* threshold value signal / noise */
         var fp1 = new FunctionParameter("NSigma", FunctionParameter.NUMBER);
         fp1.setLowerLimit(1);
         fp1.setUpperLimit(4);        
         fp1.setDefault(2)
         
     }
     
     function main(NSigma) {
        if (NSigma==null) NSigma=2;
        lookback=256;
        aSource=getValue("Close",0,-lookback);
        nBarIndex = getNumBars()+getCurrentBarIndex();
        if (nBarIndex >lookback) {
          for (x=0; x<lookback; x++) {
            ArrayPrice[x