Можете прислать кусок лога с самого момента запроса до момента получения ping failed (важно проверить таймауты)? И это на реальном или демо-счете?
Спасибо, будем разбираться.
Можете прислать кусок лога с самого момента запроса до момента получения ping failed (важно проверить таймауты)? И это на реальном или демо-счете?
Это на демо счете. Лог... Я закрыл и открыл МТ, так что запись в табе "журнал" обновилась. В следующий раз скопирую, потом перезапущусь, по ощущениям, это займет пару дней, я имею в виду повторение проблемы. Могу только предложить лог из директории experts\logs. Это то, что Вы имели в виду?
В account history этой сделке соответствует следующая строчка (кстати, почему в этом табе нет возможности построчного копирования в буффер?):
1728130 2005.08.31 15:00 buy 0.10 eurusd 1.2223 1.2183 0 2005.08.31 20:07 1.2330 0 107.00 Friday
Нахожусь я в Москве, это может быть нужно при анализе времени сделок.
Заметьте, что закрыта сделка экспертом в 20.07. На самом деле, условие закрытия наступило в 20.01, но позиция не закрылась. Я закрыл и открыл МТ, и в 20.07, то есть сразу же, в течение нескольких секунд после перезапуска позиция закрылась.
Сейчас посмотрел на лог (весь), но там 147 Кб. Если хотите, прицеплю, но поверьте на слово, по данной сделке там лишь две записи:
17:00:18 _Friday_Expert EURUSD,H1: open #1728130 buy 0.10 EURUSD at 1.2223 sl: 1.2183 ok
...
22:07:24 _Friday_Expert EURUSD,H1: close #1728130 buy 0.10 EURUSD at 1.2223 sl: 1.2183 at price 1.2330
То есть, попытки закрыть позицию в 20.01 вроде бы и не было. "Вроде бы" - потому, что а) в табе "журнал" (я не ожидал, что МТ его сбросит) появилась надпись насчет попытки пинга, и неудачи и б) поскольку это не первая проблема с данным экспертом, посмотрите, как он выглядит изнутри:
for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) { SaveComment("\r\n\t" + MathFloor(CurTime() / 3600) + " - " + MathFloor(OrderOpenTime() / 3600) + " >= " + nHoursToHold); int nCurHour = TimeHour(CurTime()); int nOrderOpenHour = TimeHour(OrderOpenTime()); if(nOrderOpenHour > nCurHour) nCurHour += 24; // if(MathFloor(CurTime() / 3600) - MathFloor(OrderOpenTime() / 3600) >= nHoursToHold) if(nCurHour - nOrderOpenHour >= nHoursToHold) { if(OrderType() == OP_BUY) { CloseBuy("Friday"); SaveComment(", nbuy closed"); } else if(OrderType() == OP_SELL) { CloseSell("Friday"); SaveComment(", sell closed"); } } } } ... void CloseBuy(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket); int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } } // ------ void CloseSell(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket); int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } } // ------
SaveComment просто пишет текст в файл.
Так вот, все подобающие попытке закрытия позиции записи в файле появились, а алерт - не был вызван, то есть OrderClose вернул код успешного завершения.
Ошибка бывает : ping failed в журнале.
Может быть, после того, как ping failed происходит, ваша система не должна позволять исполняться OrderSend, тогда бы генерировалось сообщение об ошибке.
В данном случае сообщения об ошибке нет, есть только запись в логе. Программа ведет себя, как если бы ей удалось закрыть сделку, вот только сделка не закрывается.
Итак, в журнале (Journal):
2005.09.05 16:01:35 TradeContext: ping failed
2005.09.05 16:01:35 TradeContext: ping error
2005.09.05 16:01:14 '142605': close order #1775545 sell 0.10 EURUSD at 1.2535 sl: 0.0000 tp: 0.0000 at price 1.2542
2005.09.05 16:01:14 '142605': login (4.00, #27FFBBD7)
Кстати, очень хотелось бы понять, почему sl: 0.0000, я-то не ноль передаю.
При этом, функция start имеет вид:
int start() { if(Bars < 5) return(0); Report("Friday", nMagic, bReportDone); // ------ if(!IsBarEnd()) return(0); CheckTradeSemaphore(); // ------ if(bUseMm == true) { dProfit = 0; for(int nCnt = 0; nCnt < HistoryTotal(); nCnt++) { OrderSelect(nCnt, SELECT_BY_POS, MODE_HISTORY); if(OrderMagicNumber() == nMagic && OrderType() <= OP_SELL) { dProfit += OrderProfit(); } } } int nSignal = GetSignal(); SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); switch(nSignal) { case -1: SaveComment(", Signal: none"); break; case OP_BUY: SaveComment(", Signal: buy"); break; case OP_SELL: SaveComment(", Signal: sell"); break; default: SaveComment(", Signal: ????"); break; } for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) { SaveComment("\r\n\t" + MathFloor(CurTime() / 3600) + " - " + MathFloor(OrderOpenTime() / 3600) + " >= " + nHoursToHold); int nCurHour = TimeHour(CurTime()); int nOrderOpenHour = TimeHour(OrderOpenTime()); if(nOrderOpenHour > nCurHour) nCurHour += 24; // if(MathFloor(CurTime() / 3600) - MathFloor(OrderOpenTime() / 3600) >= nHoursToHold) if(nCurHour - nOrderOpenHour >= nHoursToHold) { if(OrderType() == OP_BUY) { CloseBuy("Friday"); SaveComment(", buy closed"); } else if(OrderType() == OP_SELL) { CloseSell("Friday"); SaveComment(", sell closed"); } } } } int nNumOfOpenedOrders = 0; for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) nNumOfOpenedOrders++; } if(nNumOfOpenedOrders == 0) { if(nSignal == OP_BUY) { SaveComment("\r\n\tAsk: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit); Buy("Friday"); SaveComment("\r\n\tbuy opened"); } else if(nSignal == OP_SELL) { SaveComment("\r\n\tBid: " + Bid + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit); Sell("Friday"); SaveComment("\r\n\tsell opened"); } } SaveComment("\r\n"); // ------ // ModifyOrders(); // ------ if(!IsTesting()) GlobalVariableSet(strTradeSemaphore, 0.0); // ------ return(0); }
SaveComment - это функция для вывода строки в файл.
Вот вызываемая из start функция закрытия позиции. Как видно, она пытается закрыть позицию 5 раз (я это сделал только с целью тестирования), и если не возвращается код ошибки (то есть, МТ считает, что позиция закрыта), проводит среди все еще открытых ордеров поиск того, который имеет нужный тикет.
void CloseSell(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket); for(int nTry = 0; nTry < 5; nTry++) { int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else SaveComment("\r\n\tOrder with this ticket still present, trying again"); } }
В приведенном ниже логе видно, что все 5 попыток закрыть ордер провалились (тикет не исчез), при этом МТ считает, что позиция закрыта.
5.9.2005 14:1:29, Signal: none
312758.00000000 - 312754.00000000 >= 4
Attempting to close short position, ticket: 1775545
Order with this ticket still present, trying again
Order with this ticket still present, trying again
Order with this ticket still present, trying again
Order with this ticket still present, trying again
Order with this ticket still present, trying again, sell closed
Примечание: не пугайтесь "Signal: none" - так и должно быть. Это сигнал на открытие новой позиции, сигнал же на закрытие генерируется по выполнению неравенства "312758.00000000 - 312754.00000000 >= 4"
Уважаемые разработчики!
Очень надеюсь, что эту проблему мы сообща все-таки вылечим.
Кварк
П.С. Как обычно, перезапустив МТ, получаю закрытие позиции экспертом, без к.л. проблем.
Добавил код, пишущий результаты в файл при попытке открытия - закрытия сделки во все свои эксперты. Результат неутешительный. Примерно через раз, для всех экспертов, одной попытки открыть - закрыть ордер не хватает. В среднем, нужно две (см. код выше, там цикл из пяти попыток). Иногда не хватает и пяти. При этом МТ работает, как если бы ордер успешно открыт - закрыт, сообщений об ошибках не выдает.
Все семафоры, предложенные в ветке "Ошибка номер 6" (которая, кстати, по-прежнему иногда случается) я использую, плюс таймер экспертов гарантирует, что каждый эксперт запускается в свои, отведенные ему, 10 секунд, то есть, конфликтов между экспертами быть не должно.
Я предлагаю другим разработчикам использовать приведенный ниже код в работающих в реал тайме экспертах, дабы проверить, все ли ваши ордера отрабатывают так, как вы ожидаете. С точки зрения трейдинга, это всего лишь обычные OrderSend, окруженные функциями вывода в файл.
Не в обиду будет сказано, но кажется, в МТ надо отладить взаимодействие с торговым сервером.
double GetLotSize(double dInitFraction = 0.1, double dProfitFraction = 0.1) { double dLot = 0.1; if(bUseMm) { dLot = (dInitFraction * dInitAmount + dProfitFraction * dProfit) / 1000; dLot = MathFloor(dLot * 10) / 10; if(dLot < 0.1) dLot = 0.1; } return(dLot); } // ------ void Sell(string strExpertName) { dLotSize = GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Bid - dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment("Trying to sell, attempt " + nTry + "\r\n"); nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, dTp, strExpertName, nMagic, 0, OrangeRed); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else SaveComment(" failed, error " + GetLastError() + "\r\n"); } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); } } // ------ void Buy(string strExpertName) { dLotSize = GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Ask + dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment("Trying to buy, attempt " + nTry); nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, dTp, strExpertName, nMagic, 0, Aqua); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else SaveComment(" failed, error " + GetLastError() + "\r\n"); } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " buy error: " + nError + "\r\n" + Ask + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " buy error: " + nError + "\r\n" + Ask + ", " + dStopLoss + ", " + dTp); } } // ------ void CloseBuy(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket); for(int nTry = 0; nTry < 5; nTry++) { int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else SaveComment("\r\n\tOrder with this ticket still present, trying again"); } } // ------ void CloseSell(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket); for(int nTry = 0; nTry < 5; nTry++) { int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else SaveComment("\r\n\tOrder with this ticket still present, trying again"); } } // ------ void SaveComment(string strComment) { if(!IsTesting()) { int hFile = FileOpen("__test_" + strExpert + "_" + Symbol() + ".txt", FILE_BIN | FILE_READ | FILE_WRITE, '\t'); FileSeek(hFile, 0, SEEK_END); FileWriteString(hFile, strComment, StringLen(strComment)); // FileFlush(hFile); FileClose(hFile); } } // ------
Тогда нужно нащупать границу допустимого интервала на демо-счете.
С 00:00 до 12:00
сделок - 141
ошибок - 3 ("1", и две "6").
Quark, можешь мне в komposterius мыло ру кинуть последнюю глючную версию твоего эксперта (который на М1)? Я повешу ещё 8 окон - посмотрю, что получится ;)
Эксперты ждут (при помощи семафоров) очереди, более того, эксперт с маджик равным, например, 10, ждет 10 * 10 = 100 секунд с начала бара, и лишь потом торгует. Поэтому его шансы пересечься с экспертом с маджик 11 близки к 0 - даже без семафоров.
Впечатление таково, что если МТ один раз дал сбой (пинг не прошел, ошибка 6 вылезла и т.п.) то у него в системе что-то глобально сбивается, и последующие сделки данного эксперта сбоят.
Пример лога (код приведен выше):
Trying to buy, attempt 0 failed, error 6
Trying to buy, attempt 1 failed, error 129
Trying to buy, attempt 2 failed, error 129
Trying to buy, attempt 3 failed, error 129
Trying to buy, attempt 4 failed, error 129
Zigzag buy error: 4050
2.28000000, 0.02700000, 0.00000000
Что мы здесь имеем? Сначала произошол сбой (в журнале - ошибка соединения с сервером). Затем 5 попыток (у меня в цикле их 5) дают 129 - неверная цена. Ниже приведена цена - вполне нормальная. После перезапуска МТ по этой цене ордер успешно открылся. Затем - 4050, неверное число аргументов. Это у функции, которая нормально работает в других вызовах. Явный сбой системы сообщений об ошибках.
Привожу одного эксперта, хотя подозреваю, что надо иметь их много, для того, чтобы проблема возникала часто. Надеюсь, компостер, Рош и разработчики посмотрят на код и что-нибудь посоветуют. Все-таки, мне кажется, дело здесь в МТ.
Эксперт:
extern double dZigzagSize; extern int nMa1; extern int nMa2; extern int nBuySell; // ------ double dTrailingStop; double dStopLoss; double dTakeProfit; bool bUseMm = false; string strExpert = "Zigzag"; // ------ #include "mylib.mq4" // ------ int init () { nBars = 0;//Bars; if(!IsTesting() && !GlobalVariableCheck(strTradeSemaphore)) GlobalVariableSet(strTradeSemaphore, 0.0); // ------ if(IsTesting() && nMa1 >= nMa2) return(-1); if(Symbol() == "EURUSD" && Period() == 60) { if(!IsTesting()) { dZigzagSize = 210; // 210,60,108,3: 2397, 614 nMa1 = 48; // 210,48,120,1: 2016, 332 nMa2 = 120; nBuySell = 1; } nMagic = 23; } else if(Symbol() == "EURJPY" && Period() == 60) { if(!IsTesting()) { // 240,24,132,1: 1987, 387 dZigzagSize = 240; nMa1 = 24; nMa2 = 132; nBuySell = 3; } nMagic = 2; } else if(Symbol() == "USDCHF" && Period() == 60) { if(!IsTesting()) { // 260,36,204,2: 2219, 262 dZigzagSize = 260; nMa1 = 36; nMa2 = 204; nBuySell = 2; } nMagic = 3; } else if(Symbol() == "GBPUSD" && Period() == 60) { if(!IsTesting()) { // 270,48,84,3: 5515, 679 dZigzagSize = 270; nMa1 = 48; nMa2 = 84; nBuySell = 3; } nMagic = 4; } else if(Symbol() == "GBPCHF" && Period() == 60) { if(!IsTesting()) { // 270,96,108,1: 2854,292 dZigzagSize = 270; nMa1 = 96; nMa2 = 108; nBuySell = 1; } nMagic = 5; } else if(Symbol() == "USDCAD" && Period() == 60) { if(!IsTesting()) { // 220,60,300: 1906, 213 dZigzagSize = 220; nMa1 = 60; nMa2 = 300; nBuySell = 2; } nMagic = 7; } else if(Symbol() == "EURAUD" && Period() == 60) { if(!IsTesting()) { // 210,24,36,3: 3921, 545 dZigzagSize = 230; // 230,24,60,3: 3397, 453 nMa1 = 24; // 230,24,132,3: 2819, 292 nMa2 = 60; nBuySell = 3; } nMagic = 9; } dStopLoss = dZigzagSize * Point; dTrailingStop = dZigzagSize * Point; dTakeProfit = 0; return(0); } ////////////////// int deinit() { if(!IsTesting()) GlobalVariableSetOnCondition(strTradeSemaphore, 0.0, nMagic); return(0); } //////////////////// int start() { if(Bars < MathMax(nMa1, nMa2)) return(0); if(IsTesting() && nMa1 >= nMa2) return(0); Report("Zigzag", nMagic, bReportDone); // ------ if(!IsBarEnd()) return(0); CheckTradeSemaphore(); // ------ int nSignal = 0; double dMa1; double dMa2; nSignal = iCustom(NULL, 0, "_Zigzag_Ind", dZigzagSize, 0, 1); dMa1 = iMA(NULL, 0, nMa1, 0, MODE_EMA, PRICE_CLOSE, 1); dMa2 = iMA(NULL, 0, nMa2, 0, MODE_EMA, PRICE_CLOSE, 1); if(bUseMm == true) { dProfit = 0; for(int nCnt = 0; nCnt < HistoryTotal(); nCnt++) { OrderSelect(nCnt, SELECT_BY_POS, MODE_HISTORY); if(OrderMagicNumber() == nMagic && OrderType() <= OP_SELL) { dProfit += OrderProfit(); } } } for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) { int nMode = OrderType(); if(nMode == OP_BUY && nSignal == 1) { CloseBuy("Zigzag"); break; } else if(nMode == OP_SELL && nSignal == -1) { CloseSell("Zigzag"); break; } } } int nNumOfOpenedOrders = 0; for(nCnt = OrdersTotal() - 1; nCnt >= 0; nCnt--) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) nNumOfOpenedOrders++; } if(!nNumOfOpenedOrders) { if(nSignal == -1 && dMa1 >= dMa2) { if(nBuySell == 1 || nBuySell == 3) Buy("Zigzag"); } else if((nSignal == 1 && dMa1 <= dMa2)) { if(nBuySell == 2 || nBuySell == 3) Sell("Zigzag"); } } // ------ ModifyOrders(); // ------ if(!IsTesting()) GlobalVariableSet(strTradeSemaphore, 0.0); // ------ return(0); } // ------
Индикатор:
#property copyright "Quark" #property link "" #property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 Red #property indicator_minimum -1 #property indicator_maximum 1 // indicator parameters extern int nMinMaxPoints = 50; // indicator buffers double arrExtMapBuffer[]; int nExtCountedBars = 0; int nLastMinMaxBar; int nLastMinMaxType; double dLastMin, dLastMax; //////////////////////// int init() { string strIndicatorShortName; // drawing settings SetIndexStyle(0, DRAW_HISTOGRAM); SetIndexShift(0, 0); SetIndexEmptyValue(0,0.0); IndicatorDigits(4); strIndicatorShortName = "Zigzag(" + nMinMaxPoints + ")"; IndicatorShortName(strIndicatorShortName); // indicator buffers mapping SetIndexBuffer(0, arrExtMapBuffer); dLastMin = Low[Bars - 1]; dLastMax = High[Bars - 1]; nLastMinMaxBar = Bars - 1; nLastMinMaxType = 0; int nPos = Bars - 1; int nLastPos = nPos; while(nPos >= 0) // Looking for a first min or max { if(dLastMax <= High[nPos]) { dLastMax = High[nPos]; nLastMinMaxBar = nPos; } if(dLastMin >= Low[nPos]) { dLastMin = Low[nPos]; nLastMinMaxBar = nPos; } if(Low[nPos] < dLastMax - nMinMaxPoints * Point) // Maximum found { nLastMinMaxType = 1; dLastMin = Low[nPos]; dLastMax = High[nPos]; nLastMinMaxBar = nPos; break; } else if(High[nPos] > dLastMin + nMinMaxPoints * Point) // Minimum found { nLastMinMaxType = -1; dLastMax = High[nPos]; dLastMin = Low[nPos]; nLastMinMaxBar = nPos; break; } nPos--; } return(0); } //////////////////// int start() { nExtCountedBars = IndicatorCounted(); if(nExtCountedBars < 0) return(-1); // last counted bar will be recounted if(nExtCountedBars > 0) nExtCountedBars--; Zigzag(); return(0); } /////////////////// void Zigzag() { int nPos = Bars - nExtCountedBars - 2; while(nPos > 0) { arrExtMapBuffer[nPos] = 0.0; double dLastMaxTmp = dLastMax; double dLastMinTmp = dLastMin; if(nLastMinMaxType != 1) // Expecting maximum { if(dLastMax <= High[nPos]) { dLastMax = High[nPos]; nLastMinMaxBar = nPos; } if(Low[nPos] < dLastMax - nMinMaxPoints * Point) // Maximum found { if(High[nPos] - Low[nPos] <= nMinMaxPoints * Point) { arrExtMapBuffer[nPos] = 1;//High[nLastMinMaxBar]; nLastMinMaxType = 1; dLastMin = Low[nPos]; dLastMax = High[nPos]; nLastMinMaxBar = nPos; } else { arrExtMapBuffer[nPos] = 0; arrExtMapBuffer[nPos + 1] = 0; dLastMax = dLastMaxTmp; dLastMin = dLastMinTmp; } } } if(nLastMinMaxType != -1) // Expecting minimum { if(dLastMin >= Low[nPos]) { dLastMin = Low[nPos]; nLastMinMaxBar = nPos; } if(High[nPos] > dLastMin + nMinMaxPoints * Point) // Maximum found { if(High[nPos] - Low[nPos] <= nMinMaxPoints * Point) { arrExtMapBuffer[nPos] = -1;//Low[nLastMinMaxBar]; nLastMinMaxType = -1; dLastMax = High[nPos]; dLastMin = Low[nPos]; nLastMinMaxBar = nPos; } else { arrExtMapBuffer[nPos] = 0; arrExtMapBuffer[nPos + 1] = 0; dLastMax = dLastMaxTmp; dLastMin = dLastMinTmp; } } } nPos--; } } /////////////////// /* if(IsTesting()) { FileDelete("__zigzag_test.txt"); hFile = FileOpen("__zigzag_test.txt", FILE_BIN | FILE_WRITE, '\t'); } void SaveComment(string strComment) { if(IsTesting()) { FileWriteString(hFile, strComment, StringLen(strComment)); } } if(IsTesting()) FileClose(hFile); */
Библиотечный файл, должен лежать в директории экспертов:
double dTp = 0; //double dStop; datetime timePrev = 0; int nBars; int nDelaySeconds = 10; int nSlip = 5; double dProfit = 0; double dInitAmount = 1000; double dLotSize = 0.1; int nMagic = 0; bool bReportDone = false; string strTradeSemaphore = "TradeSemaphore"; // ------ void Report(string strFileName, int nMagic, bool& bReportDone) { if(IsTesting()) return; if(Hour() == 0 && Minute() >= nMagic / 2 && IsTesting() == false) { if(bReportDone == false) { int hFile = FileOpen(strFileName + "_" + Symbol() + "_" + Period() + ".rpt", FILE_BIN | FILE_WRITE, ','); string str = "CloseDateTime,Buy,Sell\r\n"; FileWriteString(hFile, str, StringLen(str)); for(int nCnt = 0; nCnt < HistoryTotal(); nCnt++) { OrderSelect(nCnt, SELECT_BY_POS, MODE_HISTORY); if(OrderMagicNumber() == nMagic && OrderType() <= OP_SELL && OrderSymbol() == Symbol()) { str = TimeToStr(OrderCloseTime(), TIME_DATE|TIME_MINUTES); if(OrderType() == OP_BUY) str = str + "," + OrderProfit() + ",0"; else str = str + ",0," + OrderProfit(); str = str + "\r\n"; FileWriteString(hFile, str, StringLen(str)); } } FileFlush(hFile); FileClose(hFile); bReportDone = true; } } else if(Hour() != 0) bReportDone = false; } // ------ double GetLotSize(double dInitFraction = 0.1, double dProfitFraction = 0.1) { double dLot = 0.1; if(bUseMm) { dLot = (dInitFraction * dInitAmount + dProfitFraction * dProfit) / 1000; dLot = MathFloor(dLot * 10) / 10; if(dLot < 0.1) dLot = 0.1; } return(dLot); } // ------ void Sell(string strExpertName) { dLotSize = GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Bid - dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); SaveComment(" Trying to sell, attempt " + nTry + "\r\n"); SaveComment("Ask: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit + "\r\n"); nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, dTp, strExpertName, nMagic, 0, OrangeRed); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else SaveComment(" failed, error " + GetLastError() + "\r\n"); } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); } } // ------ void Buy(string strExpertName) { dLotSize = GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Ask + dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); SaveComment(" Trying to buy, attempt " + nTry + "\r\n"); SaveComment("Bid: " + Bid + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit); nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, dTp, strExpertName, nMagic, 0, Aqua); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else SaveComment(" failed, error " + GetLastError() + "\r\n"); } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " buy error: " + nError + "\r\n" + Ask + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " buy error: " + nError + "\r\n" + Ask + ", " + dStopLoss + ", " + dTp); } } // ------ void ModifyOrders() { for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) { if(OrderType() == OP_BUY) { if(OrderStopLoss() < Bid - dTrailingStop - 5 * Point) { OrderModify(OrderTicket(), OrderOpenPrice(), Bid - dTrailingStop, OrderTakeProfit(), 0, Aqua); break; } } if(OrderType() == OP_SELL) { if(OrderStopLoss() > Ask + dTrailingStop + 5 * Point) { OrderModify(OrderTicket(), OrderOpenPrice(), Ask + dTrailingStop, OrderTakeProfit(), 0, OrangeRed); break; } } } } } // ------ /* void ModifyOrders(double dTrailingConvergence = 1) { for(int nCnt = 0; nCnt < OrdersTotal(); nCnt++) { OrderSelect(nCnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == nMagic) { if(dTrailingConvergence != 1) { dStop *= dTrailingConvergence; dStop = NormalizeDouble(dStop, MarketInfo(Symbol(), MODE_DIGITS)); if(dStop < 10 * Point) dStop = 10 * Point; } if(OrderType() == OP_BUY) { if(OrderStopLoss() < Bid - dStop - 5 * Point) { OrderModify(OrderTicket(), OrderOpenPrice(), Bid - dStop, OrderTakeProfit(), 0, Aqua); break; } } if(OrderType() == OP_SELL) { if(OrderStopLoss() > Ask + dStop + 5 * Point) { OrderModify(OrderTicket(), OrderOpenPrice(), Ask + dStop, OrderTakeProfit(), 0, OrangeRed); break; } } } } } */ // ------ bool IsBarEnd() { bool bIsBarEnd = false; if(nBars != Bars) { if(IsTesting() || (!IsTesting() && CurTime() > Time[0] + nMagic * nDelaySeconds)) { bIsBarEnd = true; nBars = Bars; } } return(bIsBarEnd); } // ------ void CheckTradeSemaphore() { if(!IsTesting()) { // int n = 1; while(!IsStopped()) { GlobalVariableSetOnCondition(strTradeSemaphore, nMagic, 0.0); // if(GlobalVariableGet(strTradeSemaphore) == 0.0) // GlobalVariableSet(strTradeSemaphore, nMagic); if(GlobalVariableGet(strTradeSemaphore) == nMagic) break; // Comment(GlobalVariableGet(strTradeSemaphore) + ": " + n); // n++; Sleep(1000); } RefreshRates(); } } // ------ /* void CloseBuy(string strExpertName) { int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + nError); } } // ------ void CloseSell(string strExpertName) { int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert("Noc_1 close: " + nError); } } */ // ------ void CloseBuy(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket + "\r\n"); for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else SaveComment("\r\n\tOrder with this ticket still present, trying again"); } } // ------ void CloseSell(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket + "\r\n"); for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else SaveComment("\r\n\tOrder with this ticket still present, trying again"); } } // ------ void SaveComment(string strComment) { if(!IsTesting()) { int hFile = FileOpen("__test_" + strExpert + "_" + Symbol() + ".txt", FILE_BIN | FILE_READ | FILE_WRITE, '\t'); FileSeek(hFile, 0, SEEK_END); FileWriteString(hFile, strComment, StringLen(strComment)); // FileFlush(hFile); FileClose(hFile); } } // ------
Пора разработчикам задуматься о вакансии для тебя в штате, чтобы ты им всякие пакости находил.
Возможно, дело в пинге, у меня нет циклов для повторной попытки выставления ордеров, может надо в этом месте Refresh вызывать и подсовывать более свежие цены.
Я теряюсь ...:)
Пора разработчикам задуматься о вакансии для тебя в штате, чтобы ты им всякие пакости находил.
Возможно, дело в пинге, у меня нет циклов для повторной попытки выставления ордеров, может надо в этом месте Refresh вызывать и подсовывать более свежие цены.
Я теряюсь ...:)
Хорошая мысль... Сейчас сделаю...
void Sell(string strExpertName) { dLotSize = GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Bid - dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); SaveComment(" Trying to sell, attempt " + nTry + "\r\n"); SaveComment("Ask: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit + "\r\n"); nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, dTp, strExpertName, nMagic, 0, OrangeRed); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else { SaveComment(" failed, error " + GetLastError() + "\r\n"); RefreshRates(); } } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); } } // ------ void Buy(string strExpertName) { dLotSize = GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Ask + dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); SaveComment(" Trying to buy, attempt " + nTry + "\r\n"); SaveComment("Bid: " + Bid + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit); nResult = OrderSend(Symbol(), OP_BUY, dLotSize, Ask, nSlip, Ask - dStopLoss, dTp, strExpertName, nMagic, 0, Aqua); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else { SaveComment(" failed, error " + GetLastError() + "\r\n"); RefreshRates(); } } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " buy error: " + nError + "\r\n" + Ask + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " buy error: " + nError + "\r\n" + Ask + ", " + dStopLoss + ", " + dTp); } } void CloseBuy(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close long position, ticket: " + nTicket + "\r\n"); for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); int nResult = OrderClose(OrderTicket(), OrderLots(), Bid, nSlip, Aqua); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); SaveComment(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else { SaveComment("\r\n\tOrder with this ticket still present, trying again"); RefreshRates(); } } } // ------ void CloseSell(string strExpertName) { int nTicket = OrderTicket(); SaveComment("\r\n\tAttempting to close short position, ticket: " + nTicket + "\r\n"); for(int nTry = 0; nTry < 5; nTry++) { SaveComment(Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); int nResult = OrderClose(OrderTicket(), OrderLots(), Ask, nSlip, OrangeRed); if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + ", error: " + nError); SaveComment(strExpertName + ", error: " + nError); } bool bClosed = true; for(int nOrderNo = OrdersTotal() - 1; nOrderNo >= 0; nOrderNo--) { OrderSelect(nOrderNo, SELECT_BY_POS, MODE_TRADES); if(OrderTicket() == nTicket) { bClosed = false; break; } } if(bClosed == true) { SaveComment("\r\n\tNo more orders with this ticket No"); break; } else { SaveComment("\r\n\tOrder with this ticket still present, trying again"); RefreshRates(); } } }
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Что это такое и как с ним бороться?
При перезапуске МТ (условие закрытия сделки все еще в силе) сделка закрывается успешно.
В логе никаких ошибок нет, вывод в файл, который я поставил буквально через строчку, показывает, что OrderSend СРАБОТАЛ, без ошибки, но вот беда: а) ордер в списке открытых остался и б) он закрылся при перезапуске МТ, значит был не только в списке, но и в реальности.
На случай, если Мета захочет сверить логи с Альпари, счет 142605, тикет 1728130
Надеюсь все-таки получить ответ, это не первое мое сообщение об этой ошибке.
С уважением,
Кварк