у Вас код некорректно ищет последний ордер, должно быть примерно так:
//_______________________________________________________________________ int LastfOrder(int magic_) { int i,k=OrdersHistoryTotal(); string sy=Symbol(); datetime t,lasttime=0; int ticket=-1; for(i=0; i<k; i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if((OrderMagicNumber()==magic_) && (OrderSymbol()==sy)) { t = OrderCloseTime(); if(t>lasttime) { lasttime= t; ticket = OrderTicket(); } } } } return(ticket); } //_______________________________________________________________________
искать нужно по времени закрытия ордера - самое большое время (для ордера с магиком и по символу инструмента) и будет временем закрытия последнего ордера
а в части решения Вашей задачи - в один проход по циклу перебора ордеров можно решить, но нужно в массив загнать время всех ордеров, затем этот массив отсортировать и последние 2 элемента массива и будут то, что Вы ищите, но затем придется сопоставить время и № тикета ордера (нет под рукой примера, я использовал структуру в которой сразу заполнял и время и тикеты)
или решайте в два прохода по циклу перебора ордеров - нашли самый последний ордер и ищите самый последний ордер еще раз и сравнивайте с найденным временем на == - если ==, то не запоминать
Всем привет! Столкнулся с проблемой... сделал робота, который читает историю и открывает сделку.. пример выглядит так: Закрылся ордер на продажу по тейку.. открывается новый ордер на продажу итд... Вопрос в том что если одновременно закроется 2 ордера, то откроется только 1 ордер, а не 2... Как прочитать эти последние 2 ордера, чтобы открылись новые 2?? Проблема выходит когда одновременно закрываются ордера... читает только 1 ордер вместо 2 или 3 одновременно закрывшихся!
Для начала нужно хотя бы попытаться прочесть больше одного ордера. Ведь итераций цикла с исполнением тела цикла всего одна - когда i = OrdersHistoryTotal() - 1. Первая итерация (когда i = OrdersHostoryTotal()) заведомо обречена на провал, т. к. элемента списка с таким индексом не существует. Таким образом, нужно хотя бы заголовок цикла подправить (здесь читается два последних ордера):
int nToIndex = OrdersHistoryTotal() - 2; for (int i = OrdersHistoryTotal() - 1; i >= nToIndex; i--)
Далее потребуется полностью менять подход к решению задачи. Ведь по результату выполнения цикла будет получено только одно значение - открыться в том же направлении или в противоположном. А раз требуется открытие нескольких ордеров, то и сигналов должно быть несколько. Навскидку, потребуется организация массива сигналов.
вот набросал скрипт, в теории должен работать - проверить не могу, на работе дежурю
#property strict #property show_inputs input int Magic = 1234567; void OnStart() { datetime t_order; int tickets[3]; t_order = TimeCurrent(); tickets[0] = LastfOrder(Magic,t_order); for(int i=1;i<3;i++){ tickets[i] = LastfOrder(Magic,t_order); } } //_______________________________________________________________________ int LastfOrder(int magic_,datetime &starttime_) { int i,k=OrdersHistoryTotal(); string sy=Symbol(); datetime t,lasttime=0; int ticket=-1; for(i=0; i<k; i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if((OrderMagicNumber()==magic_) && (OrderSymbol()==sy)) { t=OrderCloseTime(); if(t<starttime_) { if(t>lasttime) { lasttime=t; ticket=OrderTicket(); } } } } } starttime_ = lasttime; return(ticket); } //_______________________________________________________________________единственное, что меня смущает - это фраза, что несколько ордеров могут закрыться одновременно, тип datetime имеет дискретность 1сек, если этого недостаточно, тогда нужно сравнивать время закрытия ордеров на >= и потом с № тикетов еще сравнивать
вот набросал скрипт, в теории должен работать - проверить не могу, на работе дежурю
Больше всего нравится Starttime=Lasttime.
Больше всего нравится Starttime=Lasttime.
работать будет, не захотел переменные плодить, вот и вернул по ссылке время, если хотите то можете переписать в виде:
int LastfOrder(int magic_,datetime starttime_,datetime &lasttime) { lasttime=0; ....
можно еще и спросить почему ф-ция может возвращать и несуществующие тикеты ......
старался пример дать, вроде получилось
вот набросал скрипт, в теории должен работать - проверить не могу, на работе дежурю
единственное, что меня смущает - это фраза, что несколько ордеров могут закрыться одновременно, тип datetime имеет дискретность 1сек, если этого недостаточно, тогда нужно сравнивать время закрытия ордеров на >= и потом с № тикетов еще сравниватьСпасибо большое!!! Ваш скрипт работает. Я теперь не могу решить последний момент, это когда у меня по тейку закрылись 5 ордеров, соответственно у всех время закрытия одинаковое.. значит нужно прочесть последние 5 ордеров, если закрылись 5 по тейку одновременно..
{ datetime t_order; int tickets[3]; t_order = TimeCurrent(); tickets[0] = LastfOrder(Magic,t_order); for(int i=1;i<3;i++){ tickets[i] = LastfOrder(Magic,t_order); } }
Спасибо большое!!! Ваш скрипт работает. Я теперь не могу решить последний момент, это когда у меня по тейку закрылись 5 ордеров, соответственно у всех время закрытия одинаковое.. значит нужно прочесть последние 5 ордеров, если закрылись 5 по тейку одновременно..
ну решите эту задачу в 2 цикла перебора моим скриптом:
1. нашли самый последний закрытый ордер и запомните его время
2. ищите ордера со временем >= времени закрытия последнего ордера (можно и на знак == искать, но обычно лучше искать на сравнение чем на равенство)
ЗЫ: сложная у Вас задача... а не проще было бы все таки запоминать тикеты при открытии ордеров в массив, и потом по № тикетов анализировать закрытые ордера?
попробуйте так будет работать?
#property strict #property show_inputs input int Magic = 1234567; void OnStart() { datetime t_order; int tickets[5]; t_order = TimeCurrent(); tickets[0] = LastfOrder(Magic,t_order); for(int i=1;i<5;i++){ tickets[i] = LastfOrder(Magic,t_order,true); } } //_______________________________________________________________________ int LastfOrder(int magic_,datetime &starttime_,bool equally=false) { int i,k=OrdersHistoryTotal(); string sy=Symbol(); datetime t,lasttime=0; int ticket=-1; for(i=0; i<k; i++) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if((OrderMagicNumber()==magic_) && (OrderSymbol()==sy)) { t=OrderCloseTime(); if(t<starttime_ || (equally&&(t==starttime_ ))) { if(t>lasttime) { lasttime=t; ticket=OrderTicket(); } } } } } starttime_ = lasttime; return(ticket); } //_______________________________________________________________________
попробуйте так будет работать?
Не поможете с подобной ситуацией для советника, чтобы проверялись последние 4 открытых ордера? Если 4 ордера открыты одновременно то начиналось вычисление общего профита и далее закрытие.
//+------------------------------------------------------------------+ //| Советник, выставляет 4 ордера по 4м валютам | //+------------------------------------------------------------------+ #property strict //+------------------------------------------------------------------+ extern string SYMBOL1 = "EURUSD"; //первый символ, если не указан, то не выставляется extern string SYMBOL2 = "GBPUSD"; //второй символ, если не указан, то не выставляется extern string SYMBOL3 = "EURGBP"; //третий символ, если не указан, то не выставляется extern string SYMBOL4 = "GBPJPY"; //четвертый символ, если не указан, то не выставляется extern double LOT1 = 0.1; //лот первого инструмента extern double LOT2 = 0.1; //лот второго инструмента extern double LOT3 = 0.1; //лот третьего инструмента extern double LOT4 = 0.1; //лот четвертого инструмента extern int TYPE1 = OP_BUY; //тип ордера первого инструмента extern int TYPE2 = OP_SELL; //тип ордера второго инструмента extern int TYPE3 = OP_BUY; //тип ордера третьего инструмента extern int TYPE4 = OP_SELL; //тип ордера четвертого инструмента extern int Slippage = 30; //проскальзывание extern double obpr = 10; //Общий профит extern int Magic = 777888; //============================================================================ void start() { double pa1=0, pa2=0; int i; int p1=0,p2=0; for(i=OrdersTotal()-1; i>=0; i--) {//Проверяем профит if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==Magic) {//Подсчитываем общий профит if(p1<=2 && (OrderSymbol()==SYMBOL1 || OrderSymbol()==SYMBOL2)) {pa1=pa1+OrderProfit()+OrderSwap()+OrderCommission(); p1++;} if(p2<=2 && (OrderSymbol()==SYMBOL3 || OrderSymbol()==SYMBOL4)) {pa2=pa2+OrderProfit()+OrderSwap()+OrderCommission(); p2++;} } } if(pa1>=obpr) close_orders(1); //Закрываем две пары, если они в сумме >= общему профиту if(pa2>=obpr) close_orders(2); int s=0; for(i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==Magic) s++; } if(s>2) return; int Digit=(int)MarketInfo(SYMBOL1,MODE_DIGITS); double Poin=MarketInfo(SYMBOL1,MODE_POINT); double ASK=NormalizeDouble(MarketInfo(SYMBOL1,MODE_ASK),Digit); double BID=NormalizeDouble(MarketInfo(SYMBOL1,MODE_BID),Digit); if(SYMBOL1!="") { if(TYPE1==OP_BUY) { if(OrderSend(SYMBOL1,OP_BUY,LOT1,ASK,Slippage,0,0,"1й_ордер",Magic,0,Blue)!=-1) Alert("Ордер BUY лот ",LOT1," ",SYMBOL1); else Alert(SYMBOL1," send order BAY error ",GetLastError()," ",MarketInfo(SYMBOL1,MODE_ASK)," ",LOT1); } if(TYPE1==OP_SELL) { if(OrderSend(SYMBOL1,OP_SELL,LOT1,BID,Slippage,0,0,"1й_ордер",Magic,0,Blue)!=-1) Alert("Ордер SELL лот ",LOT1," ",SYMBOL1); else Alert(SYMBOL1," send order SELL error ",GetLastError()," ",MarketInfo(SYMBOL1,MODE_ASK)," ",LOT1); } } if(SYMBOL2!="") { Digit=(int)MarketInfo(SYMBOL2,MODE_DIGITS); Poin=MarketInfo(SYMBOL2,MODE_POINT); ASK=NormalizeDouble(MarketInfo(SYMBOL2,MODE_ASK),Digit); BID=NormalizeDouble(MarketInfo(SYMBOL2,MODE_BID),Digit); if(TYPE2==OP_BUY) { if(OrderSend(SYMBOL2,OP_BUY,LOT2,ASK,Slippage,0,0,"2й_ордер",Magic,0,Blue)!=-1) Alert("Ордер BUY лот ",LOT2," ",SYMBOL2); else Alert(SYMBOL2," send order BAY error ",GetLastError()," ",MarketInfo(SYMBOL2,MODE_ASK)," ",LOT2); } if(TYPE2==OP_SELL) { if(OrderSend(SYMBOL2,OP_SELL,LOT2,BID,Slippage,0,0,"2й_ордер",Magic,0,Blue)!=-1) Alert("Ордер SELL лот ",LOT2," ",SYMBOL2); else Alert(SYMBOL2," send order SELL error ",GetLastError()," ",MarketInfo(SYMBOL2,MODE_ASK)," ",LOT2); } } if(SYMBOL3!="") { Digit=(int)MarketInfo(SYMBOL3,MODE_DIGITS); Poin=MarketInfo(SYMBOL3,MODE_POINT); ASK=NormalizeDouble(MarketInfo(SYMBOL3,MODE_ASK),Digit); BID=NormalizeDouble(MarketInfo(SYMBOL3,MODE_BID),Digit); if(TYPE3==OP_BUY) { if(OrderSend(SYMBOL3,OP_BUY,LOT3,ASK,Slippage,0,0,"3й_ордер",Magic,0,Blue)!=-1) Alert("Ордер BUY лот ",LOT3," ",SYMBOL3); else Alert(SYMBOL3," send order BAY error ",GetLastError()," ",MarketInfo(SYMBOL3,MODE_ASK)," ",LOT3); } if(TYPE3==OP_SELL) { if(OrderSend(SYMBOL3,OP_SELL,LOT3,BID,Slippage,0,0,"3й_ордер",Magic,0,Blue)!=-1) Alert("Ордер SELL лот ",LOT3," ",SYMBOL3); else Alert(SYMBOL3," send order SELL error ",GetLastError()," ",MarketInfo(SYMBOL3,MODE_ASK)," ",LOT3); } } if(SYMBOL4!="") { Digit=(int)MarketInfo(SYMBOL4,MODE_DIGITS); Poin=MarketInfo(SYMBOL4,MODE_POINT); ASK=NormalizeDouble(MarketInfo(SYMBOL4,MODE_ASK),Digit); BID=NormalizeDouble(MarketInfo(SYMBOL4,MODE_BID),Digit); if(TYPE4==OP_BUY) { if(OrderSend(SYMBOL4,OP_BUY,LOT4,ASK,Slippage,0,0,"4й_ордер",Magic,0,Blue)!=-1) Alert("Ордер BUY лот ",LOT4," ",SYMBOL4); else Alert(SYMBOL4," send order BAY error ",GetLastError()," ",MarketInfo(SYMBOL4,MODE_ASK)," ",LOT4); } if(TYPE4==OP_SELL) { if(OrderSend(SYMBOL4,OP_SELL,LOT4,BID,Slippage,0,0,"4й_ордер",Magic,0,Blue)!=-1) Alert("Ордер SELL лот ",LOT4," ",SYMBOL4); else Alert(SYMBOL4," send order SELL error ",GetLastError()," ",MarketInfo(SYMBOL4,MODE_ASK)," ",LOT4); } } return; } //===================================================================== void close_orders(int para) { bool err; int p1=0, p2=0; //удаляем только два последних ордера for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==Magic) { if(p1<=2 && para==1 && (OrderSymbol()==SYMBOL1 || OrderSymbol()==SYMBOL2)) { if(OrderType()==OP_BUY) err=OrderClose(OrderTicket(),OrderLots(), Bid, 30,clrNONE); if(OrderType()==OP_SELL) err=OrderClose(OrderTicket(),OrderLots(), Ask, 30,clrNONE); p1++; } if(p2<=2 && para==2 && (OrderSymbol()==SYMBOL3 || OrderSymbol()==SYMBOL4)) { if(OrderType()==OP_BUY) err=OrderClose(OrderTicket(),OrderLots(), Bid, 30,clrNONE); if(OrderType()==OP_SELL) err=OrderClose(OrderTicket(),OrderLots(), Ask, 30,clrNONE); p2++; } } } return; }
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Всем привет! Столкнулся с проблемой... сделал робота, который читает историю и открывает сделку.. пример выглядит так: Закрылся ордер на продажу по тейку.. открывается новый ордер на продажу итд... Вопрос в том что если одновременно закроется 2 ордера, то откроется только 1 ордер, а не 2... Как прочитать эти последние 2 ордера, чтобы открылись новые 2?? Проблема выходит когда одновременно закрываются ордера... читает только 1 ордер вместо 2 или 3 одновременно закрывшихся!