Одновременное открытие ордеров
Рассмотрим алгоритм "одновременного" открытия ордеров.
Суть: Пусть в программе была выполнена команда на открытие первого ордера. Второй ордер следует открыть через t секунд.
Алгоритм открытия двух ордеров с временной задержкой между ними можно реализовать с помощью следующих шагов.
Шаг 1. Выявить условия на рынке для открытия пары ордеров.
Шаг 2. Сформировать команду на открытие первого ордера.
Шаг 3. Задать период ожидания длительностью t секунд.
Шаг 4. Сформировать команду на открытие второго ордера.
При реализации этого алгоритма желательно знать номер выполненного шага.
Для того, чтобы можно было определить номер выполненного шага алгоритма, введем переменную Step0. В переменной Step0 будем записывать номер шага алгоритма, следующего за уже выполненным шагом.
Для реализации указанных шагов можно использовать следующие фрагменты программы:
Шаг 1.
if Step0=1 then // можно выполнить команды первого шага
{
. . . . . . . .
//проверка условий открытия пары ордеров
. . . . . . . .
Step0=2; // определено условие для открытия
. . . . . . . .
};
Шаг 2.
При открытии позиции следует запомнить время выполнения команды в переменной OpenTime1.
if Step0=2 then // можно выполнить команды второго шага
{
. . . . . . . .
OpenTime1=CurTime; //запомним текущее время
// купим лот
Price1=Ask;
StopLoss1=Price1-StopLoss0*Point;
TakeProfit1=Price1+Profit0*Point;
SetOrder(OP_BUY,Lots1,Price1,Slippage1,StopLoss1,TakeProfit1,Blue); // исполняем
// нарусуем вертикальную линию при открытии позиции
MoveObject(""+CurTime,OBJ_VLINE,CurTime,Close,
CurTime,Close,Blue,1,STYLE_SOLID);
alert(Symbol," Попытка открыть первую позицию Time=",
TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
" Trades=",SymbolTotalTrades);
Step0=3;
exit;
};
При реализации шага 3 возникает необходимость использования дополнительных настраиваемых параметров:
1. Время ожидания реального открытия первой или второй позиции- WaitTime1 (обычно 120 сек.).
2. Время ожидания после появления первого ордера в списке ордеров (после реального открытия позиции) перед открытием второго ордера (сек.) - WaitTime0 (обычно 11 сек.).
Необходимость использования этих параметров вызвана чисто техническими проблемами Metatrader, так как при его работе всегда происходят:
- пауза после команды на открытие ордера,
- пауза после появления ордера в списке ордеров.
На третьем шаге следует дождаться момента времени, когда в списке ордеров появится новый ордер:
// ========================================================================
// Этап 3. Ждем пока первый ордер появится в списке ордеров,
// т.е. когда SymbolTotalTrades = 1
// При этом:
// Step0 = 4 - после реального открытия первой позиции
// OpenTime1 - время реального открытия первой позиции
// Но если в течение WaitTime1 секунд позиция не открыта,
// то вывести сообщение на экран.
// ========================================================================
if Step0 = 3 then
{// можно ли открывать вторую позицию
// найдем количество позиций SymbolTotalTrades для данной валютной пары Symbol
SymbolTotalTrades=0;
for cnt = 1 to TotalTrades
{ // выберем ордера только для данной валюты
if OrderValue(cnt,VAL_SYMBOL)=Symbol then // инструмент совпадает?
{
if OrderValue(cnt,VAL_TYPE)=OP_BUY then // это отложенный ордер
{
SymbolTotalTrades=SymbolTotalTrades+1;
};
};
}; // for cnt = 1 to TotalTrades
После появления нового ордера в списке открытых ордеров, выполняются следующие действия:
if SymbolTotalTrades = 1 then
{ // первая позиция уже реально открыта
// определим переменные для контроля открытия второй позиции
Step0=4;
OpenTime1=CurTime;
// нарусуем вертикальную линию при открытии позиции
MoveObject(""+CurTime,OBJ_VLINE,CurTime,Close,
CurTime,Close,Blue,1,STYLE_SOLID);
}// if TotalTrades = 1
else
{ // первая позиция еще не открыта
if OpenTime1 < CurTime - WaitTime1 then
{ // первая позиция еще не открыта в течение большого периода времени
alert(Symbol," ПЕРВАЯ позиция не открыта в течение ",WaitTime1," сек. Time=",
TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime));
Step0=1; // можно заново определять условия открытия пары ордеров
};// if OpenTime1 < CurTime - WaitTime1
};// else if TotalTrades = 1
Если течение t секунд первый ордер не был открыт, то выводим на экран сообщение об ошибке и переходим к определению времени появления новых условий открытия пары ордеров.
Шаг 4.
Перед открытием второго ордера рекомендуется выдержать паузу, длительностью несколько секунд, после реального открытия первого ордера.
// =========================================================================
// Этап 4. Ждем пока после реального открытия первой позиции
// пройдет WaitTime0 секунд.
// Выдаем команду на открытие второй позиции SELL. При этом
// Step0 = 5 - после выдачи приказа на открытие второй позиции
// PoplavokTime - время выдачи команды на открытие
// ======================================================================
// откроем вторую позицию
// перед отдачей приказа на открытие второй позиции
// должно пройти WaitTime0 после открытия первой позиции
if Step0 = 4 then
{// можно ли открывать вторую позицию
tmp1=CurTime-OpenTime1;
if tmp1 >= WaitTime0 then
{ // первая позиция уже открыта в течение нескольких секунд
// alert(Symbol," Вторую позицию можно открывать ",tmp1," сек. Time=",
// TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
// " Trades=",TotalTrades);
// зададим переменные для контроля открытия второй позиции
Step0=5;
OpenTime1=CurTime;
StopLoss1=Price1+StopLoss0*Point;
TakeProfit1=Price1-Profit0*Point;
//tmp1=CurTime-OpenTime1;
// alert(Symbol," Открываем вторую позицию ",tmp1," сек. Time=",
// TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
// " Trades=",TotalTrades);
SetOrder(OP_SELL,Lots1,Price1,Slippage1,StopLoss1,TakeProfit1,Green); // исполняем
// alert(Symbol," Выполнена команда на открытие второй позиции ",tmp1," сек. Time=",
// TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
// " Trades=",TotalTrades);
exit;
};// if tmp1 >= WaitTime0
};// if Step0 = 4
Для того, чтобы быть уверенными в том, что произойдет открытие ордера Sell, рекомендуется проследить за процессом открытия второго ордера, т.е. предлагается выполнить еще один шаг. Поэтому на шаге 4 переменная Step0 было присвоено значение 5.
На шаге 5 рекомендуется:
1. Выполнить проверку на появление нового ордера Sell.
2. При обнаружении нового ордера Sell нарисовать вертикальную зеленую линию.
3. Если через t секунд новый ордер не обнаружен, то следует вывести на экран сообщение об ошибке.
// ======================================================================
// Этап 5. Проверка открытия второй позиции -
// Ждем пока второй ордер появится в списке ордеров,
// т.е. когда TotalTrades = 2. При этом:
// Step0 = 0 - открыты обе позиции
// Но если в течение WaitTime1 секунд позиция не открыта,
// надо что-то делать (что?).
// ======================================================================
// проверка открытия второй позиции
if Step0 = 5 then
{// открыта ли вторая позиция
tmp1=CurTime-OpenTime1;
// alert(Symbol," Открыта ли вторая позиция? ",tmp1," сек. Time=",
// TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
// " Trades=",TotalTrades);
// найдем количество позиций SymbolTotalTrades для данной валютной пары Symbol
SymbolTotalTrades=0;
for cnt = 1 to TotalTrades
{ // выберем ордера только для данной валюты
if OrderValue(cnt,VAL_SYMBOL)=Symbol then // инструмент совпадает?
{
if OrderValue(cnt,VAL_TYPE)=OP_SELL then // это отложенный ордер
{
SymbolTotalTrades=SymbolTotalTrades+1;
};
};
}; // for cnt = 1 to TotalTrades
if SymbolTotalTrades = 1 then
{ // первая и вторая позиции уже открыты
Step0=0;
// нарусуем вертикальную линию зеленым цветом при открытии второй позиции
MoveObject(""+CurTime,OBJ_VLINE,CurTime,Close,
CurTime,Close,Green,1,STYLE_SOLID);
alert(Symbol," Открыта вторая позиция Time=",
TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
" Trades=",SymbolTotalTrades);
}// if TotalTrades = 2
else
{ // вторая позиция еще не открыта
if OpenTime1 < CurTime - WaitTime1 then
{ // вторая позиция еще не открыта в течение большого периода времени
alert(Symbol," ВТОРАЯ позиция не открыта в течение ",WaitTime1," сек. Time=",
TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime));
Tmp1=0;
Step0=0;
};// if OpenTime1 < CurTime - WaitTime1
};// else if TotalTrades = 2
};// if Step0= 5