May 2006

Trading Tip:
Market Geometry:  Lightning Bolt
by Howard Arrington

As the tug-of-war ensues between buyers and sellers, chart patterns develop over a period of time.  There are characteristics in these patterns that repeat with sufficient frequency that they need to be given serious study in your chart analysis.  Because trading involves probabilities, not certainties, understanding and using market geometry can provide a statistical edge in trading profitably.  

All charts are drawn on a plane of rectangular (Cartesian) coordinates.   There are two perpendicular  lines that create a horizontal time based x-axis and a vertical priced based y-axis.  The measure on the horizontal x-axis may be a fixed period of time, or a variable period of time because the bar duration is based on fixed units of volume or tick count.  For additional information, read this excellent Trading Tips article on the Geometry of Charts.

The patterns that develop contain transitions from one price to another.  Major moves are called Trends, and corrective reactions to these trends are called Retracements.  Trends will be referenced with the letter 'T' and Retracements with the letter 'R'.   So, the simplest pattern would be the pairing of one Trend with one Retracement, ie. pattern T-R   The basic pattern can be either of the follow shapes.

One characteristic of primary interest is the percentage of the trend's price change that is retraced by R.  Two tools commonly used to measure and label the retracement percentage are the Fibonacci Levels and the Pesavento Patterns tools, as illustrated here.  For more information, read this Trading Tips article on the Geometry of Draw Tools.

The most probable and useful retracement ratios are 0.618, followed by 0.786, and then 0.5.  For greater insight on how Larry Pesavento uses these retracement ratios (percentages), read this Trading Tips article about Larry Pesavento.

The next pattern to consider is the addition of a Trend to the basic pattern, ie. pattern T-R-T.  This pattern will be the primary focus of this article because repeatable characteristics make it possible to predict WHEN and WHERE this second Trend move will end.  Just remember that trading is dealing with probabilities, not certainties, but an advantage is gained by trading with probabilities that are in your favor.

Parallelism - Parallelism is the single most important and repeatable characteristic.  It is seen over and over again.  It can be found multiple times on any chart, and every chart.   The principle is illustrated in this diagram where the 2nd T line is parallel to the 1st T line.

Length - The length of the 2nd T line can be compared to the length of the 1st T line.  The relationship with the highest probability is that the 2nd T line will be equal in length to the 1st T line.  Some traders prefer to view the 2nd T as a percentage extension of prior R line, and the most common extension is the 1.618 multiple.  Regardless of how you view the relationship, it is mathematically arriving at the same characteristic of a repeatable length.   Consider the following.

If   R = 0.618 * 1st T,  and  2nd T = 1.618 * R,  then  2nd T = 1.618 * (0.618 * 1st T) = 1st T

A 2nd retracement and extension pairing is the 0.786 retracement and the 1.272 extension.  This pairing also results in equal length T lines.  Consider this relationship:

If   R = 0.786 * 1st T,  and  2nd T = 1.272 * R,  then  2nd T = 1.272 * (0.786 * 1st T) = 1st T

Same Game, Different Name

Each trading mentor seems to have a custom name for this basic T-R-T pattern.   Some names in use are 'Lightning Bolt', 'AB=CD', 'Fibonacci Extension', 'Pesavento Patterns', 'Price Time Target', 'Elliott Wave a-b-c or 1-2-3'.   Two tools in Ensign Windows are handy for forecasting the WHEN and WHERE for the completion of the 2nd T line once the 1st T and R moves are completed.  The first tool shown is the Formations draw tool with its properties window.

The tool is manually applied to the chart by clicking the left mouse button down at point A, hold the button down and drag to point B, release the mouse button, move to point C and click the left mouse button.  The tool will draw the lines shown, which gives a forecast of point D by making line CD both parallel and equal in length to line AB.   The tool is customizable for colors, line styles, and markers to label the left and right sides of the lines.  The length relationship of CD in comparison to AB is a customizable parameter.  In the example, the relationship is set to 100 which means the length of line CD is 100% of the length of line AB.

The Formations tool can be used to show other variations, such as adding lines to forecast point E and point F.  Line DE is parallel to line BC and has a length relationship to line BC entered as the Level parameter on the D-E property line.   Line EF is parallel to line AB and has a length relationship to line AB entered as the Level parameter on the E-F property line.

The Show boxes can be checked to draw lines connecting points A to C, B to D, C to E, and D to F as illustrated in the following picture.

Another draw tool that creates the same forecast to point D is the straight line draw tool with its PTT (Price Time Target) Channel property checked.   The tool is applied to the chart by clicking down on point A, hold the button down and drag to point C, and release the left mouse button.  The tool will automatically find point B which is a swing point between A and C, and draw the BD line both parallel and equal in length to line AC from point B.

Although the PTT Channel construction technique is slightly different, point D is the same forecast point as illustrated in the prior example constructed with the Formations tool.   Points ABCD form a parallelogram with the following characteristics.   AB is parallel to CD and AB=CD.   AC is parallel to BD and AC=BD.

Example Charts

The ability to forecast WHEN and WHERE the 2nd Trend line will complete gives you a statistical advantage in your trading.   It enables you to have increased confidence that a trend has matured by completing its time and price objectives.   Don't overlook this gem of a Trading Tip, because it is one of the best ones that can be shared with you.  It is used by successful traders.


Training Tip:
Training Videos

Ensign Software's web site has a collection of Training Videos on a variety of  topics, including Fibonacci Levels, Pesavento Patterns, Gartley / Butterfly Patterns, Formations Tool and Pivot Points.  These training videos provide additional information related to the material presented in this issue of the Trading Tips newsletter.   To watch these 3 to 20 minute videos, go to the Ensign web site, click on the Videos button, click on any of the links in the section for the Training Videos.  The videos will play in your web browser viewer.   Please check them out.   The web site URL is:

http://www.ensignsoftware.com/video/videos.htm


Trading Tip:
Bradley Model - 2006 Update

See these articles about the Bradley Model published in previous Trading Tips Newsletter issues:


ESPL Tip:
ESPL:  Calling C++ DLLs
by Mike Lamont

Even though this article is about an advanced topic, the examples will be very simple.  Here is what we will accomplish:

  1. Preference.
  2. Build a Main ESPL Script
  3. Build an ESPL Script Library
  4. Build a Delphi DLL
  5. Create a form in the Delphi DLL
  6. Build a C++ DLL
  7. Create a form in the C++ DLL
  8. Update info and display the Delphi DLL Form from the ESPL script
  9. Update info and display the C++ DLL Form from the ESPL Script
  10. Unasked Questions answered


1. Preference

When it comes to programming, much of what you do is personal preference. When I receive program code from someone, I spend the first part of my debugging formatting the text in the manner I like to see it.

This is how some folks like the code.

Begin ShowMessage(‘Mike is here’); end;

Here is how I like the code:

begin
  ShowMessage(‘Mike is here’);
end;

With this said, I have, over the years, formulated my preferences as laid out in this article.  It may not be the best or worst, but it works for me and the many changes I do on the many programs I write.


2. Build a Main ESPL Script

I have a general Main.spt program that usually has an explanation, update date and Includes.

Here is the Main.spt

/********************************************/
/* ESPL Article Example                     */
/* Requested by: Mike LaMont                */
/* Last Update: 05-09-06                    */
/* Files:                                   */
/* ESPL.DLL - In Delphi 2006                */
/* CPP.DLL - In Borland C++ Builder 2006    */
/* Main.spt - ESPL Main program             */
/* My-Lib.spt - Unencrypted ESPL Library    */
/********************************************/

{$Include My-Lib.spt}

That is it in the Main script. All the code is called in the My-Lib.spt.  The reason for this is I usually encrypt the My-Lib.spt (eg. My-Lib.lib) and put authorization items in it to allow or deny customer access.


3. Build an ESPL Script Library

Here is the My-Lib.spt:

// My-Lib.spt for ESPL Article
procedure MyDLL(iType: integer; vValue: variant);
var a: integer;
begin
  a := 0;
  vValue := DLL3(iType, vValue, a, a, a, a, a, a, '');
end;

begin
  Output(eClear);
  if ESPL = 0 then MyDLL(0, 0);
  if ESPL = 1 then MyDLL(1, 1.1);
  if ESPL = 2 then MyDLL(2, StrToInt(FormatDateTime('S', Now)));
  if ESPL = 3 then MyDLL(3, 0);
  if ESPL = 4 then MyDLL(4, StrToInt(FormatDateTime('S', Now)));
  if ESPL = 5
then MyDLL(5, 0);
end;


4. Build a Delphi DLL

Here is the Delphi DLL main body.

library ESPL; // Delphi ESPL for Article
uses
  Forms, Dialogs, Classes, Windows, SysUtils, Unit1 in 'Unit1.pas' {Form1};

const CPPDLL = 'CPP.DLL';

function MyCPPDLLInteger(iValue: integer): integer; stdcall; external CPPDLL;
function MyCPPDLLDouble(dValue: double): double; stdcall; external CPPDLL;
procedure MyCPPDLLShowForm; stdcall; external CPPDLL;
procedure MyCPPDLLUpdateValue(dValue: double); stdcall; external CPPDLL;

procedure MyShowForm(d: double);
begin
  Form1.UpdateValue(d);
end;

function DLL(var iType, vValue, c,d,e,f,g,h: variant; s: ShortString): ShortString; stdcall;
begin
  result := '';
  case Integer(iType) of
  0: result := FormatFloat('0', MyCPPDLLInteger(Integer(vValue)));|
  1: result := FormatFloat('0.0', MyCPPDLLDouble(Double(vValue)));
  2: Form1.UpdateValue(Double(vValue));
  3: Form1.Show;
  4: MyCPPDLLUpdateValue(Double(vValue));
  5: MyCPPDLLShowForm;
  end;
end;

procedure MyDLLProc(iReason: integer);
begin
end;

exports
  DLL;

begin
  Form1 := TForm1.Create(Application);
  DLLProc := @MyDLLProc;
end.

When the DLL is instantiated, Form1 is created.  You could also do this dynamically using the Case statements.  I do this quite often in programs using an Open Dialog box and let the user open a named page.  For instance, say you want a Custom Quote Page that does your own calculations.


5. Create a form in the Delphi DLL

Here is the code in the Delphi DLL Form page along with a picture of what it looks like in the development phase of the IDE.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    btnOk: TButton;
    procedure btnOkClick(Sender: TObject);
    private
    public
    procedure UpdateValue(dValue: double);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.UpdateValue(dValue: double);
begin
  Label1.Caption := FormatFloat('0.000000', dValue);
end;

procedure TForm1.btnOkClick(Sender: TObject);
begin
  Close;
end;

end.

The Caption is "DLL Form in Delphi".


6. Build a C++ DLL

Note in the Delphi DLL ESPL page, there are function protocols:

function MyCPPDLLInteger(iValue: integer): integer; stdcall; external CPPDLL;
function MyCPPDLLDouble(dValue: double): double; stdcall; external CPPDLL;
procedure MyCPPDLLShowForm; stdcall; external CPPDLL;
procedure MyCPPDLLUpdateValue(dValue: double); stdcall; external CPPDLL;

These functions are calling external functions in the CPP DLL.  Here is the code for the main part of the CPP.DLL C++ file.

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
#include "Unit2.h"

TForm2 *frmForm2 = NULL;

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  frmForm2 = new TForm2(Application);
  return 1;
}

extern "C" int __export __stdcall MyCPPDLLInteger(int iValue)
{
  int i = iValue + 1;
  return i;
}

extern "C" double __export __stdcall MyCPPDLLDouble(double dValue)
{
  double d = dValue + 1.00000;
  return d;
}

extern "C" void __export __stdcall MyCPPDLLShowForm(int iValue)
{
  frmForm2->Show();
}

extern "C" void __export __stdcall MyCPPDLLUpdateValue(double dValue)
{
  if (frmForm2 != NULL)
  frmForm2->UpdateValue(dValue);
}

There is no header file in the CPP Unit1.cpp file.


7. Create a form in the C++ DLL

Note that the Form2 variable is created upon the instantiation of the CPP.  Again, you could do this many ways; this was "quick-and-dirty" for my purposes.  Also, note, that I am using a "new" instantiation of the form rather than

Application->CreateForm(__classid(TfrmForm2), &frmForm2)

because we the latter creates problems using Application in that Manner. We technically have three applications:

Ensign and it’s ESPL
Delphi DLL
CPP DLL

The Application->CreateForm causes Access Violation upon trying to free the memory because it belongs to the CPP DLL, not the main program, Ensign.  The "new" method takes care of the problem.

Now, the Form in the CPP DLL and its picture from the IDE.

#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm2 *Form2;

__fastcall TForm2::TForm2(TComponent* Owner): TForm(Owner)
{
}

void __fastcall TForm2::Button1Click(TObject *Sender)
{
  Close();
}

void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
  Action = caHide;
}

void __fastcall TForm2::UpdateValue(double dValue)
{
  Label1->Caption = FormatFloat("0.000000", dValue);
}

The accompanying Header file.

#ifndef Unit2H
#define Unit2H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

class TForm2 : public TForm
{
__published: // IDE-managed Components
    TButton *Button1;
    TLabel *Label1;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
public: // User declarations
  void __fastcall TForm2::UpdateValue(double dValue);
  __fastcall TForm2(TComponent* Owner);
};

extern PACKAGE TForm2 *Form2;
#endif

The picture.

The Caption shows DLL Form in C++.


8. Update info and display the Delphi DLL Form from the ESPL script

In the ESPL Editor, there is a Run button, then buttons labeled 1 through 9.  I used these for my example.

If you click run, ESPL equals 0 (Zero) and calls the ESPL main body.  The ESPL Main body says,

if ESPL = 0 then MyDLL(0, 0);

The MyDLL function is called which calls the Delphi DLL.

We have in affect, left the ensign program via the ESPL script, stepped into a DLL (Dynamically Linked Library) and now we are calling our routines.  In the Delphi DLL, we typecast the Variant variable, which I named "iType" to be an integer and do a case statement on it.

If iType equals 0 then Call the CPP DLL function called MyCPPDLLInteger and pass it a type-casted-to-int value of vValue.  All this function does is returns the same value + 1.  The result of the DLL call is returned after being formatted into a string.

If iType equals 1 then Call the CPP DLL as above but use a double value, which is decimal based instead of integer based, and return.

If iType equals 2 then call the Delphi DLL Function in the Form1 unit to update the value passed in vValue.

If iType equals 3 then show the Delphi DLL Form which shows the updated value in the label.

Here is a picture.


9. Update info and display the C++ DLL Form from the ESPL Script

If iType equals 4 then call the CPP DLL function in the CPP Form unit to update the value passed by vValue.

If iType equals 5 then show the CPP DLL Form which shows the updated values in the label.

Here is a picture.


10. Unasked Questions answered

Q. Are these MDI Child windows like Ensign uses?

A. These are not MDI Child windows. These are just normal forms that you can drag anywhere you wish. You can dynamically create forms, delete them, update them, etc.  It would be nice to have MDI Child windows on occasion, but that requires a handle the TApplication of Ensign.  This has been available from time to time but TApplication is a class that is different between compilers and versions.  It is not easy to work with.  You can set the FormStyle to StayOnTop if you wish.

Q. Why not just use a CPP.DLL instead of the Delphi Wrapper?

A. Variant, like TApplication, is a class.  Classes differ from complier to compiler and version to version.  The Variant class in C++ is different than the Variant Class in Delphi.  In fact, the Variant class in Delphi 4.0 is different in Delphi 5.0, etc.  Variant is nice in that you can pass different parameters without having to overload it.  The wrapper is nice so you can do what you want with any type of variant variable passed to it.  Since the DLL Call in Ensign uses Variant, we must use the wrapper.

Q. Why would you use CPP.DLL in the first place?

A. Not everybody has a Delphi compiler.  To obtain one costs money.  Not everybody knows how to use Delphi.  My preference is C++.  I can write (or obtain) a DLL Wrapper written in Delphi and program all my work in C++ or other languages of my choice.

Q. Why would I want to use a ESPL or a DLL?

A. In the almost 16 years I have worked with Ensign, I have learned one thing.  No matter what features Ensign has, there is always something that someone wants that is not in it.  For instance, you could use it for as complex an application as a Neural Network or as simple as doing a calculation.  I mentioned earlier you could have your own quote pages or other types of pages that can update real-time using your own calculations.  You could look for patterns in charts, your own price alert system, etc. I’ve literally written hundreds of EPSL programs for customers and the possibilities seem endless.

Q. Could a company develop their own strategies and use this method to plug it into Ensign?

A. Absolutely.  Case-in-point. I  have completed a project for Richard Smitten with the Jesse Livermore Trading Methodology.  It uses Ensign’s charts but overlays the charts with Mr. Smitten’s interpretation of Livermore’s methodology.  It has its own toolbar that you can open a Money Management system, access unique chart layouts, setup parameters, etc.  It is also a good way to "hide" your code and authenticate users.

Q. I noticed your ESPL DLL Call is using DLL3, not the documented DLL.  The parameters and result is ShortString, not Variant.

A. The documented DLL uses ShortString and 8 var Variants with a result of Variant.  Since Variant is different in compilers and versions, this could be problematic if you need / want results in the Script side of your code.  So, ShortString was introduced as a resultant value and this necessitated moving the ShortString variable to the end of the parameter list.  You can use either DLL or DLL3 but my preference is the DLL3.


Copyright © 2008 by Ensign Software, Inc.