[¡Archivo!] Cualquier pregunta de novato, para no saturar el foro. Profesionales, no pasen de largo. No puedo ir a ningún sitio sin ti - 4. - página 359

 

Chicos, podéis aconsejaros:

Al probar el asesor en los indicadores estándar incluidos en la entrega de MT4 en los pares de divisas - no hay problemas - todo funciona de acuerdo con el algoritmo de negociación.

Cuando se hacen pruebas en metales, como la plata y el oro, las órdenes no se abren, en el Diario del Probador de Estrategias escriben división cero.

Tengo los mismos parámetros de entrada, el historial de esta empresa de corretaje de cinco dígitos (forex4yu) se ha cargado para los instrumentos probados.

¿Cuál es la posible razón? No quiero enviar mi EA a un telépata. Escribí el Asesor Experto personalmente según la versión del libro.

 
Roman.:

Chicos, podéis aconsejaros:

Al probar el asesor en los indicadores estándar incluidos en la entrega de MT4 en los pares de divisas - no hay problemas - todo funciona de acuerdo con el algoritmo de negociación.

Cuando se hacen pruebas en metales, como la plata y el oro, las órdenes no se abren, en el Diario del Probador de Estrategias escriben división cero.

Tengo los mismos parámetros de entrada, el historial de esta empresa de corretaje de cinco dígitos (forex4yu) se ha cargado para los instrumentos probados.

¿Cuál es la posible razón? No quiero enviar mi EA a un telépata. Escribí el Asesor Experto personalmente según la versión del libro.

Cuando se divide por una variable, primero hay que comprobar que no es igual a cero.
 
Roman.:

Chicos, podéis aconsejaros:

Al probar el asesor en los indicadores estándar incluidos en la entrega de MT4 en los pares de divisas - no hay problemas - todo funciona de acuerdo con el algoritmo de negociación.

Cuando se hacen pruebas en metales, como la plata y el oro, las órdenes no se abren, en el Diario del Probador de Estrategias escriben división cero.

Tengo los mismos parámetros de entrada, el historial de esta empresa de corretaje de cinco dígitos (forex4yu) se ha cargado para los instrumentos probados.

¿Cuál es la posible razón? No quiero enviar mi EA a un telépata. Escribí el Asesor Experto personalmente según la versión del libro.


Deberías ver el código. En general, puedes (en el Bloc de notas++) marcar automáticamente todos los lugares donde se produce un signo de división en el código y ver si la división por cero se produce realmente en algún caso.
 
drknn:

Me encantaría ver el código. Y en general, puedes (en el Bloc de notas++) marcar automáticamente todos los lugares donde aparece el signo de división en el código y comprobar si en algún caso se produce realmente la división por cero.


Sí, ya estoy mirando las impresiones hasta donde ha llegado el desembalaje, ahí está todo bien...

En la función de normalización del volumen para los metales había este error (división por cero), ahora no está presente, había otro 131 - volumen incorrecto, aunque fijado obviamente = 0,01 lote, miro en general...

Para las monedas, esta función de normalización del volumen funciona correctamente.... ¿Quizás haya un común para ellos (para los metales y las monedas)?

//--------------------------------------------------------------------
// Lot_MM.mqh
// 
//--------------------------------------------------------------- 1 --
// Функция вычисления количества лотов.
// Глобальные переменные:
// double Lots_New - количество лотов для новых ордеров (вычисляется)
// double Lots     - желаемое количество лотов, заданное пользовател.
// double  MaksRisk  - процент риска
// Возвращаемые значения:
// true  - если средств хватает на минимальный лот
// false - если средств не хватает на минимальный лот
//--------------------------------------------------------------- 2 --
bool Lot_MM()                            // Позовательская ф-ия
  {
   int time, ticket;                  // Наибольшее время открытия и номер ордера
   double orderLots;                  // Lots   
   double orderProfit;                // Profit
   double Price;                      // Цена открытия рыночного ордера
   double SL;                         // Значение StopLoss ордера
   double  TP;                        // Значение TakeProfit ордера
   string Symb   =Symbol();                    // Финансовый инструм.
   double One_Lot=MarketInfo(Symb,MODE_MARGINREQUIRED);//Размер свободных средств, необходимых для открытия 1 лота
   double Min_Lot=MarketInfo(Symb,MODE_MINLOT);// Мин. размер. лотов
   double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
   double Step   =MarketInfo(Symb,MODE_LOTSTEP);//Шаг изменен размера
   double Free   =AccountFreeMargin();         // Свободные средства
   double LotVal =MarketInfo(Symbol(),MODE_TICKVALUE);//стоимость 1 пункта для 1 лота
   

//--------------------------------------------------------------- 3 --
   if (Lots>0)                                 // Лоты заданы явно..
{                                              // ..проверим это
      double Money=Lots*One_Lot;               // Стоимость открываемого ордера   
      if(Money<=AccountFreeMargin())             // Средств хватает..     
         {  
          Lots_New=Lots;                           // ..принимаем заданное
            // else                                     // Если не хватает..
            // Lots_New=MathFloor(Free/One_Lot/Step)*Step;// Расчёт лотов 
            Print("Функция Lot_MM: Lots_New  = ", Lots_New);    
...
...
...
...
 // ---------НОРМАЛИЗУЕМ НОВЫЕ РАСЧЕТНЫЕ ЛОТЫ И ОТКРЫВАЕМ ОЧЕРЕДНУЮ ПОЗИЦИЮ...            
                    Lots_New = NormalizeLots(Lots_New);  
   return(true);                               // Выход из польз. ф-ии
  }
//--------------------------------------------------------------- 6 --

//+------------------------------------------------------------------+
//| Нормализация лота                                                |
//+------------------------------------------------------------------+

double NormalizeLots(double lot)
{
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   double lots = NormalizeDouble(lot / lotStep, 0) * lotStep;   
   lots = MathMax(lots, MarketInfo(Symbol(), MODE_MINLOT));
   lots = MathMin(lots, MarketInfo(Symbol(), MODE_MAXLOT));   
   return (lots);
}
 

No lo entiendo: imprime la línea superior, pero la orden no se abre con el error 131 - volumen equivocado, ya he puesto 0,1 y 0,01...

 Print ("Функция открытия ордера с рынка - продажа: Teeth = ",  NormalizeDouble(Teeth,Digits), " upfractal = ", upfractal," Цена Bid = ", NormalizeDouble(Bid,Digits), " Lots_New = ", NormalizeDouble(Lots_New,2));                
Ticket=OrderSend(Symbol(),1,0.01,Bid,50,0,0,"Antiunity-start",Magic,0,Red);    

 
Techno:
Cuando se divide por una variable, primero hay que comprobar que no es igual a cero.

Gracias, lo tendré en cuenta en el futuro. Es que esta vez tomé una función de normalización de volumen ya hecha.
 

Hasta ahora no ha servido de nada... Escribe el mismo error...

 Print ("Функция открытия ордера с рынка - продажа: Teeth = ",  NormalizeDouble(Teeth,Digits), " upfractal = ", upfractal," Цена Bid = ", NormalizeDouble(Bid,Digits), " Lots_New = ", NormalizeDouble(Lots_New,2));                
          Ticket=OrderSend(Symbol(),1,Lots_New,Bid,50,0,0,"Antiunity-start",Magic,0,Red);            
          Print ("Функция открытия ордера с рынка - продажа: старт");      

He abierto una posición para el oro en mi cuenta en el probador con 10.000 y 0,01 y 0,1 lotes - en vano.

¿Quizás alguien haya tenido un problema similar? ¿Puedes darme una pista...

 

Añade mi función de comprobación de lotes a tus subrutinas personalizadas. Y llamarlo antes de cada OrderSend(). El redondeo en mi dll se hace por las leyes de las matemáticas: Si el número redondeado termina en parte fraccionaria con número >=5, entonces se redondea hacia arriba. Si es <=4, se redondea hacia abajo. Por lo que entendí los lenguajes de programación tienen problemas con esto por alguna razón - tuve que hacer mi propio código dll. Básicamente, el código es muy simple, pero busqué bastante en Internet en mi época, antes de encontrar la solución óptima. ¿Necesitas el código fuente de la dll?

// ============ ProverkaLota() =====================================================================
// функция принимает нормализует лот ордера
//-----------------------------------------------------
double ProverkaLota(double LotOrdera,string SMB){
  double SMB_MinLot=MarketInfo(SMB,MODE_MINLOT);
  double SMB_MaxLot=MarketInfo(SMB,MODE_MAXLOT);
  double SMB_LotStep=MarketInfo(SMB,MODE_LOTSTEP);
  LotOrdera=OkruglenieDoSotykh(LotOrdera);// округляем до сотых

 if(SMB_LotStep==0.1){// округляем до десятых
   LotOrdera/=10;
   LotOrdera=OkruglenieDoSotykh(LotOrdera);
   LotOrdera*=10;// возвращаем дробную часть ордера на место
 }
 if(LotOrdera<SMB_MinLot){
   LotOrdera=SMB_MinLot;
 }
 if(LotOrdera>SMB_MaxLot){
   LotOrdera=SMB_MaxLot;
 }
 return(LotOrdera);
}
// =================================================================================================
Archivos adjuntos:
basic_dll_1.zip  190 kb
 
drknn:

Añade mi función de comprobación de lotes a tus subrutinas personalizadas. Y llamarlo antes de cada OrderSend(). El redondeo en mi dll se hace por las leyes de las matemáticas: Si el número redondeado termina en parte fraccionaria con número >=5, entonces se redondea hacia arriba. Si es <=4, se redondea hacia abajo. Por lo que entendí los lenguajes de programación tienen problemas con esto por alguna razón - tuve que hacer mi propio código dll. Básicamente, el código es muy simple, pero busqué bastante en Internet en mi época, antes de encontrar la solución óptima. ¿Necesitas el código fuente de la dll?


Sí, gracias.
 
Roman.:

Sí. Gracias.


Lenguaje DLL: Delphi

library basic;

uses
  SysUtils,Windows,Classes,Dialogs;

{$R *.res}

{Обычно в своих программах не требуется менять модель вызова, delphi по
  умолчанию использует более быстрый fastcall, но при импорте функций из других
  библиотек нужно указывать stdcall (или cdecl для сишных библиотек типа
  msvcrt.dll), иначе просто не будет работать, или будет, но неверно}

// --------- Арифметическое округление до сотых ---------
function OkruglenieDoSotykh(d_ChtoOkruglit:Double):Double; stdcall;
var
  d_Rezult:Double;

begin
  d_Rezult:=Int(d_ChtoOkruglit*100+0.55);
  OkruglenieDoSotykh:=d_Rezult/100;
end;

exports OkruglenieDoSotykh;

begin
end.