Дальнейшим развитием идеи одновременного открытия пары рыночных ордеров Buy и Sell является алгоритм открытия комбинации отложенных ордеров BuyStop и SellStop. Суть этого алгоритма состоит в следующем.
Пусть на валютном рынке по некоторой валютной паре наблюдается некоторое «затишье», т.е. выявлен боковой тренд, при котором котировки изменяются внутри некоторого ценового коридора. В этом случае при открываются одновременно два отложенных ордера
- BuyStop выше ВЕРХНЕЙ ГРАНИЦЫ КОРИДОРА на k1 пунктов,
- SellStop ниже НИЖНЕЙ ГРАНИЦЫ КОРИДОРА на k1 пунктов,
по одной валюте, у которых StopLoss и TakeProfit равны s1 и t1.
После открытия одной из позиций второй отложенный ордер удаляется из системы. Преимущество данного алгоритма по сравнению с алгоритмом одновременного открытия пары рыночных ордеров Buy и Sell заключается в следующем:
1. Любая позиция (длинная или короткая) будет открыта только в случае наличия большого движения цены по валютной паре, т.е. если после обнаружения бокового тренда изменение цены будет несущественным (определяется значением k1), то в торговой системе не будут открываться позиции.
|
|
2. Имеется более удобная в смысле программной реализации возможность ограничения времени существования отложенных ордеров до вероятного открытия позиции. Легче отменить отложенный ордер без потери на спред, чем закрывать открытую позицию противоположным ордером.
3. Заранее указав в программе значение StopLoss для отложенного ордера, мы сразу же ограничили возможные потери от комбинации ордеров. В то же время для реализации такого ограничения при использовании комбинации рыночных ордеров необходимо выполнять достаточно громоздкие проверки различных условий.
Программная реализация алгоритма открытия комбинации отложенных ордеров BuyStop и SellStop отличается от реализации алгоритма одновременного открытия пары рыночных ордеров Buy и Sell следующими командами:
1. Командами открытия отложенных ордеров.
Для ордера BuyStop имеем:
Price1=CoridMax+k1*Point
StopLoss1=Price1-StopLoss0*Point;
TakeProfit1=Price1+Profit0*Point;
SetOrder(OP_BUYSTOP,Lots1,Price1,Slippage1,
StopLoss1,TakeProfit1,Blue); // исполняем
Для ордера SellStop имеем:
Price1=CoridMin-k1*Point
StopLoss1=Price1+StopLoss0*Point;
TakeProfit1=Price1-Profit0*Point;
SetOrder(OP_SELLSTOP,Lots1,Price1,Slippage1,
StopLoss1,TakeProfit1,Green); // исполняем
2. Добавляется этап, на котором необходимо отслеживать момент времени, когда исполняется один из отложенных ордеров (т.е. открывается длинная или короткая позиция). В этом случае второй отложенный ордер следует удалить. Рекомендуется время выполнения этого действия обозначить вертикальной красной линией, что реализовано в приведнном ниже фрагменте.
// =========================================================================
|
|
// Этап 6. Указать на графике время закрытия одной позиции.
// Рисуем вертикальную красную линию. При этом:
// Step0 = 5 - закрыта одна позиция
// =========================================================================
if Step0 = 6 then
{// было открыто обе позиции
// найдем количество позиций SymbolTotalTrades для данной валютной пары Symbol
SymbolTotalTrades=0;
for cnt = 1 to TotalTrades
{ // выберем ордера только для данной валюты
if OrderValue(cnt,VAL_SYMBOL)=Symbol then // инструмент совпадает?
{
SymbolTotalTrades=SymbolTotalTrades+1;
};
}; // for cnt = 1 to TotalTrades
if SymbolTotalTrades = 1 then
{ // одна позиция уже закрыта
Step0 =7;
// нарусуем вертикальную линию при закрытии позиции
MoveObject(""+CurTime,OBJ_VLINE,CurTime,Close,
CurTime,Close,Red,1,STYLE_SOLID);
alert(Symbol," Закрыта одна позиция Time=",
TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
" Trades=",SymbolTotalTrades);
};// if TotalTrades = 1
// если один ордер из отложенных стал реальным BUY or SELL,
// то tmp1=номер этого ордера
// А второй (отложенный) ордер удаляем
tmp1=0;
for cnt = 1 to TotalTrades
{
// выберем ордера только для данной валюты
if OrderValue(cnt,VAL_SYMBOL)=Symbol then // инструмент совпадает?
{
if OrderValue(cnt,VAL_TYPE)<=OP_SELL then // это открытая позиция? OP_BUY или OP_SELL
{ tmp1=cnt; //запомним номер реального ордера
break;
};
}; // if OrderValue(cnt,VAL_SYMBOL)=Symbol
}; // for cnt = 1 to TotalTrades
// найден ли реальный ордер?
if tmp1 > 0 then // if tmp1 >0
{ // здесь если один из ордеров реальнвй
// найдем номер отложенного ордера
tmp1=0;
for cnt = 1 to TotalTrades
{
// выберем ордера только для данной валюты
if OrderValue(cnt,VAL_SYMBOL)=Symbol then // инструмент совпадает?
{
if OrderValue(cnt,VAL_TYPE)>OP_SELL then // это отложенный ордер
{ tmp1=cnt; //запомним номер отложенного ордера
break;
};
}; // if OrderValue(cnt,VAL_SYMBOL)=Symbol
}; // for cnt = 1 to TotalTrades
// найден ли отложенный ордер номер tmp1?
if tmp1 >0 then
{ // здесь если найден отложенный ордер
// удалим его
alert(Symbol," Step0 =", Step0," удалить отложенный tmp1=",tmp1,
" ",OrderValue(tmp1,VAL_TICKET), " close=",Close);
DeleteOrder(OrderValue(tmp1,VAL_TICKET),Red);
}; // if tmp1 >0
}; // if tmp1 >0
};// if Step0 = 6
При завершении работы алгоритма (когда закрывается позиция Buy или Sell) рекомендуется визуально отобразить этот факт вертикальной белой линией.
// =========================================================================
// Этап 7. Указать на графике время закрытия второй позиции.
// Рисуем вертикальную белую линию. При этом:
// Step0 = 0 - закрыты обе позиции
// =========================================================================
if Step0 = 7 then
{// одна позиция уже закрыта
// найдем количество позиций SymbolTotalTrades для данной валютной пары Symbol
SymbolTotalTrades=0;
for cnt = 1 to TotalTrades
{ // выберем ордера только для данной валюты
if OrderValue(cnt,VAL_SYMBOL)=Symbol then // инструмент совпадает?
{
SymbolTotalTrades=SymbolTotalTrades+1;
};
}; // for cnt = 1 to TotalTrades
if SymbolTotalTrades = 0 then
{ // первая и вторая позиции уже закрыты
Step0=0;
// нарусуем вертикальную линию при закрытии позиции
MoveObject(""+CurTime,OBJ_VLINE,CurTime,Close,
CurTime,Close,White,1,STYLE_SOLID);
alert(Symbol," Закрыта вторая позиция Time=",
TimeHour(CurTime),":",TimeMinute(CurTime),":",TimeSeconds(CurTime),
" Trades=",SymbolTotalTrades);
};// if TotalTrades = 0
};// if Step0 = 7
Результат работы указанного алгоритма приведен на следующем рисунке.