[ARQUIVO!] Qualquer pergunta de novato, para não desorganizar o fórum. Profissionais, não passem por aqui. Em nenhum lugar sem você - 4. - página 359

 

Rapazes, vocês podem aconselhar:

Ao testar o assessor em indicadores padrão incluídos na entrega MT4 em pares de moedas - sem perguntas - tudo funciona de acordo com o algoritmo de negociação.

Ao testar em metais, como prata e ouro, as ordens não são abertas, no Strategy Tester Journal eles escrevem divisão zero.

Tenho os mesmos parâmetros de entrada, o histórico desta empresa de corretagem de cinco dígitos (forex4yu) foi carregado para os instrumentos testados.

Qual é a razão possível? Não quero enviar minha EA para um telepata. Escrevi pessoalmente o Expert Advisor, de acordo com a versão do livro.

 
Roman.:

Rapazes, vocês podem aconselhar:

Ao testar o assessor em indicadores padrão incluídos na entrega MT4 em pares de moedas - sem problemas - tudo funciona de acordo com o algoritmo de negociação.

Ao testar em metais, como prata e ouro, as ordens não são abertas, no Strategy Tester Journal eles escrevem divisão zero.

Tenho os mesmos parâmetros de entrada, o histórico desta empresa de corretagem de cinco dígitos (forex4yu) foi carregado para os instrumentos testados.

Qual é a razão possível? Não quero enviar minha EA para um telepata. Escrevi pessoalmente o Expert Advisor, de acordo com a versão do livro.

Sempre que se dividir por uma variável, é preciso primeiro verificar se ela não é igual a zero.
 
Roman.:

Rapazes, vocês podem aconselhar:

Ao testar o assessor em indicadores padrão incluídos na entrega MT4 em pares de moedas - sem problemas - tudo funciona de acordo com o algoritmo de negociação.

Ao testar em metais, como prata e ouro, as ordens não são abertas, no Strategy Tester Journal eles escrevem divisão zero.

Tenho os mesmos parâmetros de entrada, o histórico desta empresa de corretagem de cinco dígitos (forex4yu) foi carregado para os instrumentos testados.

Qual é a razão possível? Não quero enviar minha EA para um telepata. Escrevi pessoalmente o Expert Advisor, de acordo com a versão do livro.


Você deve ver o código. Em geral, você pode (no Notepad++) marcar automaticamente todos os locais onde ocorre um sinal de divisão no código e ver se a divisão por zero realmente ocorre em algum caso.
 
drknn:

Eu adoraria ver o código. E em geral, você pode (no Notepad++) marcar automaticamente todos os lugares onde o sinal de divisão aparece no código e verificar se em algum caso a divisão por zero realmente ocorre.


Sim, já estou olhando para as impressões onde o desempacotamento chegou, tudo está bem por lá...

Na função de normalização de volume para metais houve este erro (divisão por zero), agora não está presente, houve outro 131 - volume incorreto, embora definido obviamente = 0,01 lote, eu olho em geral...

Para moedas, esta função de normalização de volume funciona corretamente.... Talvez haja um comum para eles (para metais e moedas)?

//--------------------------------------------------------------------
// 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);
}
 

Não consigo entender: imprime a linha superior, mas a ordem não abre com erro 131 - volume errado, já ajustei 0,1 e 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:
Sempre que se dividir por uma variável, é preciso primeiro verificar se ela não é igual a zero.

Obrigado, terei isso em mente no futuro. É que desta vez eu assumi uma função de normalização de volume pronto.
 

Não adianta até agora... Escreve o mesmo erro...

 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 ("Функция открытия ордера с рынка - продажа: старт");      

Abri uma posição para ouro em minha conta no testador com 10.000 e 0,01 e 0,1 lotes - sem sucesso.

Talvez alguém tenha tido um problema semelhante? Você pode me dar uma dica...

 

Adicione minha função de verificação de lote a suas sub-rotinas personalizadas. E chame-o antes de cada OrderSend(). O arredondamento na minha dll é feito pelas leis da matemática: se o número arredondado terminar em parte fracionada com número >=5, então arredondado para cima. Se <=4, então é arredondado para baixo. Até onde entendi, as linguagens de programação têm problemas com isso por alguma razão - eu tive que fazer meu próprio código dll. Basicamente, o código é muito simples, mas pesquisei bastante na Internet na minha época, antes de encontrar a solução ideal. Você precisa do código fonte da 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);
}
// =================================================================================================
Arquivos anexados:
basic_dll_1.zip  190 kb
 
drknn:

Adicione minha função de verificação de lote a suas sub-rotinas personalizadas. E chame-o antes de cada OrderSend(). O arredondamento na minha dll é feito pelas leis da matemática: se o número arredondado terminar em parte fracionada com número >=5, então arredondado para cima. Se <=4, então é arredondado para baixo. Até onde entendi, as linguagens de programação têm problemas com isso por alguma razão - eu tive que fazer meu próprio código dll. Basicamente, o código é muito simples, mas pesquisei bastante na Internet na minha época, antes de encontrar a solução ideal. Você precisa do código fonte da dll?


Sim. Obrigado.
 
Roman.:

Sim, obrigado.


DLL idioma: 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.