错误、漏洞、问题 - 页 3143

 
Wizard #:
下午好!代码中是否需要PositionSelectByTicket这行...如果是这样,我如何在里面正确写票,使用PositionGetTicket(i)或离开PositionGetInteger(POSITION_TICKET)?提前感谢您!

不要无理取闹......文件不是明确规定了吗?

该函数返回一个由未结头寸列表中的索引组成的头寸票,并自动选择该头寸进行进一步的工作


如果已经选择了位置,为什么还要用PositionSelectByTicket函数重新选择?

 
Alexey Viktorov #:

不要无理取闹......文件不是明确规定了吗?

如果已经选择了位置,为什么还要用PositionSelectByTicket函数重新选择?

谢谢你的答复我想知道,因为在<Trade/Trade.mqh>库中查看,PositionClose(const ulong ticket,const ulong deviation)函数也使用了PositionSelectByTicket。而PositionClose(const ulong ticket,const ulong deviation)函数本身也经常被编码者与循环系统结合使用,for(int i = PositionsTotal()-1; i >= 0; i--),在所有的位置上循环往复。而且我在想,我是不是在什么地方多用了一个。
 
Wizard #:
你好,PositionSelectByTicket这一行在代码中是否需要...如果是这样,如何通过PositionGetTicket(i)或离开PositionGetInteger(POSITION_TICKET)正确地在里面写票?提前感谢!
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 #:
谢谢你!所以PositionGetTicket(i)就足够了,PositionSelectByTicket就不需要了
 
Wizard #:
谢谢你的回答!我开始怀疑,因为在<Trade/Trade.mqh>库中看过,PositionClose(const ulong ticket,const ulong deviation)函数也使用PositionSelectByTicket。而PositionClose(const ulong ticket,const ulong deviation)函数本身也经常被编码者与循环系统结合使用,for(int i = PositionsTotal()-1; i >= 0; i--),在所有的位置上循环往复。而且我在想,我是不是在什么地方多用了一个。

库中的PositionClose(const ulong ticket,const ulong deviation)函数收到了要关闭的位置的票据,但没有人知道票据是如何收到的,也没有人知道这个位置是否存在。

因此PositionSelectByTicket主要检查是否有东西要关闭。还有,为什么你决定所有的职位都经常在循环中关闭?不一定...

 
Alexey Viktorov #:

库中的PositionClose(const ulong ticket,const ulong deviation)函数收到了要关闭的位置的票据,但没有人知道票据是如何收到的,以及该位置是否存在。

因此PositionSelectByTicket主要检查是否有东西要关闭。还有,为什么你决定所有的职位都经常在循环中关闭?不一定...

是的,我现在都明白了。我最近有一个EA,我是按照你在一个论坛上的例子(带平均数)写的,与Timur Mashnin的代码相结合。现在我决定改变那里的条件,把它们重写一下,用系统函数取代一切,不使用库。如果说简单的PositionSelect一切都很简单,一个位置--一个选择,那么在这里的循环,我当然需要更多的考虑和逻辑。
 

你好

能否请您帮助我

与代码。

在测试器中做了一个正常工作的指标

当我把它放在图表上时,它不能正确显示。

搞不清楚为什么会出错。

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

向MqlTradeCheckResult结构返回什么?

文件 中写道:"所需 交易操作的保证金数额"。

场地

描述

转码

返回代码

平衡

交易执行后的余额值

股权

股权 的价值,这将是执行交易后的价值

利润

执行交易后将有的浮动利润值

边缘

所需交易操作所需的保证金数额

无保证金

在执行所需的交易后,将剩下的股本数额

margin_level

执行所需交易后设定的保证金水平

评论

对响应代码的评论,错误描述


但实际得到的是总保证金的大小,当前的和加上执行操作后的保证金。

以下是脚本

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

和执行的结果

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

当账户中没有未结头寸时,my_check_result.margin等于手数为0.01的未结头寸的保证金,而当账户中已经有0.01时,手数为0.02的保证金。

附加的文件:
Test_bag.mq5  5 kb
 
Alexey Viktorov #:

但你真正得到的是总的保证金的大小,目前的和加上这个操作完成后将采取的。

对。

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

对。

就这样吧,但这样一来,在文件中也应该是这样的。

如果balans是交易完成后的余额的价值

那么保证金--应该是。保证金价值, 将是执行交易操作后的价值。