В этом случае торговый сервер сам безусловно отдает реквот даже без транслировании заявки дилеру. То есть, сервер получает устаревшую цену в торговой заявке и говорит клиенту:
А чем дополнить код, что-б на такой "ответ сервера" всё равно
открыть?
пример плиз...
И что правильней использовать:
- макс. 5 пип или 2*спред
А чем дополнить код, что-б на такой "ответ сервера" всё равно
открыть?
пример плиз...
И что правильней использовать:
- макс. 5 пип или 2*спред
Уточню, что речь идет именно об Instant Execution запросах и не касается срабатывания отложенных ордеров или стопов на гепах.
Понятно, значит следует указывать отклонение цены не больше 10 пунктов. И обрабатывать код ошибки который возвращает OrderSend
Если код ошибки означает что ордер не открылся (или закрылся) из-за того что цена ушла от запрашиваемой больше 5 пунктов
и предложена новая цена, то попытаться открыть на следующем тике (или закрыть позицию).
А чем дополнить код, что-б на такой "ответ сервера" всё равно открыть?
пример плиз...
Рекомендую свою функцию. Общий срок разработки этой функции - более двух лет. Так что она проверена на многочисленных демо-счетах и само собой на реальных.
//+----------------------------------------------------------------------------+ //| Открытие позиции | //| Параметры: | //| sy - наименование инструмента (NULL - текущий символ) | //| op - операция | //| ll - лот | //| sl - уровень стоп | //| tp - уровень тейк | //| mn - MagicNumber | //+----------------------------------------------------------------------------+ void OpenPosition(string sy, int op, double ll, double sl=0, double tp=0, int mn=0) { color clOpen; double pp, pAsk, pBid; int dg, err, it, ticket; string lsComm=WindowExpertName()+" "+GetNameTF(Period()); if (sy=="" || sy=="0") sy=Symbol(); if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell; for (it=1; it<=NumberOfTry; it++) { if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while (!IsTradeAllowed()) Sleep(5000); RefreshRates(); dg=MarketInfo(sy, MODE_DIGITS); pAsk=MarketInfo(sy, MODE_ASK); pBid=MarketInfo(sy, MODE_BID); if (op==OP_BUY) pp=pAsk; else pp=pBid; pp=NormalizeDouble(pp, dg); ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, 0, clOpen); if (ticket>0) { if (UseSound) PlaySound(NameFileSound); break; } else { err=GetLastError(); if (err==128 || err==142 || err==143) { Sleep(1000*75); if (ExistPositions(sy, op, mn)) { if (UseSound) PlaySound(NameFileSound); break; } } // Вывод сообщения об ошибке Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it); Print("Ask=",pAsk," Bid=",pBid," sy=",sy," ll=",ll," op=",GetNameOP(op), " pp=",pp," sl=",sl," tp=",tp," mn=",mn); if (pAsk==0 && pBid==0) Message("Проверьте в Обзоре рынка наличие символа "+sy); // Реакция на ошибку if (err==2 || err==64 || err==65 || err==133) { gbDisabled=True; break; } if (err==4 || err==131 || err==132) { Sleep(1000*300); break; } if (err==140 || err==148 || err==4110 || err==4111) break; if (err==141) Sleep(1000*100); if (err==145) Sleep(1000*10); if (err==146) while (IsTradeContextBusy()) Sleep(1000*11); if (err!=135) Sleep(1000*10); } } }
Дополнительные необходимые функции
//+----------------------------------------------------------------------------+ //| Возвращает флаг существования позиций | //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любая позиция) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ bool ExistPositions(string sy="", int op=-1, int mn=-1) { int i, k=OrdersTotal(); if (sy=="0") sy=Symbol(); for (i=0; i<k; i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol()==sy || sy=="") { if (OrderType()==OP_BUY || OrderType()==OP_SELL) { if (op<0 || OrderType()==op) { if (mn<0 || OrderMagicNumber()==mn) return(True); } } } } } return(False); } //+----------------------------------------------------------------------------+ //| Возвращает наименование торговой операции | //| Параметры: | //| op - идентификатор торговой операции | //+----------------------------------------------------------------------------+ string GetNameOP(int op) { switch (op) { case OP_BUY : return("Buy"); case OP_SELL : return("Sell"); case OP_BUYLIMIT : return("Buy Limit"); case OP_SELLLIMIT: return("Sell Limit"); case OP_BUYSTOP : return("Buy Stop"); case OP_SELLSTOP : return("Sell Stop"); default : return("Unknown Operation"); } } //+----------------------------------------------------------------------------+ //| Возвращает наименование таймфрейма | //| Параметры: | //| TimeFrame - таймфрейм (количество секунд) (0 - текущий ТФ) | //+----------------------------------------------------------------------------+ string GetNameTF(int TimeFrame=0) { if (TimeFrame==0) TimeFrame=Period(); switch (TimeFrame) { case PERIOD_M1: return("M1"); case PERIOD_M5: return("M5"); case PERIOD_M15: return("M15"); case PERIOD_M30: return("M30"); case PERIOD_H1: return("H1"); case PERIOD_H4: return("H4"); case PERIOD_D1: return("Daily"); case PERIOD_W1: return("Weekly"); case PERIOD_MN1: return("Monthly"); default: return("UnknownPeriod"); } }
И что правильней использовать:
- макс. 5 пип или 2*спред
Я использую 3 пункта. Максимальное проскальзывание, с каким я встречался на спокойном рынке на реальном счёте - это 7 пунктов (это было один раз за два года реальной торговли на двух счетах).
Игорь, спасибо!
Ни на йоту не сомневаюсь в отработке кода временем. ;)))
Тут нечто другое, точнее другая плоскость.
Начну от Адама...
Мне без разницы по какой цене откроется позиция! если я решил её открыть...
(как и заметил выше Ренат, это для исполнения ИЕ)
Посему был уверен что слиппаж в моих скриптах 100 пип позволит мне открыть
любой скачек на любой болтанке, будь то 1 пип или 10 или даже 50, не суть...
Главное открыться! :)
Мне точность "скока вешать в граммах" в 99% случаев не нужна.
Вот почему и спросил, как и чем дополнить код простого, например этого скрипта:
// Скрипт для окрытия BUY #property show_inputs extern double lots=1.0; extern int StopLoss=100; extern int TakeProfit=100; void start() { int ticket; double loss=0; if(StopLoss>0) loss=Ask-StopLoss*Point; double profit=0; if(TakeProfit>0) profit=Ask+StopLoss*Point; ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,100,loss,profit,"",0,0,CLR_NONE); if (ticket<1) Print ("Error = ",GetLastError()); } //-----------------------------------------------------------+Тем самым приблизив исполнение по ИЕ к исполнению по "by market" . ..
Мне точность "скока вешать в граммах" в 99% случаев не нужна.
Вот почему и спросил, как и чем дополнить код простого, например этого скрипта:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Вот я при открытии позиции делаю обновленеи котировок. То есть использую саму актульную цену в терминале
RefreshRates();
И говорю что допустимое отклонение от запрашиваемой актуальной цены Ask будет 500 пунктов:
PosTicket = OrderSend(Symbol(), OP_BUY, NormalizeDouble(PosLots, 2), Ask, 500, 0, 0, Comments, PosId, 0, Green);
Однака бывают случаи, что позиции всё равно не открываются(когда активное движенеи цен). Это что реквоты такие что не находится цена от моей запрашиваемой отличающаяся на 500 пунктов.
Или я не правильно понимаю механизм реквотирования и исполнения приказов?