14,870,739 members
Articles / Programming Languages / C#
Article
Posted 17 Aug 2006

64.3K views
58 bookmarked

# Creating a Mechanical Trading System Part 2: Four Percent Trading System

Rate me:
17 Aug 2006CPOL6 min read
An article describing how to implement and test a mechanical trading system such as Ned Davis 4 percent model using a C# simulator.

## Introduction

The first article in this series introduced a project to code mechanical trading system robots for the .NET platform using the C# language. This article introduces how to code a trading system that will watch price action and make buying or selling decisions. It is the aim of this project to write a program that does not depend on any underlying platform to execute, but rather receives price data directly from a broker and places orders via an API.

The code provided here is part of a larger project to create a backtesting platform and an automated FOREX trading robot. Source code for this project is available here.

## Background

This article implements the 4 percent model, developed by Ned Davis and popularized by Martin Zweig in his book Winning on Wall Street. This is a very simple trend following model that will put you on the right side of a sustained trend. This is not to say that this system does not have weaknesses. If too small of a percentage is chosen, the system can whipsaw, or execute many small losing trades.

This system makes an initial buying or selling decision depending on whether the prices rise or fall more than a certain percentage from the first price seen. Once the initial direction is set, the system reverses its position when the prices retrace a certain percentage from a local maximum or minimum value. For example, if the system is buying, and the price rises to a maximum of 104, then retraces back to 100, the system will then close the long position and sell to establish a short position.

This is a reversal system and it is continuously in the market. To fully utilize its potential, it must be implemented on a market that allows traders to go long or short with equal ease. The futures, options, and Forex markets all possess this property.

This project implements the random walk algorithm to generate simulated price data. The algorithm is shown in the boxes below. A virtual coin is flipped each time the function is called. If heads, the price increases by 1c, if tails, the price decreases by 1c. This random data is then sent to the account manager and to the trading system. The trading system makes a decision and notifies the account manager if it wants to buy or sell. The account manager then outputs the trade log to the screen.

## Simulated Trading Example

The screenshot at the beginning of this article shows a run of the algorithm through random walk data. The price starts at 100 and starts randomly moving up and down by 1c. Since 100 is going to be the fist price, the first decision will be to buy if prices rise by 4% to 104, or sell if prices fall by 4% to 96. In this example, the 96 price target was hit first and the system places a sell order. The system is now looking for new lows, if prices retrace from this new low by 4%, then the system closes the sell order and places a buy order. In this example, the system reverses position at 98.01 as shown, since the prices must have come down to 94.08 (4% below 98.01). In the hypothetical example shown, after adding the transactions shown in the screen, the system shows a profit of 4.92. This very simple system will put you on the right side of a sustained trend, but is susceptible to whipsaws if the percentage is not appropriate for the width of the oscillations between maximums and minimums. Perhaps use of the ATR or the ADX indicators could reduce the whipsaws.

## Using the Code

This project has been arranged so that an unmodified trading system taken from the 4xlab.net project executes successfully. The supporting class framework has been implemented in a minimalistic way to allow this system to output trading decisions. Features such as parameter optimization and end of trading reports containing gains, loses and drawdown figures are not available in this project.

The FourPercentModel.cs file contains a complete implementation for a trading system. The `fPercentageChange` class inherits from the `ForexObject`. This allows the framework to receive and execute trading systems by treating them as their base class (`ForexObject`).

The base class `ForexObject` defines the following methods:

• C#
`public override void Init(string pParameters) `

This method initializes the object. This was chosen instead of the constructor to allow an existing object to be re-initialized and allow the object to remember multiple runs with different parameters for optimization purposes.

The system is initialized by sending it a parameter `string `in which parameter:value pairs are separated by semicolons. If no parameters are sent, the object is responsible for selecting default values.

• C#
`public override void ReceiveTick(sTick pTick) `

The following two methods are used by the object to receive real time quote data. If the object wants to receive tick data, it will register itself with the framework as a tick listener. The `private `method `DecisionFunction` must be called either here, or in the `ReceiveCandle` method.

The `DecisionFunction` method is responsible for analyzing quote data and making buying or selling decisions executed through the `Account` object. In this example, it can be seen that the decision function involves looking for new minimums or new maximums depending on the current trading direction. Once prices retrace by a specified percentage, the system reverses direction. Trades are entered by calling `Framework.Account.EnterTrade(int pDirection)`. For buy orders, use +1 for direction, use -1 for sell orders. The `Account `object returns its trading status via the `Framework.Account.InTrade()` method. A positive value means a buy order is open; a negative value means a sell order is open. Zero is returned if there are no trades open.

• C#
`public override void ReceiveCandle(sCandle pCandle, int pPeriod, string pCBTitle) `

This method is used by the object to receive candle data. To accomplish this, the object must register itself with the framework as a candle listener.

• C#
`public override bool Finished() `

This method allows the object to be called several times by the framework. The object can choose to change quote data after the end of each run and compare runs internally. If so, the first time the object is finished receiving quote data and this method is called, the object switches quote data and returns `false`. The second time around, this method will return `true`.

• C#
`public override string Title() `

This method allows individual objects in a collection to be identified by a friendly name.

### File: FourPercentModel.cs

C#
```//
// 4X Lab.NET © Copyright 2005-2006 ASCSE LLC
// http://www.4xlab.net
// email: 4xlab@4xlab.net
//

using System;

namespace FourPercentShell
{
// UNMODIFIED CLASS, SAME AS IN 4XLAB.NET
public class fPercentageChange : ForexObject
{
double iPercentage;
double iMin;
double iMax;

bool   FirstTick;
sTick  Tick;

public fPercentageChange()
{
}

public override void Init(string pParameters)
{
this.InitializeParameters(pParameters,"PERCENT:0.001;");
iPercentage = PParser.GetDouble("PERCENT",0);
Framework.TickServer.RegisterTickListener("System","*",this);
FirstTick = true;
}

public override void ReceiveTick(sTick pTick)
{
Tick    = pTick;

DecisionFunction();
}

public override void ReceiveCandle(sCandle pCandle, int pPeriod, string pCBTitle)
{
}

private void DecisionFunction()
{
if (FirstTick)
{
FirstTick = false;
iMin = Tick.Bid;
iMax = Tick.Bid;
}
else
{
{
if (Tick.Bid > iMax)
{
iMax = Tick.Bid;
}

if ((iMax-Tick.Bid) > iPercentage*iMax)
{
iMin = Tick.Bid;
iMax = 0;
}
}

{
if (Tick.Bid < iMin)
{
iMin = Tick.Bid;
}

if ((Tick.Bid-iMin) > iPercentage*iMin)
{
iMax = Tick.Bid;
iMin = 0;
}
}

{

if ((Tick.Bid-iMin) > iPercentage*iMin)
{
iMax = Tick.Bid;
iMin = 0;
}

if ((iMax-Tick.Bid) > iPercentage*iMax)
{
iMin = Tick.Bid;
iMax = 0;
}
}
}

double logMargin  = Framework.Account.GetAccount().C;

double MinTh = iMin + iMin*iPercentage;
double MaxTh = iMax - iMax*iPercentage;

iMin+","+MinTh+","+iMax+","+MaxTh);
}

public override bool Finished()
{
bool returnv = true;

return returnv;
}

public override string Title()
{
return "% Trend Change";
}
}
}```

The following file shows how the Tick Server generates simulated price data based on the random walk model. First, the price is incremented or decremented depending on a random number. Then a `Tick `object is created with `Bid `and `Ask `prices. Afterwards, the tick is sent first to the account simulator and to the registered tick listener later. The code implemented here only allows for one registered tick listener in addition to the account simulator.

### File: Framework.cs

C#
```public class oTickServer
{

...

public void GenerateTick()
{
int randomint = (int)(RNG.NextDouble()*1000);

if (randomint>500)
{
price++;
}
else
{
price--;
}

Tick = new sTick();

Tick.Bid = price;
Tick.Ask = Tick.Bid + 0.01;

}

...

}
```

## History

• 17th August, 2006: Initial post

## About the Author

 United States
No Biography provided

## Comments and Discussions

 First Prev Next
 Thanks mbaocha11-Aug-09 21:35 mbaocha 11-Aug-09 21:35
 Re: Thanks Member 127598101-Nov-16 8:05 Member 12759810 1-Nov-16 8:05
 Last Visit: 31-Dec-99 18:00     Last Update: 9-May-21 13:50 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.