Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 566

 
Vitaly Muzichenko:

Essayez la fonction :

Ce n'est pas si simple si vous utilisez la fonction à la fois sur les devises et les contrats à terme. Il y a un pourcentage de marge à prendre en compte.


 
Alexey Viktorov:

Ce n'est pas si simple si vous utilisez la fonction à la fois sur les devises et les contrats à terme. Il faut tenir compte du pourcentage de la marge.

Si nous parlons du pourcentage de perte, nous ne sommes pas intéressés par la marge, elle sera restituée lorsque la position sera fermée.

 
Vitaly Muzichenko:

Si nous parlons de pourcentage de perte, nous ne sommes pas intéressés par la marge, elle reviendra lorsque la position sera fermée.

J'ai dû trop dormir... ou ne s'est pas encore réveillé...
 
Alekseu Fedotov:

Peut-être

Comment ? Dites-moi s'il vous plaît !
 
Nikolay Gaylis:

Je suis désolé que ce soit tout ce que vous ayez remarqué.)

Et je ne suis pas le seul, le Terminal ne voit pas la différence, en soi. La sortie à l'extérieur du tableau est toujours là.

 
Vitaly Muzichenko:

Essayez la fonction :

Merci pour votre aide ! Malheureusement, il n'était pas possible de mettre en œuvre une solution universelle, j'ai dû procéder de cette manière :

input double MaximumRisk=0.02;                  //Риск в сделке от депозита

{
 double TickValue   =MarketInfo(Symbol(),MODE_TICKVALUE),
        TickSize    =MarketInfo(Symbol(),MODE_TICKSIZE),
        ContractSize=MarketInfo(Symbol(),MODE_LOTSIZE),
        Min_Lot     =MarketInfo(Symbol(),MODE_MINLOT),
        Max_Lot     =MarketInfo(Symbol(),MODE_MAXLOT),
        Step        =MarketInfo(Symbol(),MODE_LOTSTEP);

 {
//Для пар XXXUSD, USDXXX, XAUUSD, XAGUSD, CRYPTO, для кроссов
Lots = NormalizeDouble((((AccountBalance()*MaximumRisk)/(MathAbs(Price-SL)/Point))/TickValue),int(MathAbs(log(Step))));
//Для перечисленного в if
if (Symbol() == "BRN" || Symbol() == "WTI" || Symbol() == "NG" || Symbol() == "NIKK225" || Symbol() == "SPX500")
{Lots = NormalizeDouble(((((AccountBalance()*MaximumRisk))/MathAbs(Price-SL)))/(ContractSize/TickValue),1);}
//Для перечисленного в if
if (Symbol() == "ASX200" || Symbol() == "CAC40" || Symbol() == "NQ100" || Symbol() == "STOXX50" || Symbol() == "DAX30"
 || Symbol() == "FTSE100"  || Symbol() == "IBEX35")
{Lots = NormalizeDouble(((((AccountBalance()*MaximumRisk))/MathAbs(Price-SL)))/(TickValue/TickSize/Point),1);}
 }
}

Pouvez-vous me dire si mon courtier a un effet de levier flottant, comment puis-je le prendre en compte dans le calcul des lots ? Ou cela n'aura-t-il pas d'incidence si vous optez pour l'option ci-dessus ?

 

Un autre indicateur, également en dehors de la plage.

Il s'affiche sur le graphique sans problème, mais lorsque je l'appelle depuis l'EA, le message suivant s'affiche : ...array out of range in 'HiLo.mq4' (121,15).

Quel est le problème ?

#property copyright "Copyright ©  november 2015"
#property strict 

#property indicator_chart_window
#property indicator_buffers 6

#property indicator_color1 RoyalBlue       //DodgerBlue
#property indicator_color2 Crimson         //OrangeRed
#property indicator_color3 Black  //White
#property indicator_color4 Black  //White
#property indicator_color5 Black            //White
#property indicator_color6 Black         //Red

#property indicator_width1 2
#property indicator_width2 2

#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_DOT

input int    p        = 10;    // Период
input int    s        = 5;     // Угол наклона
input double distance = 2.0;   // Ширина канала
input bool   showBb   = false;  // Границы канала
input bool   showCl   = true;  // Центральная линия
input int    barsig   = 1;     // Сигнальная свеча (номер)
input int    arrots   = 0;    // Стрелка (отступ)
input int    arrsz    = 0;     // Стрелка (размер)
input int    ATR      = 1000;  // Период ATR
input int    cb       = 1000;  // Сколько свечей в истории

double fx1[],fx2[],hp[];
double z1,z2,ki;
int fs;

double upper[],lower[];
double upar[],dnar[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- indicator buffers mapping
IndicatorBuffers(7);
SetIndexBuffer(0,fx1);
SetIndexBuffer(1,fx2);
SetIndexBuffer(2,lower);
SetIndexBuffer(3,upper);
SetIndexBuffer(4,upar);
SetIndexBuffer(5,dnar);
SetIndexBuffer(6,hp);

SetIndexStyle (4,DRAW_ARROW,0,arrsz);
SetIndexArrow (4,233);
SetIndexStyle (5,DRAW_ARROW,0,arrsz);
SetIndexArrow (5,234);

   if(showBb)
   {SetIndexStyle(2,DRAW_LINE);
    SetIndexStyle(3,DRAW_LINE);
   }
   else
   {SetIndexStyle(2,DRAW_NONE);
    SetIndexStyle(3,DRAW_NONE);
   }
   
    if(showCl)
   {SetIndexStyle(0,DRAW_LINE);
    SetIndexStyle(1,DRAW_LINE);
   }
   else
   {SetIndexStyle(0,DRAW_NONE);
    SetIndexStyle(1,DRAW_NONE);
   }

SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);

//---
   return(INIT_SUCCEEDED);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int i;
   
   SetIndexDrawBegin(0,Bars-cb);
   SetIndexDrawBegin(1,Bars-cb);

double avg;

ki=2.0/(p+1);

for (i=cb; i>=0; i--) {fx1[i]=Close[i];}

for (int m=0; m<=s; m++)
{
z1=fx1[0];
for (i=0; i<=cb; i++) {z1=z1+(fx1[i]-z1)*ki; hp[i]=z1;}

z2=fx1[cb];
for (i=cb; i>=0; i--) {z2=z2+(fx1[i]-z2)*ki; fx1[i]=(hp[i]+z2)/2;}
}

fs=0;
for (i=cb; i>=0; i--)
{
if (fx1[i]>fx1[i+1]) fs=1;
if (fx1[i]<fx1[i+1]) {if (fs==1) fx2[i+1]=fx1[i+1]; fs=2;}
if (fs==2) fx2[i]=fx1[i]; else fx2[i]=0.0;

avg = iATR(NULL,0,ATR, i+10);
upper[i] = hp[i] + distance*avg;
lower[i] = hp[i] - distance*avg;

if(Close[i+1+barsig]<upper[i+1+barsig] && Close[i+barsig]>upper[i+barsig])
 dnar[i] = High[i]+arrots*Point; else dnar[i] = EMPTY_VALUE;
 
if(Close[i+1+barsig]>lower[i+1+barsig] && Close[i+barsig]<lower[i+barsig])
 upar[i] = Low[i]-arrots*Point; else upar[i] = EMPTY_VALUE; 
}

//--- return value of prev_calculated for next call
   return(rates_total);
  }

 
PolarSeaman:

Un autre indicateur, également en dehors de la plage.

Il s'affiche sur le graphique sans problème, mais lorsque je l'appelle depuis l'EA, le message suivant s'affiche : ...array out of range in 'HiLo.mq4' (121,15).

Quel est le problème ?


Il ne vérifie pas s'il y a 1000 barres sur le graphique. Par exemple, au moment de l'ouverture du terminal, il y a 0 barre dans tous les graphiques, mais le terminal a déjà lancé les indicateurs (je ne sais pas pourquoi il fait cela, mais c'est un fait). Par conséquent, tout accès aux tampons des indicateurs entraîne un dépassement des tableaux de séries chronologiques.

 
Ihor Herasko:

Il n'est pas vérifié qu'il y a 1000 barres sur le graphique. Par exemple, au moment de l'ouverture du terminal, il n'y a pas de barres dans tous les graphiques, mais le terminal a déjà commencé les indicateurs (on ne sait pas pourquoi il fait cela, mais c'est un fait). Par conséquent, tout accès aux tampons des indicateurs entraîne la sortie des tableaux de séries chronologiques.

if(Bars<cb)return(0);

Il se plante toujours.

 
PolarSeaman:

Il se plante toujours.

Parce que le chèque est fondamentalement faux. Disons que Bars rapporte 1000 et que cb rapporte également 1000. Puis dans la boucle, à la première itération, j'obtiens la valeur 1000. Dans la première condition du corps de la boucle :

if (fx1[i]>fx1[i+1]) fs=1;

Deux sorties hors du tableau à la fois : accès à une barre d'indice 1000 et à une barre d'indice 1001. Par exemple, si le graphique comporte 1000 barres, la première barre a l'indice 0 et la dernière l'indice 999.

Plus loin dans le corps de la boucle, on trouve une référence aux barres encore plus lointaines de l'histoire :

if(Close[i+1+barsig]<upper[i+1+barsig] && Close[i+barsig]>upper[i+barsig])

Tout cela doit être pris en compte lors de la vérification initiale.

Pour une vérification correcte, voir l'exemple de la fonction IndicatorCounted() dans la référence MQL4. Ce n'est que maintenant qu'il est préférable de remplacer IndicatorCounted() par l'utilisation conjointe des variables rates_total (c'est Bars) et prev_calculated (c'est IndicatorCounted()).