Monthly Archive for September, 2007

Thursday, September 20, 2007 $7.60 @ 2 Contracts

Gross:  $          20.00
Fees:  $          (4.80)
Net:  $          15.20
Contracts: 2
Ratio:  $             7.60

So today I completed my expiration roll over (better late than never!) and even traded a round trip. I have been ridiculously busy at work lately, which has kept me from getting to trading, but I will try to make time next week again.

GLOBEX@ER2Z7 821.80 (1h5m)  B821.80 A821.90

Rolling over isn’t as bad as I though – in quote tracker you just add the symbols, and then drag and drop the new symbols onto the current chart, and wallah!

ButtonTrader - [WSP default-1024] ButtonGrid_CONT0007    Cash  FX-EUR.USD on IDEALPRO in USD (2)

Button trader was a little more work as you had to add the symbols and recreate the containers. No big deal really. I just had to request a new password from these guys, their license scheme is a little annoying, but very reliable software!

Off to work

Hello everyone – so I just got Windows Live Writer Beta 3 installed, and this is a test post. The ADX post, turned out to be the post from hell. I used word 2007’s great equation editor, which is darn near impossible to get to post to a blog. I had to save as a filtered web page, open the page in Web Expression, and copy the html to Word 2007 to do the post (Windows Live Writer crashed when I did this).

In any case, no additional indicators today, I have to run to work early. Hopefully this post works from Beta 3!

Average Directional Movement Index ADX Formula in C#

So in my continuing series of C# implementations of common indicators, I spent all of yesterday working out the ADX. The ADX was originally developed by J. Welles Wilder and published in his book New Concepts in Technical Trading Systems, June 1978.

Various sites report implementations, but always define it in terms of indicators which have varying definitions. Namely FxStreet defines the general concept here, but only in terms of DI+/-, TR and DM+/-, each of which has varying definitions. ForexReal defines ADX here, but uses a completely different concept of TR. Stockwiz has a good overview of all of the variables used (at least they define all of their variables) here. I will be defining the ADX all the way down to price action (what you need when you are coding this…) as best I can to the original definition by J Welles Wilder.

Lets start by defining the Directional Move indicators

Directional Move Indicator

         = the Positive Direction Movement Indicator

          = the Negative Direction Movement Indicator

We use two helper variables to track the delta extreme price changes from yesterday

If today’s range is entirely within yesterday’s range, or the range is the same, then there has been no directional movement.

If the range moved up, then there has been a positive directional move.

If the range moved down, then there has been a negative directional move.

Average Directional Move Indicator

          = the Average Positive Direction Movement Indicator for N periods

          = the Average Negative Direction Movement Indicator for N periods

The Welles Wilder Average is used here to stay true to form, but this average introduces a lot of latency, so I will also implement an exponential moving average.

Alternatively, the formula for the ADM with an exponential moving average is shown below.

True Range

          is the true range for a given period. It is a measure of volatility and takes into account any overnight gap in the period’s price.

Average True Range

          is the average true range for N periods.

The Welles Wilder Average is used here again to stay true to form, but for my C# implementation I will be using the exponential moving average.

Alternatively the ATR can be calculated with the exponential moving average as shown below.

Directional Index

          is the average positive directional movement indicator normalized by the average true range.

          is the average negative directional movement indicator normalized by the average true range.

The directional index calculation is very straight forward and shown below.

Directional Movement Index

          – the directional movement index is the difference of the directional indices over the sum directional indices.

Average Directional Movement Index

          is the average directional movement calculated over N periods.

Staying true to form again, the Welles Wilder Average is used below.

Again, you can alternatively use the exponential moving average as shown below.

C# implementation

So after the laborious research to determine exactly what the ADX is and should be (exponential vs Welles Wilder Average), here is the C# implementation of this indicator.

    //The Average Directional Indicator

    if(barHistory[timePeriod].Count > 1)

    {

        //Directional Movement Indicator

        double deltaHigh = cBar.High – barHistory[timePeriod][barHistory[timePeriod].Count – 2].High;

        double deltaLow = barHistory[timePeriod][barHistory[timePeriod].Count – 2].Low – cBar.Low;

        if((deltaHigh < 0 && deltaLow < 0) || (deltaHigh == deltaLow))

        {

            sig.DmPlus = 0;

            sig.DmMinus = 0;

        }

        else
if(deltaHigh > deltaLow)

        {

            sig.DmPlus = deltaHigh;

            sig.DmMinus = 0;

        }

        else
if (deltaHigh < deltaLow)

        {

            sig.DmPlus = 0;

            sig.DmMinus = deltaLow;

        }

 
 

        //Average Directional Movement Indicator

        if(barHistory[timePeriod].Count <= 2)

        {

            sig.AdmPlus = sig.DmPlus;

            sig.AdmMinus = sig.DmMinus;

        }

        else

        {

            double a = (double) 2/(double) (calc.DMIPeriod + 1);

            sig.AdmPlus = sig.DmPlus * a +

                symbolHistory[timePeriod][symbolHistory[timePeriod].Count-2].AdmPlus * (1-a);

            sig.AdmMinus = sig.DmMinus * a +

                symbolHistory[timePeriod][symbolHistory[timePeriod].Count – 2].AdmMinus * (1 – a);

        }

 
 

        //True Range Indicator

        sig.TrueRange = Math.Max(Math.Abs(cBar.High – cBar.Low),

                                 Math.Max(

                                     Math.Abs(cBar.High – barHistory[timePeriod][barHistory[timePeriod].Count – 2].Close),

                                     Math.Abs(barHistory[timePeriod][barHistory[timePeriod].Count – 2].Close – cBar.Low)));

 
 

        //Average True Range Indicator

        if(barHistory[timePeriod].Count <= 2)

        {

            sig.AverageTrueRange = sig.TrueRange;

        }

        else

        {

            double a = (double)2 / (double)(calc.ADXPeriod + 1);

            sig.AverageTrueRange = sig.TrueRange * a +

                symbolHistory[timePeriod][symbolHistory[timePeriod].Count – 2].AverageTrueRange * (1 – a);

        }

 
 

        //Directional index Indicator

        if (sig.TrueRange != 0)

        {

            sig.DiPlus = 100 * sig.AdmPlus/sig.TrueRange;

            sig.DiMinus = 100 * sig.AdmMinus/sig.TrueRange;

        }

        else

        {

            sig.DiPlus = symbolHistory[timePeriod][symbolHistory[timePeriod].Count – 2].DiPlus;

            sig.DiMinus = symbolHistory[timePeriod][symbolHistory[timePeriod].Count – 2].DiMinus;

        }

 
 

        //Directional Movement Index Indicator

        if ((sig.DiPlus + sig.DiMinus) != 0)

            sig.Dx = Math.Abs((sig.DiPlus – sig.DiMinus)) / (sig.DiPlus + sig.DiMinus) * 100;

        else

            sig.Dx = symbolHistory[timePeriod][symbolHistory[timePeriod].Count – 2].Dx;

 
 

        //Average Directional Movement Indicator

        if (barHistory[timePeriod].Count <= 2)

        {

            sig.Adx = sig.Dx;

        }

        else

        {

            double a = (double)2 / (double)(calc.DMIPeriod + 1);

            sig.Adx = sig.Dx * a +

                symbolHistory[timePeriod][symbolHistory[timePeriod].Count – 2].Adx * (1 – a);

        }

    }

Sample Data

This is a sample data set consisting of the NYSE A/D 1-min bar data (“Close”) from August 28, 2007 and the 14 period ADX in red.

9.3.0.5 C# API Bug Fix Release

I just finished uploading a bug fix release to the 9.30 API code base – technically the bugs are in the 9.10 release as well, but I haven’t heard any problems lately, and since IB has moved to the 9.20 release as the stable version, I am not going to update the 9.10 code base (let me hear the outcry if you need otherwise).

You can download the new release here. Or go to the utilities page here for all releases.

The release notes for changes are below – enjoy!

9.3.0.5 Bug Fix Release
* Fixed Historical Data Requests (had improperly formatted parameter and timestamps)
* Fixed Disconnect call to properly kill the reader thread
* Added support for additional contracts (Forex, Futures, Indices)
* Began Order Classes, incomplete for now, but started a Limit Order class.
* Fixed Current Time call, it now returns a date time instead of a string.

9.3.0.4 Bug Fix Release
* Added Market On Open enumeration to Time in Force

AMA – Kaufman’s Adaptive Moving Average Formula in C#

So I have not been posting as much lately, as I have been working on an Auto Trading System, and after spending far too much time researching signal formulas, I thought I would being to post the implementations of various signals I am using in my ATS.

The Kaufman Adaptive Moving Average is a great low latency moving average filter. It technically has an infinite tail, but cleverly weights the amount of signal for each new bar based on the historical trendiness. If the past data has been choppy, then each new bar is weighed very low in the average, however if the past data has offered a strong direction (regardless of magnitude) then the average weighs new signal very heavily.

There aren’t too many sites discussing the actual formula – I based my implementation on the MetaStock code found here.

I started writing this post in windows Live Writer, and found that it does not keep Visual Studio’s source formatting, so I will try to post this from Word 2007. Word is much better at formatting, but terrible with images, while Live is great with images and managing the site, but terrible with formatting.

//Direction is just present over previous price
double direction = cBar.Close - BarHistory[timePeriod][BarHistory[timePeriod].Count - cnt].Close;
double vol = 0;
//Vol is the sum of all differences in the past period
for (int ix = 1; ix < cnt; ix++)
{
	vol += Math.Abs(BarHistory[timePeriod][BarHistory[timePeriod].Count - ix - 0].Close - BarHistory[timePeriod][BarHistory[timePeriod].Count - ix - 1].Close);
}

//if not enough data, or there has been no price change, then AMA is price.
if ((direction == 0 && vol == 0) || cnt == 1)
{
	sig.Ama = cBar.Close;
}
else
{
	//Elastic ratio
	double ER = Math.Abs(direction/vol);
	double FastSC = 2/(calc.AMAFastEMA + 1);
	double SlowSC = 2/(calc.AMASlowEMA + 1);
	double SSC = ER*(FastSC - SlowSC) + SlowSC;

	//This is the magic scaling/smoothing constant.
	double conC = SSC*SSC;
	if (cnt == 2)
	{
		sig.Ama = BarHistory[timePeriod][0].Close + conC*(cBar.Close - BarHistory[timePeriod][1].Close);
	}
		else if (cnt > 2)
	{
		sig.Ama = BarHistory[timePeriod][barHistory[timePeriod].Count - 2].Close +
		conC*(cBar.Close - BarHistory[timePeriod][barHistory[timePeriod].Count - 2].Close);
	}
}

This is easily my favorite indicator, and with a lot of tweaking can actually be made to have a lot lower latency. The key thing about noise removal, is that signals are noisiest when their trending derivative is lowest. This fact allows a lot of clever hacks to lower the latency of filters like the ATX. That being said, it is often important to use an indicator unscathed, as so much of the market uses it, its performance is a self fulfilling prophesy.