任何菜鸟问题,为了不给论坛添乱。专业人士,不要路过。没有你就无处可去 - 6. - 页 342

 

这是项目的.cpp文件,看看吧,经过谷歌和Yandex的几次搜索,我没有发现任何脑洞大开的东西,大致上可以理解。它甚至看起来很简单。

//+------------------------------------------------------------------+
//| 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 // Указатель на стринг, я плохо помню.
};
static int CompareMqlStr(const void *left,const void *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(const int ipar) // __stdcall кладет аргументы в стек справа налево
{ // MT4_EXPFUNC говорит что функция будет видима из метатрайдера, я не совсем понял.
printf("GetIntValue takes %d\n",ipar);
return(ipar);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
MT4_EXPFUNC double __stdcall GetDoubleValue(const double 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(const double *arr,const int arraysize,const int 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,const int arraysize,const int nitem,const double 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,const int rates_total,const int shift,const int 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)
{
case 0: return double(rates[nitem].ctm);
case 1: return rates[nitem].open;
case 2: return rates[nitem].low;
case 3: return rates[nitem].high;
case 4: return rates[nitem].close;
case 5: return rates[nitem].vol;
}
//---
return(0.0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
MT4_EXPFUNC int __stdcall SortStringArray(MqlStr *arr,const int 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,const int 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 string
if(arr[i+1].string==NULL) continue;
//--- destination string is uninitialized and cannot be allocated within dll
if(arr[i].string==NULL) continue;
//--- memory piece is less than needed and cannot be reallocated within dll
if(arr[i].len<len1+len2) continue;
//--- final processing
strcat(arr[i].string,arr[i+1].string);
}
//---
return(arraysize);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CompareMqlStr(const void *left,const void *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));
}
//+------------------------------------------------------------------+

但它是如何工作的呢?我不太确定如何引用这个ddl--从EA的代码中引用?如何?首先,它看起来像这样 #include <GetIntValue>.

2.调用dll时,你不必一直开着工作室,对吗? 它是如何执行的?

请展示一下从mql代码中调用这个dll的最简单的例子。

 
Trader7777:

我不明白这里的情况...


如果开出第二个单向订单,手数应以指数形式增加(乘数为2)。



这就是结果。

然后像这样

double OrderLotsSell(string sy="", int op=-1, int mn=-1) { 
 datetime o;
   int      i, k=OrdersTotal(); double r=-1;

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if ( OrderType()==OP_SELL) {
          if (op<0 || OrderType()==OP_SELL) {
            if (mn<0 || OrderMagicNumber()==Magic) {
              r=OrderLots()*2;
            }
          }
        }
      }
    }
  }
  return(r);
}

double OrderLotsBuy(string sy="", int op=-1, int mn=-1) { 
 datetime o;
   int      i, k=OrdersTotal(); double r=-1;

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if ( OrderType()==OP_BUY) {
          if (op<0 || OrderType()==OP_BUY) {
            if (mn<0 || OrderMagicNumber()==Magic) {
              r=OrderLots()*2;
            }
          }
        }
      }
    }
  }
  return(r);
}





 
max020780:


你会得到这样的结果

然后就这样了。


谢谢,我明白了......我已经想好了。

这条线是做什么用的?


datetime o;
 

还有一个问题,我有一个尾随订单。当1个单向订单打开时,一切都很正常,如果更多,就会因某种原因而不工作。为什么?

void Trailing ()
{
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);
}
}
}
}
}
}
}


 
Vladimirovits:

这是项目的.cpp文件,看看吧,经过谷歌和Yandex的几次搜索,我没有发现任何脑洞大开的东西,大致上可以理解。这甚至看起来很简单。

但它是如何工作的呢?我不太确定如何引用这个ddl--从EA的代码中引用?如何?首先,它看起来像这样 #include <GetIntValue>.

大致是这样的。为了让它工作,你需要编译dll并把它放在experts/libraries文件夹中(阅读帮助和教程,那里有详细说明)。

//сначала надо объявить импорт функции из DLL
#import "имя_вашей_длл.dll"
int SortStringArray(string *arr[],const int arraysize);
#import


//в тексте программы вызов проще простого

string arr[];
int size;
...
//где-то в коде массив заполняется
...
//а вот и вызов сортировки
SortStringArray(arr,size);

2.调用dll时,你不必一直开着工作室,对吗? 那么它是如何执行的?

简单地说,DLL是一个正常的Windows程序,只是它实现的功能不是由用户调用,而是由另一个程序调用。为了使之成为可能,我们向C++编译器指定了__declspec(dllexport)修改器。
 
Trader7777:

还有一个问题,我有一个尾随订单。当1个单向订单打开时,一切都很正常,如果更多,就会因某种原因而不工作。为什么?

void Trailing ()
{
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);
}
}
}
}
}
}
}


因为你需要向函数传递参数,请尝试这样做

bool IfProfTrail=false; // 只对盈利的头寸使用--盈亏平衡模式
int TrailingStop=0; // 拖曳距离=0 - 允许的最小距离
int TrailingStep=1; // 拖曳距离步骤


void Trailing(string sy="",int op=-1,int mn=-1)
  {
   double po,pp;
   int    i,k=OrdersTotal();
   

   if(sy=="0") sy=Symbol();
   if(TrailingStop==0)TrailingStop=MarketInfo(Symbol(),MODE_STOPLEVEL);
   for(i=0;i<k;i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op))
           {
            po=MarketInfo(OrderSymbol(),MODE_POINT);
            if(mn<0 || OrderMagicNumber()==mn)
              {
               if(OrderType()==OP_BUY)
                 {
                  pp=MarketInfo(OrderSymbol(),MODE_BID);
                  if((!IfProfTrail && OrderProfit()>0) || pp-OrderOpenPrice()>TrailingStop*po)
                    {
                     if(OrderStopLoss()<pp-(TrailingStop+TrailingStep-1)*po)
                       {
                        ModifyOrder(-1,pp-TrailingStop*po,-1);
                       }
                    }
                 }
               if(OrderType()==OP_SELL)
                 {
                  pp=MarketInfo(OrderSymbol(),MODE_ASK);
                  if((!IfProfTrail && OrderProfit()>0) || OrderOpenPrice()-pp>TrailingStop*po)
                    {
                     if(OrderStopLoss()>pp+(TrailingStop+TrailingStep-1)*po || OrderStopLoss()==0)
                       {
                        ModifyOrder(-1,pp+TrailingStop*po,-1);
                       }
                    }
                 }
              }
           }
        }
     }
  }


 
Forexman77:

非常感谢您!

现在我明白问题出在哪里了。

对于购买,我使用了。

据我所知,买入是要价,但iClose(Symbol(),Period(),0)从要价中获取价格。这可能是出错的原因。

现在我使用以下组合。

但这里的问题出现了,因为该EA不是基于点数的EA,价格在买入区的时间很长,而且每一个刻度都在更新。

为什么交易不开放?事实证明,EA在错误上停止,没有看到进一步的价格运动?

我的专家顾问的模板来自https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4

在您看来,我是否应该在该EA的错误处理功能中加入对129和138错误的检查?

如果是,如何做呢?

至少,你必须有自己的开仓/设单功能,以处理所有的错误。这是你需要获得最新价格的地方。

我还没有看过任何空白的东西。但我想说:EA需要处理服务器返回的所有错误。而这还远远不够。它应该能够在任何意外情况发生后,在不丧失功能和不发生算法故障的情况下恢复其位置,并继续其工作,就像没有发生过任何特殊情况一样。

 
编译它并把它放在experts/libraries文件夹里 给你,谢谢 我现在就去试试。 而且我以前也见过,但现在我没有找到如此详细和可消化的东西,关于这个问题。
 
artmedia70:

至少你应该有自己的开仓/定单函数来处理所有错误。这是你需要获得最新价格的地方。

我还没有看过任何蓝图。但我要说:你需要在你的EA中处理所有由服务器返回的错误。而这是不够的。它必须能够在任何不可预见的情况下,在不失去功能的情况下,在其算法没有任何故障的情况下,重新拾起它的位置,并继续其工作,就像没有发生过任何特殊情况一样。


该模板取自一本教科书。我不太擅长错误处理 功能。

在订单打开时,有RefreshRates();(我已经按照建议通过市场信息替换了Bids和Asks)。

 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);//Открытие Buy
         if (Ticket > 0)                        // Получилось :)
           {
            Alert ("Открыт ордер Buy ",Ticket);
            return;                             // Выход из start()
           }
         if (Fun_Error(GetLastError())==1)      // Обработка ошибок
            continue;                           // Повторная попытка
         return;                                // Выход из start()
        }

和错误处理功能。

int Fun_Error(int Error)                        // Ф-ия обработ ошибок
  {
   switch(Error)
     {                                          // Преодолимые ошибки            
      case  4: Alert("Торговый сервер занят. Пробуем ещё раз..");
         Sleep(3000);                           // Простое решение
         return(1);                             // Выход из функции
      case 135:Alert("Цена изменилась. Пробуем ещё раз..");
         RefreshRates();                        // Обновим данные
         return(1);                             // Выход из функции
      case 136:Alert("Нет цен. Ждём новый тик..");
         while(RefreshRates()==false)           // До нового тика
            Sleep(1);                           // Задержка в цикле
         return(1);                             // Выход из функции
      case 137:Alert("Брокер занят. Пробуем ещё раз..");
         Sleep(3000);                           // Простое решение
         return(1);                             // Выход из функции
      case 146:Alert("Подсистема торговли занята. Пробуем ещё..");
         Sleep(500);                            // Простое решение
         return(1);                             // Выход из функции
         // Критические ошибки
      case  2: Alert("Общая ошибка.");
         return(0);                             // Выход из функции
      case  5: Alert("Старая версия терминала.");
         Work=false;                            // Больше не работать
         return(0);                             // Выход из функции
      case 64: Alert("Счет заблокирован.");
         Work=false;                            // Больше не работать
         return(0);                             // Выход из функции
      case 133:Alert("Торговля запрещена.");
         return(0);                             // Выход из функции
      case 134:Alert("Недостаточно денег для совершения операции.");
         return(0);                             // Выход из функции
      default: Alert("Возникла ошибка ",Error); // Другие варианты   
         return(0);                             // Выход из функции
     }
  }

我想问的是。我想问:我可以从129个错误中再加一行吗?

      case 129:Alert("Неправильные цены. Пробуем ещё раз..");
         RefreshRates();                        // Обновим данные
         return(1); 
 
的专家 文件夹 整个visual studio项目... 编译是一个.exe文件,对吗? 我想把它复制到libarries文件夹... 我找不到它!这是项目的调试文件夹。 对不起,这是个新话题。
原因: