Aqui está o arquivo .cpp do projeto, dê uma olhada nele e depois de algumas pesquisas no Google e Yandex, não encontrei nada de inteligente, é geralmente compreensível. Parece até simples.
//+------------------------------------------------------------------+//| 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));
}
//+------------------------------------------------------------------+
Mas como funciona? Não sei bem como me referir a este ddl - a partir do código da EA? Como? Primeiro, parece que isto #inclui <GetIntValue>.
2. Ao chamar a dll, você não precisa manter o estúdio ligado, certo? como ele é executado?
Por favor, mostre o exemplo mais simples de como chamar esta dll a partir do código mql.
Aqui está outra pergunta. Tenho uma ordem de fuga. Quando 1 ordem unidirecional está aberta, tudo funciona bem, se mais, não funciona por alguma razão. Por quê?
Aqui está o arquivo .cpp do projeto, dê uma olhada nele e depois de algumas pesquisas no Google e Yandex, não encontrei nada de inteligente, é geralmente compreensível. Parece até simples.
Mas como funciona? Não sei bem como me referir a este ddl - a partir do código da EA? Como? Primeiro, parece que isto #inclui <GetIntValue>.
É mais ou menos assim. Para que funcione, você precisa compilar a dll e colocá-la na pasta experts/libraries (leia a ajuda e o tutorial, está detalhado lá).
//сначала надо объявить импорт функции из DLL#import "имя_вашей_длл.dll"int SortStringArray(string *arr[],constint arraysize);
#import
//в тексте программы вызов проще простогоstring arr[];
int size;
...
//где-то в коде массив заполняется
...
//а вот и вызов сортировки
SortStringArray(arr,size);
2. Ao chamar a dll, você não precisa manter o estúdio ligado, certo? Então como ele é executado?
Uma DLL é, para simplificar, um programa Windows normal, exceto que as funções que ela implementa não são chamadas por um usuário, mas por outro programa. Para tornar isso possível, especificamos o modificador __declspec(dllexport) para o compilador C++.
Aqui está outra pergunta. Tenho uma ordem de fuga. Quando 1 ordem unidirecional está aberta, tudo funciona bem, se mais, não funciona por alguma razão. Por quê?
Porque você precisa passar parâmetros para a função, tente isto
bool IfProfTrail=falso; // Utilização apenas para posições rentáveis - modo breakeven int TrailingStop=0; // Distância de trilha = 0 - mínimo permitido int TrailingStep=1; // Passo de distância de trilha
Na sua opinião, devo acrescentar à função de tratamento de erros nesta EA uma verificação de 129 e 138 erros?
Se sim, como fazer isso?
No mínimo, você deve ter sua própria função para abrir posições/definir ordens que irão lidar com todos os erros. É aqui que você precisa obter os preços mais recentes.
Eu não olhei nenhum espaço em branco. Mas eu direi: a EA precisa lidar com todos os erros devolvidos pelo servidor. E isso não é suficiente. Ele deve ser capaz de retomar suas posições após qualquer situação inesperada sem perda de funcionalidade e sem a falha do algoritmo, e continuar seu trabalho como se nada de extraordinário tivesse acontecido.
compile-o e coloque-o na pasta de especialistas/library Aqui está, obrigado!!! Vou tentar agora. E eu já me encontrei antes, mas agora não encontro nada tão detalhado e digerível sobre o assunto.
No mínimo, você deve ter sua própria função para abrir posições/definir ordens que lidem com todos os erros. É onde você precisa obter os preços mais recentes.
Eu não olhei nenhum projeto. Mas eu direi: você precisa lidar com todos os erros devolvidos pelo servidor em sua EA. E isto não é suficiente. Deve ser capaz de retomar suas posições após qualquer situação imprevista, sem perder a funcionalidade, sem qualquer falha de seu algoritmo, e continuar seu trabalho como se nada de extraordinário tivesse acontecido.
O modelo é retirado de um livro didático. Eu não sou realmente bom em funções de manuseio de erros.
Na abertura do pedido, há RefreshRates(); (Eu substituo Licitações e Pede através de Informações de Mercado como sugerido).
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 função de tratamento de erros:
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); // Выход из функции
}
}
Eu queria perguntar. Quero perguntar: Posso acrescentar outra linha de 129 erros a ela?
case129:Alert("Неправильные цены. Пробуем ещё раз..");
RefreshRates(); // Обновим данныеreturn(1);
Tenho todo o projeto do estúdio visual em minha pasta de especialistas... Compile é um arquivo .exe, certo? Queria copiá-lo para a pasta dos libares. Não consigo encontrar! Aqui está a pasta de depuração do projeto. Desculpe, é um novo tópico.
Aqui está o arquivo .cpp do projeto, dê uma olhada nele e depois de algumas pesquisas no Google e Yandex, não encontrei nada de inteligente, é geralmente compreensível. Parece até simples.
Mas como funciona? Não sei bem como me referir a este ddl - a partir do código da EA? Como? Primeiro, parece que isto #inclui <GetIntValue>.
2. Ao chamar a dll, você não precisa manter o estúdio ligado, certo? como ele é executado?
Por favor, mostre o exemplo mais simples de como chamar esta dll a partir do código mql.
Não entendo isso aqui...
O tamanho do lote deve aumentar exponencialmente (com multiplicador 2) se uma segunda ordem unidirecional for aberta.
Este é o resultado.
então assim
você obtém um resultado como este
Então é isso.
Obrigado, entendi a idéia... Já percebi.
para que serve essa linha?
datetime o;Aqui está outra pergunta. Tenho uma ordem de fuga. Quando 1 ordem unidirecional está aberta, tudo funciona bem, se mais, não funciona por alguma razão. 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);
}
}
}
}
}
}
}
Aqui está o arquivo .cpp do projeto, dê uma olhada nele e depois de algumas pesquisas no Google e Yandex, não encontrei nada de inteligente, é geralmente compreensível. Parece até simples.
Mas como funciona? Não sei bem como me referir a este ddl - a partir do código da EA? Como? Primeiro, parece que isto #inclui <GetIntValue>.
É mais ou menos assim. Para que funcione, você precisa compilar a dll e colocá-la na pasta experts/libraries (leia a ajuda e o tutorial, está detalhado lá).
2. Ao chamar a dll, você não precisa manter o estúdio ligado, certo? Então como ele é executado?
Aqui está outra pergunta. Tenho uma ordem de fuga. Quando 1 ordem unidirecional está aberta, tudo funciona bem, se mais, não funciona por alguma razão. 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);
}
}
}
}
}
}
}
Porque você precisa passar parâmetros para a função, tente isto
bool IfProfTrail=falso; // Utilização apenas para posições rentáveis - modo breakeven
int TrailingStop=0; // Distância de trilha = 0 - mínimo permitido
int TrailingStep=1; // Passo de distância de trilha
Muito obrigado!
Agora eu entendo qual é o problema.
Para a compra que utilizei:
Tanto quanto sei, comprar é pedir, mas iClose(Symbol(),Period(),0) aceita preços de licitação. Esta pode ser a razão do erro.
Mas aqui surge a questão, porque a EA não é uma EA baseada em Pips, o preço esteve na zona de compra por um longo tempo e atualizado a cada tic tac.Agora eu uso a seguinte combinação:
Por que o comércio não é aberto? Acontece que a EA pára com o erro e não vê mais movimento de preços?
Eu peguei o modelo para meu consultor especializado em https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4
Na sua opinião, devo acrescentar à função de tratamento de erros nesta EA uma verificação de 129 e 138 erros?
Se sim, como fazer isso?
No mínimo, você deve ter sua própria função para abrir posições/definir ordens que irão lidar com todos os erros. É aqui que você precisa obter os preços mais recentes.
Eu não olhei nenhum espaço em branco. Mas eu direi: a EA precisa lidar com todos os erros devolvidos pelo servidor. E isso não é suficiente. Ele deve ser capaz de retomar suas posições após qualquer situação inesperada sem perda de funcionalidade e sem a falha do algoritmo, e continuar seu trabalho como se nada de extraordinário tivesse acontecido.
No mínimo, você deve ter sua própria função para abrir posições/definir ordens que lidem com todos os erros. É onde você precisa obter os preços mais recentes.
Eu não olhei nenhum projeto. Mas eu direi: você precisa lidar com todos os erros devolvidos pelo servidor em sua EA. E isto não é suficiente. Deve ser capaz de retomar suas posições após qualquer situação imprevista, sem perder a funcionalidade, sem qualquer falha de seu algoritmo, e continuar seu trabalho como se nada de extraordinário tivesse acontecido.
O modelo é retirado de um livro didático. Eu não sou realmente bom em funções de manuseio de erros.
Na abertura do pedido, há RefreshRates(); (Eu substituo Licitações e Pede através de Informações de Mercado como sugerido).
E função de tratamento de erros:
Eu queria perguntar. Quero perguntar: Posso acrescentar outra linha de 129 erros a ela?