Ecco il file .cpp del progetto, dategli un'occhiata e dopo un paio di ricerche su Google e Yandex, non ho trovato nulla di cervellotico, è generalmente comprensibile. Sembra persino semplice.
//+------------------------------------------------------------------+//| 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));
}
//+------------------------------------------------------------------+
Ma come funziona? Non sono sicuro di come fare riferimento a questo ddl - dal codice dell'EA? Come? Per prima cosa, si presenta così #include <GetIntValue>.
2. Quando si chiama la dll, non si deve tenere lo studio acceso, giusto? come si esegue?
Si prega di mostrare l'esempio più semplice di chiamare questa dll dal codice mql.
Ecco un'altra domanda: ho un ordine trailing. Quando 1 ordine unidirezionale è aperto, tutto funziona bene, se più, non funziona per qualche motivo. Perché?
Ecco il file .cpp del progetto, dategli un'occhiata e dopo un paio di ricerche su Google e Yandex, non ho trovato nulla di cervellotico, è generalmente comprensibile. Sembra persino semplice.
Ma come funziona? Non sono sicuro di come fare riferimento a questo ddl - dal codice dell'EA? Come? Per prima cosa, si presenta così #include <GetIntValue>.
È più o meno così. Per farlo funzionare, devi compilare la dll e metterla nella cartella experts/libraries (leggi l'aiuto e il tutorial, è dettagliato lì).
//сначала надо объявить импорт функции из DLL#import "имя_вашей_длл.dll"int SortStringArray(string *arr[],constint arraysize);
#import
//в тексте программы вызов проще простогоstring arr[];
int size;
...
//где-то в коде массив заполняется
...
//а вот и вызов сортировки
SortStringArray(arr,size);
2. Quando si chiama la dll, non si deve tenere lo studio acceso, giusto? come viene eseguito?
Una DLL è, per dirla semplicemente, un normale programma di Windows, tranne che le funzioni che implementa non sono chiamate da un utente, ma da un altro programma. Per renderlo possibile, specifichiamo il modificatore __declspec(dllexport) al compilatore C++.
Ecco un'altra domanda: ho un ordine trailing. Quando 1 ordine unidirezionale è aperto, tutto funziona bene, se più, non funziona per qualche motivo. Perché?
Poiché avete bisogno di passare dei parametri nella funzione, provate questo
bool IfProfTrail=false; // Usa solo per le posizioni profittevoli - modalità Breakeven int TrailingStop=0; // Distanza di trascinamento = 0 - minimo consentito int TrailingStep=1; // Passo di distanza in uscita
Secondo te, dovrei aggiungere alla funzione di gestione degli errori in questo EA un controllo per gli errori 129 e 138?
Se sì, come fare?
Come minimo, dovete avere una vostra funzione per aprire posizioni/impostare ordini che gestisca tutti gli errori. È qui che devi trovare gli ultimi prezzi.
Non ho guardato alcuno spazio vuoto. Ma dirò: l'EA deve gestire tutti gli errori restituiti dal server. E questo non basta. Dovrebbe essere in grado di riprendere le sue posizioni dopo qualsiasi situazione imprevista senza perdita di funzionalità e senza il fallimento dell'algoritmo, e continuare il suo lavoro come se non fosse successo nulla di straordinario.
compilatelo e mettetelo nella cartella experts/libraries Ecco a voi, grazie!!! Lo proverò ora. E l'ho già visto, ma ora non trovo nulla di così dettagliato e digeribile sull'argomento.
Come minimo dovreste avere una vostra funzione per aprire posizioni/impostare ordini che gestisca tutti gli errori. È lì che devi trovare i prezzi più recenti.
Non ho guardato nessun progetto. Ma vi dirò: dovete gestire tutti gli errori restituiti dal server nel vostro EA. E questo non è sufficiente. Deve essere in grado di riprendere le sue posizioni dopo qualsiasi situazione imprevista, senza perdere la funzionalità, senza alcun fallimento del suo algoritmo, e continuare il suo lavoro come se nulla di straordinario fosse accaduto.
Il modello è tratto da un libro di testo. Non sono molto bravo con le funzioni di gestione degli errori.
All'apertura dell'ordine, c'è RefreshRates(); (ho sostituito Bids e Asks con Market Info come suggerito).
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()
}
E la funzione di gestione degli errori:
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); // Выход из функции
}
}
Volevo chiedere. Voglio chiedere: posso aggiungere un'altra linea di 129 errori?
case129:Alert("Неправильные цены. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1);
Ho l' intero progetto visual studio nella mia cartella esperti... Compile è un file .exe, giusto? Volevo copiarlo nella cartella libarries... Non riesco a trovarlo! Ecco la cartella debug del progetto. Mi dispiace, è un nuovo argomento.
Ecco il file .cpp del progetto, dategli un'occhiata e dopo un paio di ricerche su Google e Yandex, non ho trovato nulla di cervellotico, è generalmente comprensibile. Sembra persino semplice.
Ma come funziona? Non sono sicuro di come fare riferimento a questo ddl - dal codice dell'EA? Come? Per prima cosa, si presenta così #include <GetIntValue>.
2. Quando si chiama la dll, non si deve tenere lo studio acceso, giusto? come si esegue?
Si prega di mostrare l'esempio più semplice di chiamare questa dll dal codice mql.
Non capisco qui...
La dimensione del lotto dovrebbe aumentare esponenzialmente (con moltiplicatore 2) se viene aperto un secondo ordine unidirezionale.
Questo è il risultato.
poi come questo
si ottiene un risultato come questo
Allora questo è tutto.
Grazie, ho capito l'idea... ho capito tutto.
a cosa serve quella linea?
datetime o;Ecco un'altra domanda: ho un ordine trailing. Quando 1 ordine unidirezionale è aperto, tutto funziona bene, se più, non funziona per qualche motivo. Perché?
{
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);
}
}
}
}
}
}
}
Ecco il file .cpp del progetto, dategli un'occhiata e dopo un paio di ricerche su Google e Yandex, non ho trovato nulla di cervellotico, è generalmente comprensibile. Sembra persino semplice.
Ma come funziona? Non sono sicuro di come fare riferimento a questo ddl - dal codice dell'EA? Come? Per prima cosa, si presenta così #include <GetIntValue>.
È più o meno così. Per farlo funzionare, devi compilare la dll e metterla nella cartella experts/libraries (leggi l'aiuto e il tutorial, è dettagliato lì).
2. Quando si chiama la dll, non si deve tenere lo studio acceso, giusto? come viene eseguito?
Ecco un'altra domanda: ho un ordine trailing. Quando 1 ordine unidirezionale è aperto, tutto funziona bene, se più, non funziona per qualche motivo. Perché?
{
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);
}
}
}
}
}
}
}
Poiché avete bisogno di passare dei parametri nella funzione, provate questo
bool IfProfTrail=false; // Usa solo per le posizioni profittevoli - modalità Breakeven
int TrailingStop=0; // Distanza di trascinamento = 0 - minimo consentito
int TrailingStep=1; // Passo di distanza in uscita
Grazie mille!
Ora capisco qual è il problema.
Per l'acquisto ho usato:
Per quanto ne so, l'acquisto è ask, ma iClose(Symbol(),Period(),0) prende i prezzi da bid. Questo può essere il motivo dell'errore.
Ma qui sorge la domanda, perché l'EA non è un EA basato sui Pips, il prezzo è stato nella zona di acquisto per molto tempo e aggiornato con ogni tick.Ora uso la seguente combinazione:
Perché il commercio non si apre? Risulta che l'EA si ferma sull'errore e non vede ulteriori movimenti di prezzo?
Ho preso il modello per il mio Expert Advisor da https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4
Secondo te, dovrei aggiungere alla funzione di gestione degli errori in questo EA un controllo per gli errori 129 e 138?
Se sì, come fare?
Come minimo, dovete avere una vostra funzione per aprire posizioni/impostare ordini che gestisca tutti gli errori. È qui che devi trovare gli ultimi prezzi.
Non ho guardato alcuno spazio vuoto. Ma dirò: l'EA deve gestire tutti gli errori restituiti dal server. E questo non basta. Dovrebbe essere in grado di riprendere le sue posizioni dopo qualsiasi situazione imprevista senza perdita di funzionalità e senza il fallimento dell'algoritmo, e continuare il suo lavoro come se non fosse successo nulla di straordinario.
Come minimo dovreste avere una vostra funzione per aprire posizioni/impostare ordini che gestisca tutti gli errori. È lì che devi trovare i prezzi più recenti.
Non ho guardato nessun progetto. Ma vi dirò: dovete gestire tutti gli errori restituiti dal server nel vostro EA. E questo non è sufficiente. Deve essere in grado di riprendere le sue posizioni dopo qualsiasi situazione imprevista, senza perdere la funzionalità, senza alcun fallimento del suo algoritmo, e continuare il suo lavoro come se nulla di straordinario fosse accaduto.
Il modello è tratto da un libro di testo. Non sono molto bravo con le funzioni di gestione degli errori.
All'apertura dell'ordine, c'è RefreshRates(); (ho sostituito Bids e Asks con Market Info come suggerito).
E la funzione di gestione degli errori:
Volevo chiedere. Voglio chiedere: posso aggiungere un'altra linea di 129 errori?