[e]ADX





//+------------------------------------------------------------------+
//|                                                       [e]ADX.mq4 |
//|                                      Copyright © 2008, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, komposter"
#property link      "mailto:komposterius@mail.ru"

//	Save "trade_lib&info_lib.mqh" into the directiry "MetaTrader 4\experts\include\".
//	Save "[e]ADX.mq4" into the directiry "MetaTrader 4\experts\", open it and compile (F5).

// Extern variables:
extern string 		Expert_Properties 			= "-------Expert-Properties-------";
extern int 			Expert_Id 						= 1123;	// Unic Expert ID (use if starting more then 1 expert on one symbol)

extern double		Lot								= 0.4;	// lot size for new positions
extern int			CloseAfterProfit_pips		= 20;		// if profit >= CloseAfterProfit_pips, closing part of order (CloseAfterProfit_lot lots)
extern double		CloseAfterProfit_lot			= 0.2;
extern int			StopLoss							= 0;		// 0 - SL is not used
extern int			TakeProfit						= 0;		// 0 - TP is not used
extern int			TrailingStop					= 0;		// 0 - TS is not used

extern int			ADX_Period						= 14;		// indicator period
extern int			ADX_Price						= 0;		// used price
extern double		ADX_MinLevel					= 18.0;
extern double		ADX_MinChange					= 0.25;

extern int			RSI_Period						= 14;		// indicator period
extern int			RSI_Price						= 0;		// used price
extern double		RSI_BuyLevel					= 50.0;
extern double		RSI_SellLevel					= 50.0;

#include <trade_lib&info_lib.mqh>

datetime counted_bar = -1; int signal = 0, close_signal = 0;

int init()
{
	EnglishInfo = true;
	TradeInfoLib_Initialization ( Expert_Id, "[e]ADX" );

	if ( ADX_Period < 1 ) { ADX_Period = 1; }
	if ( ADX_Price < 0 || ADX_Price > 6 ) { ADX_Price = 0; }

	return(0);
}

int deinit()
{
	TradeInfoLib_Deinitialization();
	return(0);
}

int start()
{
	if ( !IsOK() ) { return(0); }

	find_signal();

	if ( _IsExpertOrder ( _MagicNumber ) )
		trade_control();
	else
		trade();

	return(0);
}

void find_signal()
{
	if ( Time[0] <= counted_bar ) { return(0); }
	counted_bar = Time[0];

	signal = 0; close_signal = 0;

	double adx			= iADX( _Symbol, _Period, ADX_Period, ADX_Price, MODE_MAIN		, 1 );
	double adx1			= iADX( _Symbol, _Period, ADX_Period, ADX_Price, MODE_MAIN		, 2 );
	double adx_plus	= iADX( _Symbol, _Period, ADX_Period, ADX_Price, MODE_PLUSDI	, 1 );
	double adx_minus	= iADX( _Symbol, _Period, ADX_Period, ADX_Price, MODE_MINUSDI	, 1 );
	double rsi			= iRSI( _Symbol, _Period, RSI_Period, RSI_Price, 1 );

	// buy open when:
	// ADX > ADX_MinLevel
	// RSI > RSI_BuyLevel
	//  +DI > -DI
	// buy close when:
	//  +DI < -DI

	// sell open when:
	// ADX > ADX_MinLevel
	// RSI < RSI_SellLevel
	//  -DI > +DI
	// sell close when:
	//  -DI < +DI
	if ( adx > ADX_MinLevel && adx - adx1 >= ADX_MinChange )
	{
		if ( rsi > RSI_BuyLevel  && adx_plus > adx_minus ) signal = 1;
		if ( rsi < RSI_SellLevel && adx_minus > adx_plus ) signal = -1;
	}
	if ( adx_plus > adx_minus ) close_signal = 1;
	if ( adx_minus > adx_plus ) close_signal = -1;
}

void trade()
{
	if ( signal > 0 )
	{
		OpenBuy();
		return;
	}
	if ( signal < 0 )
	{
		OpenSell();
		return;
	}
}

void trade_control()
{
	_ExpertOrdersInit( _MagicNumber );

	if ( _BuyTicket > 0 )
	{
		if ( close_signal < 0 )
		{
			if ( _OrderClose( _BuyTicket ) > 0 ) trade();
			return;
		}
		if ( CloseAfterProfit_pips > 0 )
		{
			if ( NormalizeDouble( Bid - _BuyOpenPrice - CloseAfterProfit_pips*_Point, _Digits ) >= 0 )
			{
				if ( _BuyLots >= Lot && _BuyLots >= CloseAfterProfit_lot )
				{
					_OrderClose( _BuyTicket, CloseAfterProfit_lot );
					return;
				}
			}
		}
		_TrailingStop( _BuyTicket, TrailingStop, 0, TrailingStop );
	}
	if ( _SellTicket > 0 )
	{
		if ( close_signal > 0 )
		{
			if ( _OrderClose( _SellTicket ) > 0 ) trade();
			return;
		}
		if ( CloseAfterProfit_pips > 0 )
		{
			if ( NormalizeDouble( _SellOpenPrice - Ask - CloseAfterProfit_pips*_Point, _Digits ) >= 0 )
			{
				if ( _SellLots >= Lot && _SellLots >= CloseAfterProfit_lot )
				{
					_OrderClose( _SellTicket, CloseAfterProfit_lot );
					return;
				}
			}
		}
		_TrailingStop( _SellTicket, TrailingStop, 0, TrailingStop );
	}
}

void OpenBuy()
{
	string text = strComment + ": BUY signal!";
	Alert( text );
	SendMail( text, text );

	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel;
	_OpenPriceLevel = NormalizeDouble( Ask, _Digits );

	if ( StopLoss > 0 )
	{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel - StopLoss*_Point, _Digits ); }
	else
	{ _StopLossLevel = 0.0; }

	if ( TakeProfit > 0 )
	{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel + TakeProfit*_Point, _Digits ); }
	else
	{ _TakeProfitLevel = 0.0; }

	if ( _OrderSend ( _Symbol, OP_BUY, Lot, _OpenPriceLevel, Slippage, _StopLossLevel, _TakeProfitLevel, "", _MagicNumber ) < 0 )
	{
		Alert( strComment, ": OrderSend error!!!" );
	}
	else
	{
		signal = 0;
	}
}

void OpenSell()
{
	string text = strComment + ": SELL signal!";
	Alert( text );
	SendMail( text, text );

	double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel;
	_OpenPriceLevel = NormalizeDouble( Bid, _Digits );

	if ( StopLoss > 0 )
	{ _StopLossLevel = NormalizeDouble( _OpenPriceLevel + StopLoss*_Point, _Digits ); }
	else
	{ _StopLossLevel = 0.0; }

	if ( TakeProfit > 0 )
	{ _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel - TakeProfit*_Point, _Digits ); }
	else
	{ _TakeProfitLevel = 0.0; }

	if ( _OrderSend ( _Symbol, OP_SELL, Lot, _OpenPriceLevel, Slippage, _StopLossLevel, _TakeProfitLevel, "", _MagicNumber ) < 0 )
	{
		Alert( strComment, ": OrderSend error!!!" );
	}
	else
	{
		signal = 0;
	}
}

/*
Indicator - ADX
During crossover of +DI/-DI lines after completion of the particular time bar and in the beginning of next time bar

BUY order should be triggered, when +DI crosses above -DI
          - Alert should be generated both the sound and email

SELL order should be triggered, when -DI crosses above +DI
          - Alert should be generated both the sound and email

There should be a possibility to alter the lot size
There should be a possibility to close percentage of order with 10 or 20 PIPS and the rest of the order can be closed at next cross.
So with the above specification when one order closes the other side of the begins.
This should work in all currency pairs and in all time frames

Associating with another indicator.
Initial I though of using RSI, Stochastic or Awesome OSC. But now I feel, if the ADX executes order based on the crossovers will be enough. 
So I don't want to make it complex. Because with ADX very few trades go wrong with some minimum loss. But mostly it brings some reasonable profit.

Please feel free to comment on the above criteria. If there is any better way to improve or add new features to this criteria, I would like to have it.
*/



Sample





Analysis



Market Information Used:

Series array that contains open time of each bar


Indicator Curves created:


Indicators Used:

Movement directional index
Relative strength index


Custom Indicators Used:

Order Management characteristics:
It Closes Orders by itself

Other Features:

It issuies visual alerts to the screen
It sends emails