Выставление ордеров по времени
#1
Отправлено 25 May 2010 - 16:58
Прошу Вас помочь, доработать эксперта, который выставляет ордера различного типа в заданное время.
Чего не хватает, надо чтобы когда наступает время выставить ордер, то проверялось условие: текущая цена равна или более/менее указанной в параметрах эксперта. Если да, то ордер sell/buy и т.д., если нет, то не выставлять.
Заранее благодарен, за внимание.
Вот сам код:
------------------------------------------------------------------------------------------------------------------
extern double Lots=0.1; //рабочий лот
extern int TP=10; //тейк профит
extern int SL=0; //стоп лосс
extern datetime Open_Time=D'22.03.2010 13:00'; //время открытия ордеров
extern int slippage=2; //уровень допустимого реквота
extern int MagicNumber=5345; //магическое число ордеров
extern bool Open_Sell=false; //включение/выключение работы с sell-ордерами
extern bool Open_Buy=false; //включение/выключение работы с buy-ордерами
extern bool Open_Sell_Stop=false; //включение/выключение работы с sell stop-ордерами
extern bool Open_Buy_Stop=false; //включение/выключение работы с buy stop-ордерами
extern bool Open_Sell_Limit=false; //включение/выключение работы с sell limit-ордерами
extern bool Open_Buy_Limit=false; //включение/выключение работы с buy limit-ордерами
extern int Open_Level=30; //уровень отдаления от цены, на котором ставим отложенный ордер
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
//----
//+----------------------------------------------------------------------------------------------+
//| поиск открытых ордеров по паре |
bool pos_sell=false;
for (int i_op_sell=OrdersTotal()-1; i_op_sell>=0; i_op_sell--)
{
if (!OrderSelect(i_op_sell,SELECT_BY_POS,MODE_TRADES)) break;
if (Symbol()==OrderSymbol()
&&(OrderType()==OP_SELL||OrderType()==OP_SELLSTOP||OrderType()==OP_SELLLIMIT)
&&(OrderMagicNumber()==MagicNumber)
&&MathFloor(OrderOpenTime()/60)==TimeCurrent()/60)
{
pos_sell=true; break;
}
}
bool pos_buy=false;
for (int i_op_buy=OrdersTotal()-1; i_op_buy>=0; i_op_buy--)
{
if (!OrderSelect(i_op_buy,SELECT_BY_POS,MODE_TRADES)) break;
if (Symbol()==OrderSymbol()
&&(OrderType()==OP_BUY||OrderType()==OP_BUYSTOP||OrderType()==OP_BUYLIMIT)
&&(OrderMagicNumber()==MagicNumber)
&&MathFloor(OrderOpenTime()/60)==TimeCurrent()/60)
{
pos_buy=true; break;
}
}
//| поиск открытых ордеров по паре |
//+----------------------------------------------------------------------------------------------+
//+--------------------------------------------+
//| расчёт TP и SL |
double sl_buy, sl_sell, tp_buy, tp_sell
,sl_buy_stop, sl_sell_stop,
tp_buy_stop, tp_sell_stop
,sl_buy_limit, sl_sell_limit,
tp_buy_limit, tp_sell_limit;
if(!SL)
{
sl_buy=0;
sl_sell=0;
sl_buy_stop=0;
sl_sell_stop=0;
sl_buy_limit=0;
sl_sell_limit=0;
}
else
{
sl_buy=Bid-SL*Point;
sl_sell=Ask+SL*Point;
sl_buy_stop=Bid+Open_Level*Point-SL*Point;
sl_sell_stop=Ask-Open_Level*Point+SL*Point;
sl_buy_limit=Bid-Open_Level*Point-SL*Point;
sl_sell_limit=Ask+Open_Level*Point+SL*Point;
}
if(!TP)
{
tp_buy=0;
tp_sell=0;
tp_buy_stop=0;
tp_sell_stop=0;
tp_buy_limit=0;
tp_sell_limit=0;
}
else
{
tp_buy=Bid+TP*Point;
tp_sell=Ask-TP*Point;
tp_buy_stop=Bid+Open_Level*Point+TP*Point;
tp_sell_stop=Ask-Open_Level*Point-TP*Point;
tp_buy_limit=Bid-Open_Level*Point+TP*Point;
tp_sell_limit=Ask+Open_Level*Point-TP*Point;
}
//| расчёт TP и SL |
//+--------------------------------------------+
//+-----------------------------------------------------------------------------------------------------------+
//| открытие ордеров |
if(Open_Time/60==TimeCurrent()/60)
{
if(!pos_buy)
{
if(Open_Buy)
{
OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, sl_buy,tp_buy, "time_open", MagicNumber, 0, NULL);
}
if(Open_Buy_Stop)
{
OrderSend(Symbol(), OP_BUYSTOP, Lots, Ask+Open_Level*Point, slippage, sl_buy_stop,tp_buy_stop,
"time_open", MagicNumber, 0, NULL);
}
if(Open_Buy_Limit)
{
OrderSend(Symbol(), OP_BUYLIMIT, Lots, Ask-Open_Level*Point, slippage, sl_buy_limit,tp_buy_limit,
"time_open", MagicNumber, 0, NULL);
}
}
if(!pos_sell)
{
if(Open_Sell)
{
OrderSend(Symbol(), OP_SELL, Lots, Bid, slippage, sl_sell, tp_sell, "time_open", MagicNumber, 0, NULL);
}
if(Open_Sell_Stop)
{
OrderSend(Symbol(), OP_SELLSTOP, Lots, Bid-Open_Level*Point,slippage, sl_sell_stop, tp_sell_stop,
"time_open", MagicNumber, 0, NULL);
}
if(Open_Sell_Limit)
{
OrderSend(Symbol(), OP_SELLLIMIT, Lots, Bid+Open_Level*Point,slippage, sl_sell_limit, tp_sell_limit,
"time_open", MagicNumber, 0, NULL);
}
}
}
//| открытие ордеров |
//+-----------------------------------------------------------------------------------------------------------+
//----
return(0);
}
//+------------------------------------------------------------------+
 
#2
Отправлено 25 May 2010 - 17:17
if(Open_Buy) { OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, sl_buy,tp_buy, "time_open", MagicNumber, 0, NULL); }и замените на
if(Open_Buy && Bid>=Price) { OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, sl_buy,tp_buy, "time_open", MagicNumber, 0, NULL); }для селов соответственно:
if(Open_Sell && Bid<=Price) { OrderSend(Symbol(), OP_SELL, Lots, Bid, slippage, sl_sell, tp_sell, "time_open", MagicNumber, 0, NULL); }и также с каждым типом ордера. И в начале кода потом добавьте
extern double Price=1.2345;Это и будет то значение цены с которым сверяемся при открытии ордера.
#3
Отправлено 25 May 2010 - 19:13
А тему то новую зачем создавать? Вот ведь сделали специальную ветку для таких заданий. И метку "Важно" поставили, чтобы все видели. В этом коде найдите строчки (перед OrderSend()):
if(Open_Buy) { OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, sl_buy,tp_buy, "time_open", MagicNumber, 0, NULL); }и замените наif(Open_Buy && Bid>=Price) { OrderSend(Symbol(), OP_BUY, Lots, Ask, slippage, sl_buy,tp_buy, "time_open", MagicNumber, 0, NULL); }для селов соответственно:if(Open_Sell && Bid<=Price) { OrderSend(Symbol(), OP_SELL, Lots, Bid, slippage, sl_sell, tp_sell, "time_open", MagicNumber, 0, NULL); }и также с каждым типом ордера. И в начале кода потом добавьтеextern double Price=1.2345;Это и будет то значение цены с которым сверяемся при открытии ордера.
Спасибо, попробую.
#4
Отправлено 26 May 2010 - 09:16
Попутно родился вопрос, а можно ли в этот код добавить функцию TrailingStop, напримере реализованной в советнике "Трал удавка". Скрипт прилагается.
Прикрепленные файлы
#5
Отправлено 26 May 2010 - 09:52
Вчера сделал изменения, все ОК. Спасибо.
Попутно родился вопрос, а можно ли в этот код добавить функцию TrailingStop, напримере реализованной в советнике "Трал удавка". Скрипт прилагается.
В советнике всего одна функция:
void TrailingUdavka(int ticket,int trl_dist_1,int level_1,int trl_dist_2,int level_2,int trl_dist_3) { double newstop = 0; // новый стоплосс double trldist; // расстояние трейлинга (в зависимости от "пройденного" может = trl_dist_1, trl_dist_2 или trl_dist_3) // проверяем переданные значения if ((trl_dist_1<MarketInfo(Symbol(),MODE_STOPLEVEL)) || (trl_dist_2<MarketInfo(Symbol(),MODE_STOPLEVEL)) || (trl_dist_3<MarketInfo(Symbol(),MODE_STOPLEVEL)) || (level_1<=trl_dist_1) || (level_2<=trl_dist_1) || (level_2<=level_1) || (ticket==0) || (!OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))) { Print("Трейлинг функцией TrailingUdavka() невозможен из-за некорректности значений переданных ей аргументов."); return(0); } // если длинная позиция (OP_BUY) if (OrderType()==OP_BUY) { // если профит <=trl_dist_1, то trldist=trl_dist_1, если профит>trl_dist_1 && профит<=level_1*Point ... if ((Bid-OrderOpenPrice())<=level_1*Point) trldist = trl_dist_1; if (((Bid-OrderOpenPrice())>level_1*Point) && ((Bid-OrderOpenPrice())<=level_2*Point)) trldist = trl_dist_2; if ((Bid-OrderOpenPrice())>level_2*Point) trldist = trl_dist_3; // если стоплосс = 0 или меньше курса открытия, то если тек.цена (Bid) больше/равна дистанции курс_открытия+расст.трейлинга if ((OrderStopLoss()==0) || (OrderStopLoss()<OrderOpenPrice())) { if (Bid>(OrderOpenPrice() + trldist*Point)) newstop = Bid - trldist*Point; } // иначе: если текущая цена (Bid) больше/равна дистанции текущий_стоплосс+расстояние трейлинга, else { if (Bid>(OrderStopLoss() + trldist*Point)) newstop = Bid - trldist*Point; } // модифицируем стоплосс if ((newstop>OrderStopLoss()) && (newstop<Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point)) { if (!OrderModify(ticket,OrderOpenPrice(),newstop,OrderTakeProfit(),OrderExpiration())) Print("Не удалось модифицировать стоплосс ордера №",OrderTicket(),". Ошибка: ",GetLastError()); } } // если короткая позиция (OP_SELL) if (OrderType()==OP_SELL) { // если профит <=trl_dist_1, то trldist=trl_dist_1, если профит>trl_dist_1 && профит<=level_1*Point ... if ((OrderOpenPrice()-(Ask + MarketInfo(Symbol(),MODE_SPREAD)*Point))<=level_1*Point) trldist = trl_dist_1; if (((OrderOpenPrice()-(Ask + MarketInfo(Symbol(),MODE_SPREAD)*Point))>level_1*Point) && ((OrderOpenPrice()-(Ask + MarketInfo(Symbol(),MODE_SPREAD)*Point))<=level_2*Point)) trldist = trl_dist_2; if ((OrderOpenPrice()-(Ask + MarketInfo(Symbol(),MODE_SPREAD)*Point))>level_2*Point) trldist = trl_dist_3; // если стоплосс = 0 или меньше курса открытия, то если тек.цена (Ask) больше/равна дистанции курс_открытия+расст.трейлинга if ((OrderStopLoss()==0) || (OrderStopLoss()>OrderOpenPrice())) { if (Ask<(OrderOpenPrice() - (trldist + MarketInfo(Symbol(),MODE_SPREAD))*Point)) newstop = Ask + trldist*Point; } // иначе: если текущая цена (Bid) больше/равна дистанции текущий_стоплосс+расстояние трейлинга, else { if (Ask<(OrderStopLoss() - (trldist + MarketInfo(Symbol(),MODE_SPREAD))*Point)) newstop = Ask + trldist*Point; } // модифицируем стоплосс if (newstop>0) { if (((OrderStopLoss()==0) || (OrderStopLoss()>OrderOpenPrice())) && (newstop>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point)) { if (!OrderModify(ticket,OrderOpenPrice(),newstop,OrderTakeProfit(),OrderExpiration())) Print("Не удалось модифицировать стоплосс ордера №",OrderTicket(),". Ошибка: ",GetLastError()); } else { if ((newstop<OrderStopLoss()) && (newstop>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point)) { if (!OrderModify(ticket,OrderOpenPrice(),newstop,OrderTakeProfit(),OrderExpiration())) Print("Не удалось модифицировать стоплосс ордера №",OrderTicket(),". Ошибка: ",GetLastError()); } } } } }В первом советнике (где позы открываются по времени) добавляете эту функцию в самый конец (после return(0); } ). Потом в том же советнике чуть выше return(0) добавляете блок выбора ордера, и если ордер найден-запускаем функцию TrailingUdavka(). Приблизительно следующий:
int k=OrdersTotal(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol()==Symbol()) { if (OrderOpenTime()==_Open_Time) { TrailingUdavka(OrderTicket(),iTrl_dist_1,iLevel_1,iTrl_dist_2,iLevel_2,iTrl_dist_3); } } } }iTrl_dist_1,iLevel_1,iTrl_dist_2,iLevel_2,iTrl_dist_3 выносятся в настройки или сразу задаются в коде.
#7
Отправлено 26 May 2010 - 11:15
Вот так тогда смотрите. У меня немного другой код этого советника и переменные отличаютсяВроде все сделал как Вы написали, но почему-то выводит ошибки по коду.
/
int i,k=OrdersTotal(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol()==Symbol()) { if (OrderOpenTime()==Open_Time) { TrailingUdavka(OrderTicket(),iTrl_dist_1,iLevel_1,iTrl_dist_2,iLevel_2,iTrl_dist_3); } } } }
#8
Отправлено 26 May 2010 - 12:53
Прикрепленные файлы
#9
Отправлено 26 May 2010 - 14:03
#10
Отправлено 26 May 2010 - 14:05
Нет, точно не работает трал. Уважаемый Necron, проверте пожалуйста код. Может какие-нибудь ошибки?
Так посмотрите. Вроде ошибок трал не выдает. Я что-то с направлением сегодня определиться не могу, чтобы проверить аккуратно
Прикрепленные файлы
#11
Отправлено 26 May 2010 - 16:32
Так посмотрите. Вроде ошибок трал не выдает. Я что-то с направлением сегодня определиться не могу, чтобы проверить аккуратно
Дело в том, что трал ставит безубыток =0, и далее начинает переставлять стопы +1pips, хотя как я понимаю, из настроек по умолчанию, должен тралить- начинать работу, при достижении +30пипс и далее по уровням.
Для наглядности я приложил "результат"
#12
Отправлено 01 June 2010 - 01:58
Дело в том, что трал ставит безубыток =0, и далее начинает переставлять стопы +1pips, хотя как я понимаю, из настроек по умолчанию, должен тралить- начинать работу, при достижении +30пипс и далее по уровням.
Для наглядности я приложил "результат"
Прикрепленные файлы
#13
Отправлено 01 June 2010 - 20:47
#14
Отправлено 29 January 2013 - 11:27