初学者的问题 MQL5 MT5 MetaTrader 5 - 页 1322

 
下午好,有很多相同类型的指标缓冲区,可以在循环中进行计算,但如何将指标缓冲区做成一个数组?我已经通过页面结构进行了尝试,一切都很好,SetIndexBuffer()没有出错,但是当OnCalculate()到来时,数组大小没有变化,仍然是0。请教如何在循环中组织指标缓冲区的计算,也许可以用名称,如:"buff_0"、"buff_1 " 等,但如何做到这一点我不知道((否则,就会出现一个很长的表单了(
 
SanAlex:

我猜这就是你的想法--似乎已经成功了。

谢谢!

一切都是正确的,但不完全是我 的想法!!订单沿着趋势放置(根据指标),并在采取时关闭,一旦关闭 - 一个新的订单在同一方向(沿着趋势)打开,但这只是我想法的一部分。

第二部分是,当趋势逆转时(当指标给出价格方向改变的信号时),没有被武井关闭 的订单不应该被关闭(你已经做了)。

简而言之,这两部分应该作为一对来工作。

 
Alexey Viktorov:

昨天我下载了这个奇迹来观看......突然间我就没有网络了。一场雷雨过后,我在当天剩下的时间里都有技术工作。所以我决定用MQL5重写它,并在这里 发表。

因此,每朵云都有一线生机.........

非常感谢您!

如果我的想法成真,它可能会派上用场。

 
VANDER:
通过网页试了一下,似乎工作正常

这不就是它的作用吗?

int size=100;

struct All
   {
   double buff[];
   } all[];

int OnInit()
   {
   IndicatorBuffers(size);
   ArrayResize(all,size);
   for(int i=0; i<size; i++)
      {
      SetIndexBuffer(i,all[i].buff);
      SetIndexStyle(i,DRAW_LINE);
      }
   return(INIT_SUCCEEDED);
   }

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[])
   {
   for(int i=0; i<size; i++)
      {
      all[i].buff[shift]=i;
      }
   return(rates_total);
   }
 

Sprut 185:

现在我们要对其应用马丁格尔法,即以一定的步长、倍数和取平均数来开立非趋势性订单。

简而言之,这两个部分应该成对工作。

你是说下一个仓位应该在买入时以双倍手数2-4-8-16开仓,卖出时以相反的2-4-8-16开仓?

我有这样的功能--不知何故自己建造的。

//+------------------------------------------------------------------+
//| ENUM_LOT_RISK                                                    |
//+------------------------------------------------------------------+
enum LotMax
  {
   Lot=0,   // Lots
   Lotx2=1, // Lots*2
   Risk=2,  // Risk
  };
//+------------------------------------------------------------------+
input LotMax InpLotRisk              = Risk;         // : Lots,- Lots*2,- Risk
input double MaximumRisk             = 0.02;         // : Maximum Risk in percentage
input double DecreaseFactor          = 3;            // : Descrease factor
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- select lot size
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);
   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      //--- select history for access
      HistorySelect(0,TimeCurrent());
      //---
      int    orders=HistoryDealsTotal();  // total history deals
      int    losses=0;                    // number of losses orders without a break
      for(int i=orders-1; i>=0; i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- check symbol
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- check Expert Magic number
         if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=UNO_MAGIC)
            continue;
         //--- check profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- normalize and check limits
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);
   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;
   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- return trading volume
   return(lot);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double OptimizedBuy(void)
  {
   double PROFIT_BUY=0.00;
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of open positions
     {
      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol позиции
      if(position_GetSymbol==m_symbol.Name())
        {
         if(m_position.PositionType()==POSITION_TYPE_BUY)
           {
            PROFIT_BUY=PROFIT_BUY+m_position.Select(Symbol());
           }
        }
     }
   double Lots=MaximumRisk;
   double ab=PROFIT_BUY;
   switch(InpLotRisk)
     {
      case Lot:
         Lots=MaximumRisk;
         break;
      case Lotx2:
         if(ab>0 && ab<=1)
            Lots=MaximumRisk*2;
         if(ab>1 && ab<=2)
            Lots=MaximumRisk*4;
         if(ab>2 && ab<=3)
            Lots=MaximumRisk*8;
         if(ab>3)
            Lots=TradeSizeOptimized();
         break;
      case Risk:
         Lots=TradeSizeOptimized();
         break;
     }
   return(Lots);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double OptimizedSell(void)
  {
   double PROFIT_SELL=0.00;
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of open positions
     {
      string   position_GetSymbol=PositionGetSymbol(i); // GetSymbol позиции
      if(position_GetSymbol==m_symbol.Name())
        {
         if(m_position.PositionType()==POSITION_TYPE_SELL)
           {
            PROFIT_SELL=PROFIT_SELL+m_position.Select(Symbol());
           }
        }
     }
   double Lots=MaximumRisk;
   double ab=PROFIT_SELL;
   switch(InpLotRisk)
     {
      case Lot:
         Lots=MaximumRisk;
         break;
      case Lotx2:
         if(ab>0 && ab<=1)
            Lots=MaximumRisk*2;
         if(ab>1 && ab<=2)
            Lots=MaximumRisk*4;
         if(ab>2 && ab<=3)
            Lots=MaximumRisk*8;
         if(ab>3)
            Lots=TradeSizeOptimized();
         break;
      case Risk:
         Lots=TradeSizeOptimized();
         break;
     }
   return(Lots);
  }
//+------------------------------------------------------------------+

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

你需要在开仓时 替换,这里用OptimizedBuy()和OptimizedSell()代替InpLots。

      if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,OptimizedBuy(),price,0.0,0.0))
      if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,OptimizedSell(),price,0.0,0.0))
 
SanAlex:

你的意思是下一个仓位将以双倍的手数2-4-8-16开仓买入,相反2-4-8-16开仓卖出?

我有这样的功能--不知何故自己建造的。

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

你需要在开仓 时用OptimizedBuy()和OptimizedSell()代替InpLots()来取代它。

但对于这个功能,最好是有这样的功能--它将在盈利时关闭(以货币计)。

input double InpTProfit              = 40000;        // : Take Profit --> (In currency the amount)
input double InpSLoss                = 1000000;      // : Stop Loss --> (In currency the amount)
//+------------------------------------------------------------------+
//| ProfitOnTick closing                                             |
//+------------------------------------------------------------------+
void ProfitOnTick(void)
  {
//---
   double PROFIT_BUY=0.00;
   double PROFIT_SELL=0.00;
   int total=PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      string   position_GetSymbol=PositionGetSymbol(i);
      if(position_GetSymbol==m_symbol.Name())
        {
         if(m_position.PositionType()==POSITION_TYPE_BUY)
           {
            PROFIT_BUY=PROFIT_BUY+PositionGetDouble(POSITION_PROFIT);
           }
         else
           {
            PROFIT_SELL=PROFIT_SELL+PositionGetDouble(POSITION_PROFIT);
           }
        }
      if(PROFIT_BUY<-InpSLoss || PROFIT_BUY>=InpTProfit)
        {
         CheckForCloseBuy();
        }
      if(PROFIT_SELL<-InpSLoss || PROFIT_SELL>=InpTProfit)
        {
         CheckForCloseSell();
        }
     }
  }
//+------------------------------------------------------------------+
 
SanAlex:

但对于这个功能,最好是有这样的功能,它将在利润(以货币计)上关闭

让我试着更清楚地解释我的想法和我正在创建的EA 的运作的意义。

你需要一个简单的马丁--例如AutoProfit 3,在其中你只需要添加,开单是基于指标信号(根据趋势),但不是像AutoProfit那样--因为牌落在.........,就这样。

与所附文件中的输出参数大致相同。
附加的文件:
pbx0dcw.jpg  201 kb
 
Sprut 185:

让我试着更清楚地解释我的想法和创建的EA的 工作的意义。

你需要一个简单的马丁--例如AutoProfit 3,在其中你只需要加上开单是在指标(趋势)的信号上,而不是像AutoProfit那样--因为卡在.........,就可以了。

因此,它在指标的信号下打开 - 但如果出现相反的信号,它将在另一个方向打开。如果信号翻转到另一边,关闭了那个开放的位置,它就不会对你起作用。

 
SanAlex:

如果信号转向另一个方向,它将在另一个方向开仓,如果该仓位没有获利平仓,它将挂在那里,直到它获利平仓。如果给对方一个信号,把那个开放的位置翻过来关闭,那就不适合你了。

对..........,如果该仓位没有获利平仓,它将停留在那里直到获利平仓

但未获利平仓的头寸(例如,买入)应保留并下降到某一步骤,在该步骤中以倍增的成交量和平均时间损失等开立另一个订单(买入),直到趋势逆转,但在轨道上开立的头寸 将不会停止。

这就是为什么我写道,2个区块应该同时工作--马丁和按指标。

如果我没有很好地解释什么--我准备在Skype上演示,并向你展示它应该是什么样的。

 
Sprut 185:

一切都是正确的..........,如果该仓位没有获利平仓,它就会一直留在那里,直到获利平仓

但没有获利平仓的头寸(例如买入)应该保留并下降到一定的台阶,这时另一个订单将以倍增的成交量打开(买入),平均时间将下降,等等,直到趋势逆转,但交易中的开仓 不会停止。

这就是为什么我写道,2个区块应该同时工作--马丁和按指标。

如果有些东西没有得到很好的解释--我准备在Skype上演示,向你展示它应该是什么样子。

马丁必须只有在指示器信号相反或不依赖它时才会被激活?

例子:我根据指标开了一个买入头寸。价格已经向下移动了设定的距离,而指标已经显示为卖出。是否应该打开买入仓位?