Hier ist die .cpp-Datei des Projekts, schauen Sie es sich an, und nach ein paar Google- und Yandex-Suchen habe ich überhaupt nichts Gescheites gefunden, es ist allgemein verständlich. Es scheint sogar einfach zu sein.
//+------------------------------------------------------------------+//| Sample DLL for MQL4 |//| Copyright 2001-2012, MetaQuotes Software Corp. |//| http://www.metaquotes.net |//+------------------------------------------------------------------+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
//---#define MT4_EXPFUNC __declspec(dllexport) //это что?//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+#pragma pack(push,1)
struct RateInfo // Структура, переменные
{
unsigned int ctm;
double open;
double low;
double high;
double close;
double vol;
};
#pragma pack(pop)
//---struct MqlStr
{
int len;
char *string// Указатель на стринг, я плохо помню.
};
staticint CompareMqlStr(constvoid *left,constvoid *right);
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)//функция
{
//---switch(ul_reason_for_call) // оператор что делать
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH: //что это всюду, не понял.break;
}
//---return(TRUE);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall GetIntValue(constint ipar) // __stdcall кладет аргументы в стек справа налево
{ // MT4_EXPFUNC говорит что функция будет видима из метатрайдера, я не совсем понял.printf("GetIntValue takes %d\n",ipar);
return(ipar);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetDoubleValue(constdouble dpar)
{
printf("GetDoubleValue takes %.8lf\n",dpar);
return(dpar);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC char* __stdcall GetStringValue(char *spar)
{
printf("GetDoubleValue takes \"%s\"\n",spar);
return(spar);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetArrayItemValue(constdouble *arr,constint arraysize,constint nitem)
{
//---if(arr==NULL)
{
printf("GetArrayItemValue: NULL array\n");
return(0.0);
}
if(arraysize<=0)
{
printf("GetArrayItemValue: wrong arraysize (%d)\n", arraysize);
return(0.0);
}
if(nitem<0 || nitem>=arraysize)
{
printf("GetArrayItemValue: wrong item number (%d)\n", nitem);
return(0.0);
}
//---return(arr[nitem]);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC BOOL __stdcall SetArrayItemValue(double *arr,constint arraysize,constint nitem,constdouble value)
{
//---if(arr==NULL)
{
printf("GetArrayItemValue: NULL array\n");
return(FALSE);
}
if(arraysize<=0)
{
printf("GetArrayItemValue: wrong arraysize (%d)\n", arraysize);
return(FALSE);
}
if(nitem<0 || nitem>=arraysize)
{
printf("GetArrayItemValue: wrong item number (%d)\n", nitem);
return(FALSE);
}
//---
arr[nitem]=value;
return(TRUE);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetRatesItemValue(const RateInfo* rates,constint rates_total,constint shift,constint nrate)
{
//---if(rates==NULL)
{
printf("GetRatesItemValue: NULL array\n");
return(0.0);
}
//---if(rates_total<0)
{
printf("GetRatesItemValue: wrong rates_total number (%d)\n", rates_total);
return(0.0);
}
//---if(shift<0 || shift>=rates_total)
{
printf("GetRatesItemValue: wrong shift number (%d)\n", shift);
return(0.0);
}
//---if(nrate<0 || nrate>5)
{
printf("GetRatesItemValue: wrong rate index (%d)\n", nrate);
return(0.0);
}
//---int nitem=rates_total-1-shift;
switch(nrate)
{
case0: returndouble(rates[nitem].ctm);
case1: return rates[nitem].open;
case2: return rates[nitem].low;
case3: return rates[nitem].high;
case4: return rates[nitem].close;
case5: return rates[nitem].vol;
}
//---return(0.0);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall SortStringArray(MqlStr *arr,constint arraysize)
{
//---if(arr==NULL)
{
printf("SortStringArray: NULL array\n");
return(-1);
}
if(arraysize<=0)
{
printf("SortStringArray: wrong arraysize (%d)\n", arraysize);
return(-1);
}
//---
qsort(arr,arraysize,sizeof(MqlStr),CompareMqlStr);
//---return(arraysize);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall ProcessStringArray(MqlStr *arr,constint arraysize)
{
int len1,len2;
//---if(arr==NULL)
{
printf("ProcessStringArray: NULL array\n");
return(-1);
}
if(arraysize<=0)
{
printf("ProcessStringArray: wrong arraysize (%d)\n", arraysize);
return(-1);
}
//---for(int i=0; i<arraysize-1; i++)
{
if(arr[i].string==NULL) len1=0;
else len1=strlen(arr[i].string);
if(arr[i+1].string==NULL) len2=0;
else len2=strlen(arr[i+1].string);
//--- uninitialized stringif(arr[i+1].string==NULL) continue;
//--- destination string is uninitialized and cannot be allocated within dllif(arr[i].string==NULL) continue;
//--- memory piece is less than needed and cannot be reallocated within dllif(arr[i].len<len1+len2) continue;
//--- final processing
strcat(arr[i].string,arr[i+1].string);
}
//---return(arraysize);
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+int CompareMqlStr(constvoid *left,constvoid *right)
{
MqlStr *leftstr=(MqlStr *)left;
MqlStr *rightstr=(MqlStr *)right;
//---if(leftstr->string==NULL) return(-1); //-> вот этот знак я не знаюif(rightstr->string==NULL) return(1);
//---return(strcmp(leftstr->string,rightstr->string));
}
//+------------------------------------------------------------------+
Aber wie funktioniert das? Ich bin mir nicht ganz sicher, wie man auf diese ddl verweisen - aus dem Code des EA? Wie? Zunächst sieht es so aus: #include <GetIntValue>.
2. Wenn man die DLL aufruft, muss man das Studio nicht eingeschaltet lassen, oder? wie wird es ausgeführt?
Bitte zeigen Sie das einfachste Beispiel für den Aufruf dieser DLL aus dem MQL-Code.
Ich habe eine weitere Frage: Ich habe einen Auftrag im Nachlauf. Wenn 1 unidirektionaler Auftrag offen ist, funktioniert alles gut, wenn mehr, funktioniert es aus irgendeinem Grund nicht. Und warum?
Hier ist die .cpp-Datei des Projekts, schauen Sie es sich an, und nach ein paar Google- und Yandex-Suchen habe ich überhaupt nichts Gescheites gefunden, es ist allgemein verständlich. Es scheint sogar einfach zu sein.
Aber wie funktioniert das? Ich bin nicht ganz sicher, wie man auf diese ddl verweisen - aus dem Code des EA? Wie? Zunächst sieht es so aus: #include <GetIntValue>.
Das ist ungefähr so. Damit es funktioniert, müssen Sie die dll kompilieren und im Ordner experts/libraries ablegen (lesen Sie die Hilfe und das Tutorial, dort ist es ausführlich beschrieben).
//сначала надо объявить импорт функции из DLL#import "имя_вашей_длл.dll"int SortStringArray(string *arr[],constint arraysize);
#import
//в тексте программы вызов проще простогоstring arr[];
int size;
...
//где-то в коде массив заполняется
...
//а вот и вызов сортировки
SortStringArray(arr,size);
2. Wenn man die DLL aufruft, muss man das Studio nicht eingeschaltet lassen, richtig? Wie wird es also ausgeführt?
Eine DLL ist, um es einfach auszudrücken, ein normales Windows-Programm, mit dem Unterschied, dass die Funktionen, die es implementiert, nicht von einem Benutzer, sondern von einem anderen Programm aufgerufen werden. Um dies zu ermöglichen, geben wir dem C++-Compiler den Modifikator __declspec(dllexport) an.
Ich habe eine weitere Frage: Ich habe einen Auftrag im Nachlauf. Wenn 1 unidirektionaler Auftrag offen ist, funktioniert alles gut, wenn mehr, funktioniert es aus irgendeinem Grund nicht. Und warum?
Soweit ich weiß, ist der Kauf ein Kauf, aber iClose(Symbol(),Periode(),0) nimmt die Preise vom Angebot. Dies kann der Grund für den Fehler sein.
Jetzt verwende ich die folgende Kombination:
Aber hier stellt sich die Frage, denn der EA ist kein Pips-basierter EA, der Preis war lange Zeit in der Kaufzone und wurde mit jedem Tick aktualisiert.
Warum wird der Handel nicht eröffnet? Es stellt sich heraus, dass der EA auf den Fehler stoppt und nicht sehen, weitere Preisbewegung?
Sollte ich Ihrer Meinung nach der Fehlerbehandlungsfunktion in diesem EA eine Prüfung auf 129 und 138 Fehler hinzufügen?
Wenn ja, wie kann man das tun?
Zumindest müssen Sie eine eigene Funktion für die Eröffnung von Positionen/Aufträgen haben, die alle Fehler behandelt. Hier müssen Sie sich über die neuesten Preise informieren.
Ich habe mir keine Rohlinge angeschaut. Aber ich will sagen: der EA muss alle vom Server zurückgegebenen Fehler behandeln. Und das ist noch nicht genug. Es sollte in der Lage sein, seine Positionen nach einer unerwarteten Situation ohne Funktionsverlust und ohne Ausfall des Algorithmus wieder einzunehmen und seine Arbeit fortzusetzen, als ob nichts Außergewöhnliches passiert wäre.
kompilieren und im Ordner experts/libraries ablegen Bitte sehr, danke!!! Ich werde es jetzt versuchen. Und ich habe vor, aber jetzt habe ich nicht finden, etwas so detailliert und verdaulich zu diesem Thema.
Zumindest sollten Sie eine eigene Funktion zum Öffnen von Positionen/Aufträgen haben, die alle Fehler behandelt. Dort müssen Sie sich über die neuesten Preise informieren.
Ich habe mir keine Baupläne angesehen. Aber ich will sagen: Sie müssen alle vom Server zurückgegebenen Fehler in Ihrem EA behandeln. Und das ist nicht genug. Es muss in der Lage sein, nach einer unvorhergesehenen Situation seine Positionen wieder einzunehmen, ohne dass es zu einem Funktionsverlust oder einem Ausfall seines Algorithmus kommt, und seine Arbeit fortzusetzen, als ob nichts Außergewöhnliches passiert wäre.
Bei Auftragseröffnung gibt es RefreshRates(); (Ich habe Bids und Asks durch Market Info ersetzt, wie vorgeschlagen).
while(true) // Цикл закрытия орд.
{
if (Total==0 && Opn_B==true) // Открытых орд. нет +
{ // критерий откр. Buy
RefreshRates(); // Обновление данных
SL=Bid - New_Stop(StopLoss)*Point; // Вычисление SL откр.
TP=Bid + New_Stop(TakeProfit)*Point; // Вычисление TP откр.Alert("Попытка открыть Buy. Ожидание ответа..");
Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP);//Открытие Buyif (Ticket > 0) // Получилось :)
{
Alert ("Открыт ордер Buy ",Ticket);
return; // Выход из start()
}
if (Fun_Error(GetLastError())==1) // Обработка ошибокcontinue; // Повторная попыткаreturn; // Выход из start()
}
Und eine Funktion zur Fehlerbehandlung:
int Fun_Error(int Error) // Ф-ия обработ ошибок
{
switch(Error)
{ // Преодолимые ошибки case4: Alert("Торговый сервер занят. Пробуем ещё раз..");
Sleep(3000); // Простое решениеreturn(1); // Выход из функцииcase135:Alert("Цена изменилась. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1); // Выход из функцииcase136:Alert("Нет цен. Ждём новый тик..");
while(RefreshRates()==false) // До нового тикаSleep(1); // Задержка в циклеreturn(1); // Выход из функцииcase137:Alert("Брокер занят. Пробуем ещё раз..");
Sleep(3000); // Простое решениеreturn(1); // Выход из функцииcase146:Alert("Подсистема торговли занята. Пробуем ещё..");
Sleep(500); // Простое решениеreturn(1); // Выход из функции// Критические ошибкиcase2: Alert("Общая ошибка.");
return(0); // Выход из функцииcase5: Alert("Старая версия терминала.");
Work=false; // Больше не работатьreturn(0); // Выход из функцииcase64: Alert("Счет заблокирован.");
Work=false; // Больше не работатьreturn(0); // Выход из функцииcase133:Alert("Торговля запрещена.");
return(0); // Выход из функцииcase134:Alert("Недостаточно денег для совершения операции.");
return(0); // Выход из функцииdefault: Alert("Возникла ошибка ",Error); // Другие варианты return(0); // Выход из функции
}
}
Das wollte ich fragen. Ich möchte fragen: Darf ich eine weitere Zeile aus 129 Fehler hinzufügen?
case129:Alert("Неправильные цены. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1);
Ich habe das gesamte Visual Studio-Projekt in meinem Expertenordner... Compile ist eine .exe-Datei, richtig? Ich wollte es in den Ordner libarries kopieren... Ich kann es nicht finden! Hier ist der Debug-Ordner des Projekts. Tut mir leid, das ist ein neues Thema.
Hier ist die .cpp-Datei des Projekts, schauen Sie es sich an, und nach ein paar Google- und Yandex-Suchen habe ich überhaupt nichts Gescheites gefunden, es ist allgemein verständlich. Es scheint sogar einfach zu sein.
Aber wie funktioniert das? Ich bin mir nicht ganz sicher, wie man auf diese ddl verweisen - aus dem Code des EA? Wie? Zunächst sieht es so aus: #include <GetIntValue>.
2. Wenn man die DLL aufruft, muss man das Studio nicht eingeschaltet lassen, oder? wie wird es ausgeführt?
Bitte zeigen Sie das einfachste Beispiel für den Aufruf dieser DLL aus dem MQL-Code.
Ich verstehe das hier nicht...
Die Losgröße sollte exponentiell ansteigen (mit Multiplikator 2), wenn ein zweiter unidirektionaler Auftrag eröffnet wird.
Das ist das Ergebnis.
dann wie folgt
erhalten Sie ein Ergebnis wie dieses
Dann war's das.
Danke, ich habe verstanden... Ich habe es verstanden.
Wofür ist diese Zeile?
datetime o;Ich habe eine weitere Frage: Ich habe einen Auftrag im Nachlauf. Wenn 1 unidirektionaler Auftrag offen ist, funktioniert alles gut, wenn mehr, funktioniert es aus irgendeinem Grund nicht. Und warum?
{
for(int i = 0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > TrailingStop*Point)
{
if (OrderStopLoss() < Bid - (TrailingStop + TrailingStep)*Point)
{
SL = NormalizeDouble(Bid - TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0);
}
}
}
if (OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > TrailingStop*Point)
{
if (OrderStopLoss() > Ask + (TrailingStop+ TrailingStep)*Point)
{
SL = NormalizeDouble (Ask+TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify (OrderTicket(), OrderOpenPrice(), SL,0,0);
}
}
}
}
}
}
}
Hier ist die .cpp-Datei des Projekts, schauen Sie es sich an, und nach ein paar Google- und Yandex-Suchen habe ich überhaupt nichts Gescheites gefunden, es ist allgemein verständlich. Es scheint sogar einfach zu sein.
Aber wie funktioniert das? Ich bin nicht ganz sicher, wie man auf diese ddl verweisen - aus dem Code des EA? Wie? Zunächst sieht es so aus: #include <GetIntValue>.
Das ist ungefähr so. Damit es funktioniert, müssen Sie die dll kompilieren und im Ordner experts/libraries ablegen (lesen Sie die Hilfe und das Tutorial, dort ist es ausführlich beschrieben).
2. Wenn man die DLL aufruft, muss man das Studio nicht eingeschaltet lassen, richtig? Wie wird es also ausgeführt?
Ich habe eine weitere Frage: Ich habe einen Auftrag im Nachlauf. Wenn 1 unidirektionaler Auftrag offen ist, funktioniert alles gut, wenn mehr, funktioniert es aus irgendeinem Grund nicht. Und warum?
{
for(int i = 0; i<OrdersTotal(); i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
{
if(Bid - OrderOpenPrice() > TrailingStop*Point)
{
if (OrderStopLoss() < Bid - (TrailingStop + TrailingStep)*Point)
{
SL = NormalizeDouble(Bid - TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0);
}
}
}
if (OrderType() == OP_SELL)
{
if(OrderOpenPrice() - Ask > TrailingStop*Point)
{
if (OrderStopLoss() > Ask + (TrailingStop+ TrailingStep)*Point)
{
SL = NormalizeDouble (Ask+TrailingStop*Point,Digits);
if (OrderStopLoss() !=SL)
OrderModify (OrderTicket(), OrderOpenPrice(), SL,0,0);
}
}
}
}
}
}
}
Da Sie Parameter an die Funktion übergeben müssen, versuchen Sie Folgendes
bool IfProfTrail=false; // Nur für profitable Positionen verwenden - Breakeven-Modus
int TrailingStop=0; // Schleppabstand = 0 - Mindestabstand
int TrailingStep=1; // Schleppender Abstandsschritt
Herzlichen Dank!
Jetzt verstehe ich, wo das Problem liegt.
Für den Kauf habe ich verwendet:
Soweit ich weiß, ist der Kauf ein Kauf, aber iClose(Symbol(),Periode(),0) nimmt die Preise vom Angebot. Dies kann der Grund für den Fehler sein.
Aber hier stellt sich die Frage, denn der EA ist kein Pips-basierter EA, der Preis war lange Zeit in der Kaufzone und wurde mit jedem Tick aktualisiert.Jetzt verwende ich die folgende Kombination:
Warum wird der Handel nicht eröffnet? Es stellt sich heraus, dass der EA auf den Fehler stoppt und nicht sehen, weitere Preisbewegung?
Ich habe die Vorlage für meinen Expert Advisor von https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4 übernommen.
Sollte ich Ihrer Meinung nach der Fehlerbehandlungsfunktion in diesem EA eine Prüfung auf 129 und 138 Fehler hinzufügen?
Wenn ja, wie kann man das tun?
Zumindest müssen Sie eine eigene Funktion für die Eröffnung von Positionen/Aufträgen haben, die alle Fehler behandelt. Hier müssen Sie sich über die neuesten Preise informieren.
Ich habe mir keine Rohlinge angeschaut. Aber ich will sagen: der EA muss alle vom Server zurückgegebenen Fehler behandeln. Und das ist noch nicht genug. Es sollte in der Lage sein, seine Positionen nach einer unerwarteten Situation ohne Funktionsverlust und ohne Ausfall des Algorithmus wieder einzunehmen und seine Arbeit fortzusetzen, als ob nichts Außergewöhnliches passiert wäre.
Zumindest sollten Sie eine eigene Funktion zum Öffnen von Positionen/Aufträgen haben, die alle Fehler behandelt. Dort müssen Sie sich über die neuesten Preise informieren.
Ich habe mir keine Baupläne angesehen. Aber ich will sagen: Sie müssen alle vom Server zurückgegebenen Fehler in Ihrem EA behandeln. Und das ist nicht genug. Es muss in der Lage sein, nach einer unvorhergesehenen Situation seine Positionen wieder einzunehmen, ohne dass es zu einem Funktionsverlust oder einem Ausfall seines Algorithmus kommt, und seine Arbeit fortzusetzen, als ob nichts Außergewöhnliches passiert wäre.
Die Vorlage stammt aus einem Lehrbuch. Ich bin nicht wirklich gut im Umgang mit Fehlerfunktionen.
Bei Auftragseröffnung gibt es RefreshRates(); (Ich habe Bids und Asks durch Market Info ersetzt, wie vorgeschlagen).
Und eine Funktion zur Fehlerbehandlung:
Das wollte ich fragen. Ich möchte fragen: Darf ich eine weitere Zeile aus 129 Fehler hinzufügen?