Order placement by Fibonacci levels

Such MT4 tool as "Fibonacci lines" is especially popular among traders. It is used for absolutely different purposes. Wave makers (adherents of the wave analysis) use this tool for calculation of waves, others - for simple calculation of the channel in which it is possible to find quickly the middle or other parts from the width of the channel.

In many cases, after the construction Fibonacci lines traders need to set pending orders on key levels. For this purpose it is necessary to make some operations of installation of orders manually in a row. Thus it is necessary to enter each price of a level in a window of order opening price. The trader does not feel discomfort when there are 2-3 Fibonacci levels, but a large amount of levels can even confuse the trader. This is where the help comes in. the script SetOrdersOnFibo.

The script's task is to find the last "Fibonacci lines" drawn on the chart and set pending orders at all of its levels. The script will automatically determine the order type. If the "0%" level of the symbol "Fibonacci lines" is lower than the "100%" level, the script will set BUY orders (Buy Stop or Buy Limit depending on the current price location). And if the "0%" level is higher than the "100%" level, the script will set SELL orders (Sell Stop or Sell Limit).

Let's look at how all these problems are solved in the code.

The script must first find the tool "Fibonacci lines":

bool FindFibo()
{
if (ObjectsTotal(OBJ_FIBO) > 0)
{
// — 1 — ========== Нахождение первой по счету сетки Фибо ==============
for (int i = ObjectsTotal()-1; i >= 0; i—)
if (ObjectType(ObjectName(i)) == OBJ_FIBO)
break;
// — 1 — ========== Окончание блока =============================
// — 2 — ========== Определение цены каждого из уровней ===============
string Name = ObjectName(i);
double ZeroLevel = ObjectGet(Name, OBJPROP_PRICE2);
double Level100 = ObjectGet(Name, OBJPROP_PRICE1);
CountLevels = ObjectGet(Name, OBJPROP_FIBOLEVELS);

if (ZeroLevel > Level100)
Direction = False;
else
Direction = True;
for (i = 0; i < CountLevels; i++)
{
double Level = ObjectGet(Name, OBJPROP_FIRSTLEVEL+i);
if (!Direction)
OpenPrice[i] = ZeroLevel — (ZeroLevel — Level100)*Level;
else
OpenPrice[i] = ZeroLevel + (Level100 — ZeroLevel)*Level;
}
return(True);

// — 2 — ========== Окончание блока =============================
}
else
{
Alert("No Fibo grid found!");
return(False);
}
}

At the very beginning of the function, it is determined whether the chart, to which the Expert Advisor is attached, has a Fibonacci Lines instrument at all. If no such instruments are found, then the script will end with an audible error message.

If at least one instrument is detected, the program execution will move to Block 1, where the last instrument "Fibonacci lines" will be found from all the objects present on the chart. Thus, the problem of presence on the chart of several similar instruments is solved. That is, in any case, the last instrument attached to the chart will be taken as the basis.

Next, block 2 is executed, where first the levels "0%" and "100%" are defined. These levels correspond to the points on which the tool is constructed. By comparing the values of zero and 100% levels, the direction of pending orders is determined. As a result, the Direction variable takes the False value if SELL orders are to be set, and the True value if BUY orders are to be set. The total number of levels is also calculated here, and stored in the CountLevels variable.

When the base levels are defined and the direction is chosen, all other levels of the "Fibonacci lines" object are calculated. The calculated values are stored in the OpenPrice array. This array consists of 32 elements - the maximum number of levels allowed for "Fibonacci lines".

The FindFibo function is called from the start function of the script. If it (the FindFibo function) worked successfully, the orders will be set:

if (FindFibo())
for (int i = 0; i < CountLevels; i++)
{
// — 2 — == Расчет для BUY-ордеров =================================
int Type = -1; // we do not set orders by default
If (Direction)
{
RefreshRates();
if (OpenPrice[i] > Ask + StopLevel) // if the price is higher than Ask, put BuyStop
if (UseStopOrders)

{
Type = OP_BUYSTOP;
double Price = NP(OpenPrice[i] + Spread);
double SL = NP(IF(StopLoss == 0, 0, Price — StopLoss*Tick));
double TP = NP(IF(TakeProfit == 0, 0, Price + TakeProfit*Tick));
}
if (OpenPrice[i] < Ask — StopLevel)  // если цена ниже Ask, то ставим BuyLimit
if (UseLimitOrders)

{
Type = OP_BUYLIMIT;
Price = NP(OpenPrice[i] + Spread);
SL = NP(IF(StopLoss == 0, 0, Price — StopLoss*Tick));
TP = NP(IF(TakeProfit == 0, 0, Price + TakeProfit*Tick));
}
}
// — 2 — == Окончание блока =====================================
// — 3 — == Расчет для SELL-ордеров ================================
else
{
RefreshRates();
if (OpenPrice[i] < Bid — StopLevel)  // если цена ниже Bid, то ставим SellStop
if (UseStopOrders)
{
Type = OP_SELLSTOP;
Price = NP(OpenPrice[i]);
SL = NP(IF(StopLoss == 0, 0, Price + StopLoss*Tick));
TP = NP(IF(TakeProfit == 0, 0, Price — TakeProfit*Tick));

}
if (OpenPrice[i] > Bid + StopLevel) // if the price is higher than Bid, set SellLimit
if (UseLimitOrders)
{
Type = OP_SELLLIMIT;
Price = NP(OpenPrice[i]);
SL = NP(IF(StopLoss == 0, 0, Price + StopLoss*Tick));
TP = NP(IF(TakeProfit == 0, 0, Price — TakeProfit*Tick));

}
}
// — 3 — == Окончание блока =====================================
// — 4 — == Установка одного ордера ================================
if (Type != -1) // if an order is defined, set
OpenOrderCorrect(Type, Price, SL, TP);
// — 4 — == Окончание блока =====================================

To set an order at each level found, a cycle is used, executed CountLevels times. This loop is divided into three blocks (block numbers from 2 to 4).

In the second block, the commands are executed if the value of Direction, previously defined in the FindFibo function, is True. The block itself, in its turn, is divided into two parts. In the first one, the price value of the found OpenPrice level is compared to the Ask price, to which the StopLevel minimum stop level is added. If the level is higher than that, the value of the UseStopOrders expert input parameter is checked, using which the user can permit or deny the setting of stop orders (BuyStop and SellStop), and the Type variable is assigned the OP_BUYSTOP order type, and the Price, SL and TP variables receive the corresponding values. Then the level is compared to the Ask price from which the StopLevel value is deducted. If the level is lower than this price, the value of the input parameter UseLimitOrders is checked (permit/prohibit orders BuyLimit and SellLimit), and the Type variable is assigned the value OP_BUYLIMIT. The variables Price, SL and TP also receive their values.

The third block is a mirror copy of the second block. It is executed when the value of Direction is False. The OpenPrice level is compared to priced at Bid, depending on which the stop or limit SELL-order is set.

In the fourth block, first, the value of the Type variable is checked and, if its value is greater than or equal to zero, the OpenOrderCorrect function is called, which sets the next order.

Для работы со скриптом необходимо установить на графике объект «линии Фибоначчи», у которого настроить все нужные уровни (ненужные — удалить). Только после этого можно присоединять скрипт.

At startup. of the script you can set the values of the input parameters:
—         Lots = 0.01 – объем каждого из отложенных ордеров;
—         TakeProfit = 50 — уровень профита в пунктах от цены открытия (для пятизначных котировок умножить на 10);
—         StopLoss = 100 — уровень стоп-приказа в пунктах (для пятизначных котировок умножить на 10);
—         UseStopOrders = True – разрешать (True) или запрещать (False) установку ордеров BuyStop и SellStop;
—         UseLimitOrders = True – разрешать (True) или запрещать (False) установку ордеров BuyLimit и SellLimit;
—         MagicNumber = 900 – уникальный идентификатор ордеров, установленных скриптом. Самим скриптом это значение только устанавливается, но нигде не проверяется. Используется для последующих действий пользователя с ордерами.

Full source code of the script.

Leave a Reply

Back to top button