Pouvez-vous envoyer un morceau du journal à partir du moment où la demande est faite jusqu'à la réception de l'échec du ping (il est important de vérifier les délais d'attente) ? Et est-ce sur un compte réel ou de démonstration ?
Ceci est sur un compte de démonstration. Log... J'ai fermé et ouvert MT, donc l'entrée de l'onglet "log" a été mise à jour. Je vais le copier la prochaine fois, puis le redémarrer, j'ai l'impression que cela va prendre quelques jours, je veux dire une récurrence du problème. Je ne peux que suggérer un journal du répertoire experts\logs. C'est ce que vous aviez à l'esprit ?
Dans l'historique du compte, cette transaction correspond à la ligne suivante (au fait, pourquoi n'y a-t-il pas de copie ligne par ligne vers le tampon dans cet onglet ?)
1728130 2005.08.31 15:00 acheter 0.10 eurusd 1.2223 1.2183 0 2005.08.31 20:07 1.2330 0 107.00 Vendredi
Je suis à Moscou, cela peut être nécessaire dans l'analyse des temps de transaction.
Notez que le conseiller expert a fermé la transaction à 20 h 07. En fait, la condition de clôture était à 20 h 01, mais la position n'a pas été fermée. J'ai fermé et ouvert MT, et à 20.07, c'est-à-dire immédiatement, dans les secondes qui suivent le redémarrage de la position fermée.
J'ai maintenant regardé le journal (tout le journal), mais il fait 147Kb. Je vous le joins si vous voulez, mais croyez-moi, il n'y a que deux entrées pour cette transaction :
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
Il semble donc qu'il n'y ait pas de tentative de fermeture de la position à 20.01. "En quelque sorte" parce que a) l'onglet "log" (je ne m'attendais pas à ce que MT le réinitialise) montrait une note sur la tentative et l'échec du ping et b) comme ce n'est pas le premier problème avec cette EA, voyez à quoi elle ressemble de l'intérieur :
.
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 écrit simplement du texte dans un fichier.
Ainsi, toutes les entrées du fichier qui étaient appropriées pour la tentative de fermeture de la position sont apparues, mais l'alerte n'a pas été appelée, c'est-à-dire que OrderClose a renvoyé le code de réussite.
Il y a une erreur : ping failed dans le journal.
Peut-être qu'après l'échec d'un ping, votre système ne devrait pas permettre l'exécution de OrderSend, un message d'erreur serait alors généré.
Dans ce cas, il n'y a pas de message d'erreur, seulement une entrée dans le journal. Le programme se comporte comme s'il avait réussi à clôturer la transaction, mais celle-ci n'est pas clôturée.
Donc, dans le 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' : ordre de clôture #1775545 sell 0.10 EURUSD at 1.2535 sl : 0.0000 tp : 0.0000 au prix de 1.2542
2005.09.05 16:01:14 '142605' : login (4.00, #27FFBBD7)
Au fait, je me demande vraiment pourquoi sl : 0.0000, je n'envoie pas de zéro.
Dans le même temps, la fonction de démarrage ressemble à ceci :
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 est une fonction qui permet de sortir la chaîne de caractères dans un fichier.
Voici la fonction de position fermée appelée depuis le début. Comme vous pouvez le voir, il essaie de fermer la position 5 fois (je l'ai fait uniquement à des fins de test), et si aucun code d'erreur n'est renvoyé (c'est-à-dire que MT pense que la position est fermée), il recherche parmi les ordres encore ouverts celui qui a le ticket requis.
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"); } }
Le journal ci-dessous montre que les 5 tentatives de fermeture d'un ordre ont échoué (le ticket n'a pas disparu), MT croyant que la position est fermée.
5.9.2005 14:1:29, Signal : none
312758.00000000 - 312754.00000000 >= 4
Tentative de clôture d'une position courte, ticket : 1775545
Ordre avec ce ticket toujours présent, réessayer
Ordre avec ce ticket toujours présent, réessayer
Ordre avec ce ticket toujours présent, réessayer
Ordre avec ce ticket toujours présent, réessayer, vente fermée
Note : n'ayez pas peur du "Signal : none" - il devrait être comme ceci. Il s'agit d'un signal pour ouvrir une nouvelle position. Le signal pour fermer une position est généré si l'inégalité "312758.00000000 - 312754.00000000 >= 4" est respectée,
Chers développeurs !
J'espère vraiment que nous parviendrons à résoudre ce problème ensemble.
Quark
P.S. Comme d'habitude, après avoir redémarré MT, j'obtiens la fermeture de la position par expert, sans problème de k.l..
Ajout d'un code écrivant les résultats dans un fichier lorsque j'essaie d'ouvrir - fermer une transaction dans tous mes EAs. Le résultat est décevant. A peu près à chaque fois, pour tous les EAs, une seule tentative d'ouverture - fermeture d'un ordre n'est pas suffisante. En moyenne, il en faut deux (voir le code ci-dessus, il y a un cycle de cinq tentatives). Parfois, cinq tentatives ne suffisent pas. En même temps, MT fonctionne comme si l'ordre était ouvert - fermé avec succès, aucun message d'erreur n'est donné.
Tous les sémaphores suggérés dans la branche "Erreur numéro 6" (qui, soit dit en passant, se produit encore parfois), je les utilise, plus le timer des Expert Advisors qui garantit que chaque EA démarre dans les 10 secondes qui lui sont dédiées, c'est-à-dire qu'il ne devrait pas y avoir de conflits entre les EAs.
Je suggère aux autres développeurs d'utiliser le code ci-dessous dans des EAs en direct pour vérifier si tous vos ordres fonctionnent comme vous le souhaitez. D'un point de vue commercial, il s'agit simplement d'un OrderSend normal, entouré de fonctions de sortie vers un fichier.
Sans vouloir vous offenser, il semble que MT doive affiner l'interaction avec le serveur de commerce.
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); } } // ------
Je dois ensuite trouver la limite de l'intervalle autorisé sur le compte de démonstration.
De 00:00 à 12:00
métiers - 141
3 erreurs ("1" et deux "6").
Quark, pouvez-vous me jeter dans l'email komposterius ru la dernière version glitchy de votre EA (qui est sur M1) ? Je vais accrocher 8 fenêtres de plus - voir ce qui se passe ;)
Les experts attendent (à l'aide de sémaphores) pour une file d'attente, de plus, l'EA dont le nombre magique est égal à, par exemple, 10, attend 10 * 10 = 100 secondes à partir du début d'une barre, et ce n'est qu'ensuite qu'il effectue des transactions. Par conséquent, les chances de rencontrer un EA avec magic 11 sont proches de 0, même sans sémaphores.
L'impression est que si MT échoue une fois (ping failed, error 6, etc.), quelque chose ne va pas dans son système et les transactions suivantes de cet EA échouent.
Exemple de journal (code affiché ci-dessus) :
Essayer d'acheter, la tentative 0 a échoué, erreur 6
Essayer d'acheter, tentative 1 a échoué, erreur 129
Essayer d'acheter, tentative 2 a échoué, erreur 129
Essayer d'acheter, tentative 3 a échoué, erreur 129
Essayer d'acheter, tentative 4 a échoué, erreur 129
Erreur d'achat en zigzag : 4050
2.28000000, 0.02700000, 0.00000000
Qu'avons-nous là ? Il y a d'abord eu un échec (dans le journal - erreur de connexion avec le serveur). Ensuite, 5 tentatives (j'en ai 5 dans ma boucle) donnent 129 - mauvais prix. Le prix est en dessous - tout à fait normal. Après avoir redémarré MT à ce prix, l'ordre a été ouvert avec succès. Ensuite, nous obtenons 4050, le mauvais nombre d'arguments. Il s'agit d'une fonction qui fonctionne bien dans d'autres appels. Il y a une défaillance manifeste du système de signalement des erreurs.
Je cite un expert, mais je pense qu'il faut en avoir beaucoup pour que le problème soit fréquent. Espérons que le compositeur, Roche et les développeurs examineront le code et donneront leur avis. Quand même, je pense que c'est une question de MT ici.
Expert :
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); } // ------
Indicateur :
#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); */
Le fichier de la bibliothèque, doit se trouver dans le répertoire Expert :
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); } } // ------
Il est temps pour les développeurs de réfléchir à un travail pour vous au sein du personnel pour leur trouver toutes sortes de méchancetés.
Peut-être que c'est le ping, je n'ai pas de cycles pour réessayer de passer des commandes, peut-être que je devrais appeler Refresh à ce stade et profiter de prix plus frais.
Je me perds... :)
Peut-être que c'est le ping, je n'ai pas de cycles pour réessayer de passer des commandes, peut-être que je dois appeler Refresh à ce stade et mettre en place des prix plus frais.
Je suis en train de me perdre... :)
Bonne idée... Je vais le faire maintenant...
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(); } } }
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation
Qu'est-ce que c'est et comment y remédier ?
Lorsque vous redémarrez MT (la condition de clôture est toujours valable), l'opération se termine avec succès.
Il n'y a pas d'erreurs dans le journal, la sortie dans le fichier, que j'ai mis littéralement en travers d'une ligne, montre que OrderSend a fonctionné, sans erreur, mais voici le problème : a) l'ordre dans la liste des ouverts est resté et b) il s'est fermé au redémarrage de MT, donc il n'était pas seulement dans la liste, mais aussi dans la réalité.
Au cas où Meta voudrait réconcilier les logs avec Alpari, compte 142605, ticket 1728130
J'espère obtenir encore une réponse, ce n'est pas mon premier post sur cette erreur.
Salutations,
Quark