Fehler, Irrtümer, Fragen - Seite 3143

 
Wizard #:
Guten Tag, benötigt der Code die Zeile PositionSelectByTicket... Wenn ja, wie schreibe ich die Fahrkarte korrekt hinein, indem ich PositionGetTicket(i) verwende oder diePositionGetInteger(POSITION_TICKET) belasse? Vielen Dank im Voraus!

Seien Sie nicht unhöflich... Steht in der Dokumentation nicht eindeutig

Die Funktion gibt ein Positionsticket durch den Index in der Liste der offenen Positionen zurück und wählt diese Position automatisch für die weitere Arbeit mit ihr aus


Wenn die Position bereits ausgewählt ist, warum sollte sie mit der Funktion PositionSelectByTicket erneut ausgewählt werden?

 
Alexey Viktorov #:

Ich will nicht unhöflich sein... Steht in der Dokumentation nicht eindeutig

Wenn die Position bereits ausgewählt ist, warum sollte sie mit der Funktion PositionSelectByTicket erneut ausgewählt werden?

Vielen Dank für Ihre Antwort! Ich habe mich das gefragt, weil ich in der Bibliothek <Trade/Trade.mqh> nachgesehen habe, dass die Funktion PositionClose(const ulong ticket,const ulong deviation) auch PositionSelectByTicket verwendet. Und die Funktion PositionClose( const ulong ticket,const ulong deviation ) selbst wird von Programmierern oft in Kombination mit der Schleife for(int i = PositionsTotal()-1; i >= 0; i--) verwendet und durchläuft alle Positionen in einer Schleife. Und ich frage mich, ob ich irgendwo ein zusätzliches Exemplar verwende.
 
Wizard #:
Hallo, ist die PositionSelectByTicket Zeile im Code erforderlich... Wenn ja, wie schreibt man einen Fahrschein korrekt hinein, durch PositionGetTicket(i) oder durchPositionGetInteger(POSITION_TICKET)? Vielen Dank im Voraus!
int IsPositions()
{
   int pos = 0;     
   
   int total = PositionsTotal();
   for(int i = total-1; i >= 0; i--)
   {
      if(!PositionGetTicket(i))
         continue;        
          
      if(PositionGetString(POSITION_SYMBOL) == Symbol_T && PositionGetInteger(POSITION_MAGIC) == EXPERT_MAGIC)
         pos = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? 1 : (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) ? -1 : 0;
   }
   
   return(pos);
}
 
Roman #:
Ich danke Ihnen! Daher ist PositionGetTicket(i) ausreichend, undPositionSelectByTicket wird nicht benötigt.
 
Wizard #:
Vielen Dank für Ihre Antwort! Ich begann mich zu wundern, weil ich in der Bibliothek <Trade/Trade.mqh> nachgeschaut habe, dass die Funktion PositionClose(const ulong ticket,const ulong deviation) auch PositionSelectByTicket verwendet. Und die Funktion PositionClose( const ulong ticket,const ulong deviation ) selbst wird häufig von Programmierern in Kombination mit der Schleife for(int i = PositionsTotal()-1; i >= 0; i--) verwendet und durchläuft alle Positionen in einer Schleife. Und ich frage mich, ob ich irgendwo ein zusätzliches Exemplar verwende.

Die Funktion PositionClose(const ulong ticket,const ulong deviation) in der Bibliothek empfängt ein Ticket der zu schließenden Position, aber niemand weiß, wie das Ticket empfangen wurde oder ob die Position existiert.

Daher prüft PositionSelectByTicket meist, ob es etwas zu schließen gibt. Und warum haben Sie beschlossen, dass alle Positionen oft in der Schleife geschlossen werden? Nicht unbedingt...

 
Alexey Viktorov #:

Die Funktion PositionClose(const ulong ticket,const ulong deviation) in der Bibliothek erhält ein Ticket der zu schließenden Position, aber niemand weiß, wie das Ticket empfangen wurde und ob die Position existiert.

Daher prüft PositionSelectByTicket meist, ob es etwas zu schließen gibt. Und warum haben Sie beschlossen, dass alle Positionen oft in der Schleife geschlossen werden? Nicht unbedingt...

Ja, jetzt verstehe ich alles. Ich habe vor kurzem eine EA, ich habe es nach Ihrem Beispiel geschrieben (mit Durchschnitten) aus einem Forum, kombiniert es mit Timur Mashnin's Code. Jetzt habe ich beschlossen, die Bedingungen dort zu ändern und sie ein wenig umzuschreiben, indem ich alles durch Systemfunktionen ohne Bibliotheken ersetze. Wenn bei einem einfachen PositionSelect alles sehr einfach war, eine Position - eine Auswahl, dann brauche ich mit der Schleife hier natürlich mehr Überlegungen und Logik.
 

Hallo

Können Sie mir bitte helfen?

mit dem Code.

Ein Indikator im Testgerät funktioniert richtig

Wenn ich sie in die Tabelle einfüge, wird sie nicht korrekt angezeigt.

Ich kann nicht herausfinden, warum das falsch ist.

//+------------------------------------------------------------------+
//|                                                        Oscil.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property  indicator_buffers 5
#property indicator_plots   5

#property  indicator_color1  clrNONE
#property  indicator_color2  clrRoyalBlue
#property  indicator_color3  clrPink
#property  indicator_color4  clrAqua
#property  indicator_color5  clrYellow

#property  indicator_width1 1
#property  indicator_width2 5
#property  indicator_width3 5
#property  indicator_width4 5
#property  indicator_width5 5

double MainLine[];
double UpLine[];
double DnLine[];
double muls[];
double x,y,z;
double price;
double mulSum=0;
double Pi   = 3.1415926535;
bool LastUp = false;
bool GoUp   = false;
input bool otl    = false;
/***********Range***************/
int    Length             = 3;
int    MajorRangeStrength = 4;


double MajorRangeBuy[];
double MajorRangeSell[];


double RangePrice  = 0.0,
       SweepB      = 0.0;
int    Switch2     = 0,
         SwitchB     = 0;
double Price2BuyA  = 0.0;
int    Price2BuyB  = 1.0;
double Price2SellA = 0.0;
int    Price2SellB = 0.0;
bool   BuySwitchB  = false,
       SellSwitchB = false;
       
int hendlMA_1;
double MA_1[];

int hendlMA_2;
double MA_2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MainLine,INDICATOR_DATA);
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_HISTOGRAM); 
   ArraySetAsSeries(MainLine, true);
   
   SetIndexBuffer(1,UpLine,INDICATOR_DATA);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_HISTOGRAM); 
   ArraySetAsSeries(UpLine, true);
   
   SetIndexBuffer(2,DnLine,INDICATOR_DATA);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_HISTOGRAM); 
   ArraySetAsSeries(DnLine, true);
   
   SetIndexBuffer(3,MajorRangeBuy,INDICATOR_DATA);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetInteger(3,PLOT_DRAW_TYPE,DRAW_HISTOGRAM); 
   ArraySetAsSeries(MajorRangeBuy, true);
   
   SetIndexBuffer(4,MajorRangeSell,INDICATOR_DATA);
   PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetInteger(4,PLOT_DRAW_TYPE,DRAW_HISTOGRAM); 
   ArraySetAsSeries(MajorRangeSell, true);
   
   hendlMA_1=iMA(Symbol(),0,1,0,MODE_LWMA,PRICE_CLOSE);
   ArraySetAsSeries(MA_1,true);
   
   hendlMA_2=iMA(Symbol(),0,1,0,MODE_SMMA,PRICE_CLOSE);
   ArraySetAsSeries(MA_2,true);
   
   ArrayResize(muls, 99);
   
   mulSum = 0;
   
   for (int i0 = 0; i0 < 98; i0++) {//повторяем в цикле 98 раз
      if (i0 <= 18) y = 1.0 * i0 / 18; //если это первые 18 повторений
      else y = (i0 - 18) * 7.0 / 79.0 + 1.0; //иначе
      
      x = MathCos(Pi * y);
      z = 1.0 / (3.0 * Pi * y + 1.0);
      if (y <= 0.5) z = 1;
      
      muls[i0] = z * x;
      mulSum += muls[i0];
   }
   if(otl)Print(" Распределение создано muls[20]=",muls[20]);
//---
   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[])
  {
//---
  if (PeriodSeconds() <60*60 || PeriodSeconds() >10080*60) return(0);
   int depth=0;

   int l_ind_counted_8 = prev_calculated; //Возвращает количество баров, не измененных после последнего вызова индикатора.
   
   int bars=Bars(Symbol(),PERIOD_CURRENT);
   if (l_ind_counted_8 < 0) return (0);
   if (l_ind_counted_8 == 0)
      {
         depth = bars - 98;
         for(int a=0;a<bars;a++)
            {
               MainLine[a] = 0;
               UpLine[a] = 0;
               DnLine[a] = 0;
               MajorRangeBuy[a]=0;
               MajorRangeSell[a]=0;
            }
      }
   if (l_ind_counted_8 > 0)  depth = bars - l_ind_counted_8;
   if(otl)Print(" количество баров, не измененных после последнего вызова индикатора= ",l_ind_counted_8,"  Количество баров на текущем графике Bars=",bars,"  depth= ",depth);
   if (l_ind_counted_8 < 1) {
      for (int i2 = 1; i2 < 100; i2++) {
         MainLine[bars - i2] = 0;
         UpLine[bars - i2] = 0;
         DnLine[bars - i2] = 0;
      }
   }
   
   for (int i1 = depth; i1 >= 0; i1--) 
   {
      price = 0;
          
          CopyBuffer(hendlMA_1,0,0,bars,MA_1);
          
      for (int i2 = 0; i2 <= 98; i2++) 
         {
            if(i2 + i1>=bars)break;
            price += muls[i2] * MA_1[i2 + i1];
         }
          
      if (mulSum > 0.0) MainLine[i1] = price / mulSum;

     GoUp=MainLine[i1 + 1] > MainLine[i1] ;
     
      if (GoUp) 
      {
         if (!LastUp) DnLine[i1+1] = MainLine[i1+1];
         DnLine[i1] = MainLine[i1];
         UpLine[i1] = 0;
      }
         else
      {
         if (LastUp) UpLine[i1+1] = MainLine[i1+1];
         UpLine[i1] = MainLine[i1];
         DnLine[i1] = 0;
      }
      LastUp=GoUp; 

   }//  for (int i1

 //  return (0);

/***************** Range **********************/

  int counted_bars=prev_calculated;
  if(otl)Print(" Range counted_bars = ", counted_bars);
   if(counted_bars<0) return(-1);
   int position=bars-counted_bars;
   if (position<0) position=0;
   if (position==0) position=1;
   int rnglength = 250;
   double range = 0.0, srange = 0.0;
   if(otl) Print(" position=",position);
   
   for (int pos = position; pos >=0; pos--)
   {/***************** MAIN Range **********************/
      srange = 0.0;
      int j = 0;
      for (int i=0;i<rnglength;i++)
      {
         j++;
         int posr = pos + i;
         if (posr >= bars) break; 
         srange = srange + (High(posr) - Low(posr));
      }
      range = srange / j * Length;
      int BarNumber = bars-pos; //??????????
      if (BarNumber < 0)  BarNumber = 0;
          
          CopyBuffer(hendlMA_2,0,0,bars,MA_2);
          //Print(bars," - ",pos);
      if(pos<bars)RangePrice = MA_2[pos];  //Moving Average MODE_SMMA
      else RangePrice = MA_2[pos-1];

      if (BarNumber == 1)
      {
         SweepB  = range *  MajorRangeStrength;
         Price2BuyA = RangePrice;
         Price2SellA = RangePrice;
      }     

      if (BarNumber > 1)
      {

         if (Switch2  >  - 1)//проверка цикла на покупку
         {
            if (RangePrice < Price2BuyA) //если средняя цена ниже
            {
if (BuySwitchB ) MajorRangeBuy [pos +BarNumber - Price2BuyB] = 0;                                                                //OUT
                           Price2BuyA = RangePrice;
               Price2BuyB = BarNumber;
               BuySwitchB = true;
            } 
            else if (RangePrice > Price2BuyA)
            {
                            SwitchB = BarNumber - Price2BuyB;
MajorRangeBuy [pos +SwitchB] = MainLine[pos + SwitchB]*1.0005;                                                                                                                          //OUT
                BuySwitchB = true;

                              if (RangePrice - MA_2[pos + SwitchB] >= SweepB && SwitchB >= 1)
                              {
                     Switch2 =  - 1;
                     Price2SellA = RangePrice;
                     Price2SellB = BarNumber;
                     SellSwitchB = false;
                     BuySwitchB = false;
               }
            }
         }
         if (Switch2  < 1)//проверка цикла на продажу
         {
            if (RangePrice  > Price2SellA )
            {
if (pos +BarNumber - Price2SellB<bars&&SellSwitchB ) MajorRangeSell [pos +BarNumber - Price2SellB] = 0;                                                         //OUT
                           Price2SellA = RangePrice;
               Price2SellB = BarNumber;
               SellSwitchB = true;
                    }
                       else if (RangePrice < Price2SellA)
                    {
               SwitchB = BarNumber - Price2SellB ;

         if(pos+ SwitchB<bars)MajorRangeSell[pos + SwitchB] =MainLine[pos + SwitchB]*1.0005;                                                                                                                             //OUT
                SellSwitchB = true;             
        
                              if (pos + SwitchB<bars&&MA_2[pos + SwitchB] - RangePrice >= SweepB && SwitchB >= 1)
                              {
                                     Switch2 = 1;
                     Price2BuyA = RangePrice;
                     Price2BuyB = BarNumber;
                     SellSwitchB = false;
                     BuySwitchB = false;
                                  }
            }
         }
      }

   //   MajorRangeSell[pos] = 0;
    //  MajorRangeBuy[pos]  = 0;  
    }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//========================================================================================
double High(int index)
{   
   if(index < 0) return(-1);
   double Arr[];
   ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT;
   if(CopyHigh(Symbol(),timeframe, index, 1, Arr)>0) 
        return(Arr[0]);
   else return(-1);
}
//========================================================================================
double Low(int index)
{   
   if(index < 0) return(-1);
   double Arr[];
   ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT;
   if(CopyLow(Symbol(),timeframe, index, 1, Arr)>0) 
        return(Arr[0]);
   else return(-1);
}
 

Was wird an die MqlTradeCheckResult-Struktur zurückgegeben?

In der Dokumentation heißt es: "Der Betrag der Marge, der für die gewünschte Handelsoperation erforderlich ist".

Feld

Beschreibung

retcode

Rückgabecode

Bilanz

Saldowert, der sich nach Ausführung des Geschäfts ergibt

Eigenkapital

Wert desEigenkapitals, der sich nach der Ausführung des Geschäfts ergeben wird

Gewinn

Wert des schwebenden Gewinns, der sich nach der Ausführung des Geschäfts ergeben wird

Marge

die Höhe der für das gewünschte Geschäft erforderlichen Marge

margin_free

Der Betrag des Eigenkapitals, der nach der Ausführung des gewünschten Geschäfts verbleibt

margin_level

Die Höhe der Marge, die nach der Ausführung des gewünschten Geschäfts festgelegt wird

Kommentar

Kommentar zum Antwortcode, Fehlerbeschreibung


Was man aber tatsächlich erhält, ist die Größe des gesamten Spielraums, des aktuellen und desjenigen, der nach der Ausführung der Operation genommen wird.

Hier ist das Skript

#include <Trade\Trade.mqh>
CTrade trade;
  MqlTradeRequest           my_request;
  MqlTradeCheckResult       my_check_result;
  MqlTick                   mqlTick;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
 {
  SymbolInfoTick(_Symbol, mqlTick);
  CheckOrder(0.01, ORDER_TYPE_SELL);
  Print(my_check_result.margin);
//---
  trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, 0.01, mqlTick.bid, 0.0, 0.0);
//---
  CheckOrder(0.01, ORDER_TYPE_SELL);
  Print(my_check_result.margin);
 }/******************************************************************/

/********************************************************************\
||
\********************************************************************/
bool CheckOrder(double volume, ENUM_ORDER_TYPE order_type)
 {
  if(order_type != ORDER_TYPE_BUY && order_type != ORDER_TYPE_SELL)
    return false;
  ZeroMemory(my_request);
  ZeroMemory(my_check_result);
  bool checkOrder = false;
//--- setting my_request
  my_request.action = TRADE_ACTION_DEAL;
  my_request.symbol = _Symbol;
  my_request.volume = volume;
  my_request.type   = order_type;
  my_request.price  = order_type == ORDER_TYPE_BUY ? mqlTick.ask : mqlTick.bid;
  checkOrder = ::OrderCheck(my_request, my_check_result);
  if(my_check_result.retcode != 0)
    return(false);
//---
  return(true);
 }/******************************************************************/

und das Ergebnis der Ausführung

2022.02.01 10:11:28.002 Test bag (EURUSD,H1)    2.25
2022.02.01 10:11:28.108 Test bag (EURUSD,H1)    4.5

Wenn keine offenen Positionen auf dem Konto sind, entspricht my_check_result.margin der Marge für die offene Position mit Lot 0,01, und wenn bereits 0,01 auf dem Konto sind, entspricht die Marge für Lot 0,02

Dateien:
Test_bag.mq5  5 kb
 
Alexey Viktorov #:

Was Sie aber tatsächlich erhalten, ist die Höhe der gesamten Marge, die derzeitige und diejenige, die nach Abschluss der Operation genommen wird.

Richtig.

MarginOpen = CheckResult.margin - ::AccountInfoDouble(ACCOUNT_MARGIN); // Маржа для открытия.
 
fxsaber #:

Richtig.

Lassen Sie es so sein, aber dann sollte es auch in der Dokumentation so sein.

Wenn balans der Wert des Saldos ist , der sich nach Abschluss des Handels ergibt

dann Marge - sein sollte. Margin-Wert, der sich nach der Ausführung des Geschäfts ergibt