Aquí está el archivo .cpp del proyecto, échale un vistazo y después de un par de búsquedas en Google y Yandex, no encontré nada del otro mundo, en general es comprensible. Incluso parece sencillo.
//+------------------------------------------------------------------+//| 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));
}
//+------------------------------------------------------------------+
¿Pero cómo funciona? No estoy muy seguro de cómo hacer referencia a este ddl - desde el código del EA? ¿Cómo? En primer lugar, tiene este aspecto #include <GetIntValue>.
2. Al llamar a la dll, no hay que mantener el estudio encendido, ¿verdad? ¿cómo se ejecuta?
Por favor, muestre el ejemplo más sencillo de llamar a esta dll desde el código mql.
Aquí hay otra pregunta. Tengo una orden de arrastre. Cuando hay 1 orden unidireccional abierta, todo funciona bien, si hay más, no funciona por alguna razón. ¿Por qué?
Aquí está el archivo .cpp del proyecto, échale un vistazo y después de un par de búsquedas en Google y Yandex, no encontré nada del otro mundo, en general es comprensible. Incluso parece sencillo.
¿Pero cómo funciona? No estoy muy seguro de cómo hacer referencia a este ddl - desde el código del EA? ¿Cómo? En primer lugar, tiene este aspecto #include <GetIntValue>.
Es más o menos así. Para que funcione, tienes que compilar la dll y ponerla en la carpeta experts/libraries (lee la ayuda y el tutorial, ahí está detallado).
//сначала надо объявить импорт функции из DLL#import "имя_вашей_длл.dll"int SortStringArray(string *arr[],constint arraysize);
#import
//в тексте программы вызов проще простогоstring arr[];
int size;
...
//где-то в коде массив заполняется
...
//а вот и вызов сортировки
SortStringArray(arr,size);
2. Al llamar a la dll, no hay que mantener el estudio encendido, ¿verdad? ¿cómo se ejecuta?
Una DLL es, en pocas palabras, un programa normal de Windows, salvo que las funciones que implementa no son llamadas por un usuario, sino por otro programa. Para hacerlo posible, especificamos el modificador __declspec(dllexport) al compilador de C++.
Aquí hay otra pregunta. Tengo una orden de arrastre. Cuando hay 1 orden unidireccional abierta, todo funciona bien, si hay más, no funciona por alguna razón. ¿Por qué?
Como necesitas pasar parámetros a la función, prueba esto
bool IfProfTrail=false; // Usar sólo para posiciones rentables - Modo Breakeven int TrailingStop=0; // Distancia de arrastre = 0 - mínimo permitido int TrailingStep=1; // Paso de distancia final
Por lo que sé, la compra es ask, pero iClose(Symbol(),Period(),0) toma los precios de bid. Este puede ser el motivo del error.
Ahora uso la siguiente combinación:
Pero aquí surge la pregunta, porque el EA no es un EA basado en Pips, el precio estuvo en la zona de compra durante mucho tiempo y se actualizó con cada tick.
¿Por qué no se abre el comercio? Resulta que el EA se detiene en el error y no ve más movimiento de precios?
En su opinión, ¿debería añadir a la función de gestión de errores de este EA una comprobación de los errores 129 y 138?
En caso afirmativo, ¿cómo hacerlo?
Como mínimo, debe tener su propia función para la apertura de posiciones/configuración de órdenes que maneje todos los errores. Aquí es donde tienes que conseguir los últimos precios.
No he mirado ninguna pieza en blanco. Pero sí diré: el EA necesita manejar todos los errores devueltos por el servidor. Y eso no es suficiente. Debe ser capaz de retomar sus posiciones tras cualquier situación inesperada sin pérdida de funcionalidad y sin que el algoritmo falle, y continuar su trabajo como si no hubiera ocurrido nada extraordinario.
compilarlo y ponerlo en la carpeta expertos/bibliotecas Aquí tienes, ¡¡¡gracias!!! Lo intentaré ahora. Y lo he visto antes, pero ahora no encuentro nada tan detallado y digerible, sobre el tema.
Como mínimo debería tener su propia función para abrir posiciones/establecer órdenes que maneje todos los errores. Es donde debe obtener los últimos precios.
No he mirado ningún plano. Pero diré: necesitas manejar todos los errores devueltos por el servidor en tu EA. Y esto no es suficiente. Debe ser capaz de retomar sus posiciones después de cualquier situación imprevista, sin perder funcionalidad, sin ningún fallo de su algoritmo, y continuar su trabajo como si no hubiera ocurrido nada extraordinario.
La plantilla está sacada de un libro de texto. No se me dan bien las funciones de gestión de errores.
En la apertura de la orden, hay RefreshRates(); (he sustituido Bids y Asks por Market Info como se sugiere).
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()
}
Y función de tratamiento de errores:
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); // Выход из функции
}
}
Quería preguntar. Quiero preguntar: ¿Puedo añadir otra línea de 129 error a la misma?
case129:Alert("Неправильные цены. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1);
Tengo todo el proyecto de visual studio en mi carpeta de expertos... Compilar es un archivo .exe, ¿verdad? Quería copiarlo en la carpeta de librerías... No lo encuentro. Aquí está la carpeta de depuración del proyecto. Lo siento, es un tema nuevo.
Aquí está el archivo .cpp del proyecto, échale un vistazo y después de un par de búsquedas en Google y Yandex, no encontré nada del otro mundo, en general es comprensible. Incluso parece sencillo.
¿Pero cómo funciona? No estoy muy seguro de cómo hacer referencia a este ddl - desde el código del EA? ¿Cómo? En primer lugar, tiene este aspecto #include <GetIntValue>.
2. Al llamar a la dll, no hay que mantener el estudio encendido, ¿verdad? ¿cómo se ejecuta?
Por favor, muestre el ejemplo más sencillo de llamar a esta dll desde el código mql.
No lo entiendo aquí...
El tamaño del lote debe aumentar exponencialmente (con el multiplicador 2) si se abre una segunda orden unidireccional.
Este es el resultado.
entonces así
se obtiene un resultado como el siguiente
Entonces eso es todo.
Gracias, entiendo la idea... lo tengo claro.
¿para qué es esa línea?
datetime o;Aquí hay otra pregunta. Tengo una orden de arrastre. Cuando hay 1 orden unidireccional abierta, todo funciona bien, si hay más, no funciona por alguna razón. ¿Por qué?
{
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);
}
}
}
}
}
}
}
Aquí está el archivo .cpp del proyecto, échale un vistazo y después de un par de búsquedas en Google y Yandex, no encontré nada del otro mundo, en general es comprensible. Incluso parece sencillo.
¿Pero cómo funciona? No estoy muy seguro de cómo hacer referencia a este ddl - desde el código del EA? ¿Cómo? En primer lugar, tiene este aspecto #include <GetIntValue>.
Es más o menos así. Para que funcione, tienes que compilar la dll y ponerla en la carpeta experts/libraries (lee la ayuda y el tutorial, ahí está detallado).
2. Al llamar a la dll, no hay que mantener el estudio encendido, ¿verdad? ¿cómo se ejecuta?
Aquí hay otra pregunta. Tengo una orden de arrastre. Cuando hay 1 orden unidireccional abierta, todo funciona bien, si hay más, no funciona por alguna razón. ¿Por qué?
{
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);
}
}
}
}
}
}
}
Como necesitas pasar parámetros a la función, prueba esto
bool IfProfTrail=false; // Usar sólo para posiciones rentables - Modo Breakeven
int TrailingStop=0; // Distancia de arrastre = 0 - mínimo permitido
int TrailingStep=1; // Paso de distancia final
¡Muchas gracias!
Ahora entiendo cuál es el problema.
Para la compra he utilizado:
Por lo que sé, la compra es ask, pero iClose(Symbol(),Period(),0) toma los precios de bid. Este puede ser el motivo del error.
Pero aquí surge la pregunta, porque el EA no es un EA basado en Pips, el precio estuvo en la zona de compra durante mucho tiempo y se actualizó con cada tick.Ahora uso la siguiente combinación:
¿Por qué no se abre el comercio? Resulta que el EA se detiene en el error y no ve más movimiento de precios?
Tomé la plantilla para mi Asesor Experto de https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4
En su opinión, ¿debería añadir a la función de gestión de errores de este EA una comprobación de los errores 129 y 138?
En caso afirmativo, ¿cómo hacerlo?
Como mínimo, debe tener su propia función para la apertura de posiciones/configuración de órdenes que maneje todos los errores. Aquí es donde tienes que conseguir los últimos precios.
No he mirado ninguna pieza en blanco. Pero sí diré: el EA necesita manejar todos los errores devueltos por el servidor. Y eso no es suficiente. Debe ser capaz de retomar sus posiciones tras cualquier situación inesperada sin pérdida de funcionalidad y sin que el algoritmo falle, y continuar su trabajo como si no hubiera ocurrido nada extraordinario.
Como mínimo debería tener su propia función para abrir posiciones/establecer órdenes que maneje todos los errores. Es donde debe obtener los últimos precios.
No he mirado ningún plano. Pero diré: necesitas manejar todos los errores devueltos por el servidor en tu EA. Y esto no es suficiente. Debe ser capaz de retomar sus posiciones después de cualquier situación imprevista, sin perder funcionalidad, sin ningún fallo de su algoritmo, y continuar su trabajo como si no hubiera ocurrido nada extraordinario.
La plantilla está sacada de un libro de texto. No se me dan bien las funciones de gestión de errores.
En la apertura de la orden, hay RefreshRates(); (he sustituido Bids y Asks por Market Info como se sugiere).
Y función de tratamiento de errores:
Quería preguntar. Quiero preguntar: ¿Puedo añadir otra línea de 129 error a la misma?