编写免费的EA - 页 13

 
SanAlex:

TOTAL:"来回ADX "3月和4月指标--由于某种原因没有成功。

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

以下是指标本身

下面是一个更好的结果--添加了过滤器(MA和RSI)。

MA 来回 ADX

MA 来回 ADX 1

MA 来回 ADX 2

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

用0.10手

MA 来回 ADX 3

附加的文件:
 
SanAlex:

下面是一个更好的结果--添加了过滤器(MA和RSI)。

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

与地段0.10


晚上好!我注意到你有一个很大的现成的代码库。也许你有一些代码,可以在创建新条的时候确定前一个条的开盘价?问候,弗拉基米尔。

 
MrBrooklin:

晚上好!我注意到你有一个丰富的现成的代码库。也许你有一些代码,可以在创建新条的时候确定前一个条的开盘价?问候,弗拉基米尔。

例如,专家顾问的工作结果是前一栏的价格。

例如,从这个函数来看--专家顾问的结果更糟糕

//+------------------------------------------------------------------+
//| Expert new tick handling function                                |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // last trade processing time + timeout
//--- don't process if timeout
   if(TimeCurrent()>=limit_time)
     {
      //--- check for data
      if(Bars(Symbol(),Period())>2)
        {
         //--- change limit time by timeout in seconds if processed
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }
//+------------------------------------------------------------------+

我甚至不明白我在这里搞砸了什么,但专家顾问依靠戳穿给出了一个更好的结果。

//+------------------------------------------------------------------+
//| Expert new tick handling function                                |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0,ExtTimeOut=0; // last trade processing time + timeout
//--- don't process if timeout
   limit_time=iTime(Symbol(),Period(),0);
   if(ExtTimeOut==limit_time)
      return;
//--- change limit time by timeout in seconds if processed
   if(ExtExpert.Processing())
      ExtTimeOut=limit_time;
  }
//+------------------------------------------------------------------+
 
SanAlex :

晚上好!我是自学成才的,我从示例中获取代码,并通过科学戳的方法完成给自己设定的任务。

例如,从这个函数 - 专家的结果更糟

在这里,我自己不明白我作弊了什么-但是通过戳戳,专家可以更好地显示结果。



   

在这里您可以检查差异 - 仅将上面的示例替换为帖子

- 在这个 EA 中

//+------------------------------------------------------------------+
//|                                    EXP MA Back and forth ADX.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 description "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"

#define MACD_MAGIC 7234102
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//---
input double InpLots          = 0.01 ; // Lots
input int     InpTakeProfit    = 500 ;   // Take Profit (in pips)
input int     InpTrailingStop  = 300 ;   // Trailing Stop Level (in pips)
input int     InpBars          = 1 ;     // Bars
input int     InpMATrendPeriod = 14 ;   // MA trend period
//+------------------------------------------------------------------+
//| MACD Sample expert class                                         |
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected :
   double             m_adjusted_point;             // point value adjusted for 3 or 5 points
   CTrade            m_trade;                       // trading object
   CSymbolInfo       m_symbol;                     // symbol info object
   CPositionInfo     m_position;                   // trade position object
   CAccountInfo      m_account;                     // account info wrapper
   //--- indicators
   int                m_handle_macd;                 // MACD indicator handle
   int                m_handle_ema;                 // moving average indicator handle
   int                m_handle_emas;                 // moving average indicator handle
   //--- indicator buffers
   double             m_buff_MACD_main[];           // MACD indicator main buffer
   double             m_buff_MACD_signal[];         // MACD indicator signal buffer
   double             m_buff_EMA[];                 // EMA indicator buffer
   double             m_buff_EMAS[];                 // EMA indicator buffer
   //--- indicator data for processing
   double             m_macd_current;
   double             m_signal_current;
   double             m_ema_current;
   double             m_ema_previous;
   //---
   double             m_traling_stop;
   double             m_take_profit;

public :
                     CSampleExpert( void );
                    ~CSampleExpert( void );
   bool               Init( void );
   void               Deinit( void );
   bool               Processing( void );

protected :
   bool               InitCheckParameters( const int digits_adjust);
   bool               InitIndicators( void );
   bool               LongClosed( void );
   bool               ShortClosed( void );
   bool               LongModified( void );
   bool               ShortModified( void );
   bool               LongOpened( void );
   bool               ShortOpened( void );
  };
//--- global expert
CSampleExpert ExtExpert;
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert( void ) : m_adjusted_point( 0 ),
   m_handle_macd( INVALID_HANDLE ),
   m_handle_ema( INVALID_HANDLE ),
   m_handle_emas( INVALID_HANDLE ),
   m_macd_current( 0 ),
   m_signal_current( 0 ),
   m_ema_current( 0 ),
   m_ema_previous( 0 ),
   m_traling_stop( 0 ),
   m_take_profit( 0 )
  {
   ArraySetAsSeries (m_buff_MACD_main, true );
   ArraySetAsSeries (m_buff_MACD_signal, true );
   ArraySetAsSeries (m_buff_EMA, true );
   ArraySetAsSeries (m_buff_EMAS, true );
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert( void )
  {
  }
//+------------------------------------------------------------------+
//| Initialization and checking for input parameters                 |
//+------------------------------------------------------------------+
bool CSampleExpert::Init( void )
  {
//--- initialize common information
   m_symbol.Name( Symbol ());                   // symbol
   m_trade.SetExpertMagicNumber(MACD_MAGIC); // magic
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol( Symbol ());
//--- tuning for 3 or 5 digits
   int digits_adjust= 1 ;
   if (m_symbol. Digits ()== 3 || m_symbol. Digits ()== 5 )
      digits_adjust= 10 ;
   m_adjusted_point=m_symbol. Point ()*digits_adjust;
//--- set default deviation for trading in adjusted points
   m_traling_stop    =InpTrailingStop*m_adjusted_point;
   m_take_profit     =InpTakeProfit*m_adjusted_point;
//--- set default deviation for trading in adjusted points
   m_trade.SetDeviationInPoints( 3 *digits_adjust);
//---
   if (!InitCheckParameters(digits_adjust))
       return ( false );
   if (!InitIndicators())
       return ( false );
//--- succeed
   return ( true );
  }
//+------------------------------------------------------------------+
//| Checking for input parameters                                    |
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters( const int digits_adjust)
  {
//--- initial data checks
   if (InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
       printf ( "Take Profit must be greater than %d" ,m_symbol.StopsLevel());
       return ( false );
     }
   if (InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
       printf ( "Trailing Stop must be greater than %d" ,m_symbol.StopsLevel());
       return ( false );
     }
//--- check for right lots amount
   if (InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
     {
       printf ( "Lots amount must be in the range from %f to %f" ,m_symbol.LotsMin(),m_symbol.LotsMax());
       return ( false );
     }
   if ( MathAbs (InpLots/m_symbol.LotsStep()- MathRound (InpLots/m_symbol.LotsStep()))> 1.0 E- 10 )
     {
       printf ( "Lots amount is not corresponding with lot step %f" ,m_symbol.LotsStep());
       return ( false );
     }
//--- warning
   if (InpTakeProfit<=InpTrailingStop)
       printf ( "Warning: Trailing Stop must be less than Take Profit" );
//--- succeed
   return ( true );
  }
//+------------------------------------------------------------------+
//| Initialization of the indicators                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators( void )
  {
//--- create MACD indicator
   if (m_handle_macd== INVALID_HANDLE )
       if ((m_handle_macd= iADX ( NULL , 0 , 14 ))== INVALID_HANDLE )
        {
         printf ( "Error creating MACD indicator" );
         return ( false );
        }
//--- create EMA indicator and add it to collection
   if (m_handle_ema== INVALID_HANDLE )
       if ((m_handle_ema= iMA ( NULL , 0 ,InpMATrendPeriod, 0 , MODE_LWMA , PRICE_CLOSE ))== INVALID_HANDLE )
        {
         printf ( "Error creating EMA indicator" );
         return ( false );
        }
//--- create EMA indicator and add it to collection
   if (m_handle_emas== INVALID_HANDLE )
       if ((m_handle_emas= iMA ( NULL , 0 ,InpMATrendPeriod, 0 , MODE_SMA , PRICE_OPEN ))== INVALID_HANDLE )
        {
         printf ( "Error creating EMA indicator" );
         return ( false );
        }
//--- succeed
   return ( true );
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed( void )
  {
   bool res= false ;
//--- should it be closed?
   if (m_macd_current<m_signal_current && m_ema_current<m_ema_previous)
     {
       //--- close position
       if (m_trade.PositionClose( Symbol ()))
         printf ( "Long position by %s to be closed" , Symbol ());
       else
         printf ( "Error closing position by %s : '%s'" , Symbol (),m_trade.ResultComment());
       //--- processed and cannot be modified
      res= true ;
     }
//--- result
   return (res);
  }
//+------------------------------------------------------------------+
//| Check for short position closing                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed( void )
  {
   bool res= false ;
//--- should it be closed?
   if (m_macd_current>m_signal_current && m_ema_current>m_ema_previous)
     {
       //--- close position
       if (m_trade.PositionClose( Symbol ()))
         printf ( "Short position by %s to be closed" , Symbol ());
       else
         printf ( "Error closing position by %s : '%s'" , Symbol (),m_trade.ResultComment());
       //--- processed and cannot be modified
      res= true ;
     }
//--- result
   return (res);
  }
//+------------------------------------------------------------------+
//| Check for long position modifying                                |
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified( void )
  {
   bool res= false ;
//--- check for trailing stop
   if (InpTrailingStop> 0 )
     {
       if (m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
        {
         double sl= NormalizeDouble (m_symbol.Bid()-m_traling_stop,m_symbol. Digits ());
         double tp=m_position.TakeProfit();
         if (m_position.StopLoss()<sl || m_position.StopLoss()== 0.0 )
           {
             //--- modify position
             if (m_trade.PositionModify( Symbol (),sl,tp))
               printf ( "Long position by %s to be modified" , Symbol ());
             else
              {
               printf ( "Error modifying position by %s : '%s'" , Symbol (),m_trade.ResultComment());
               printf ( "Modify parameters : SL=%f,TP=%f" ,sl,tp);
              }
             //--- modified and must exit from expert
            res= true ;
           }
        }
     }
//--- result
   return (res);
  }
//+------------------------------------------------------------------+
//| Check for short position modifying                               |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified( void )
  {
   bool    res= false ;
//--- check for trailing stop
   if (InpTrailingStop> 0 )
     {
       if ((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
        {
         double sl= NormalizeDouble (m_symbol.Ask()+m_traling_stop,m_symbol. Digits ());
         double tp=m_position.TakeProfit();
         if (m_position.StopLoss()>sl || m_position.StopLoss()== 0.0 )
           {
             //--- modify position
             if (m_trade.PositionModify( Symbol (),sl,tp))
               printf ( "Short position by %s to be modified" , Symbol ());
             else
              {
               printf ( "Error modifying position by %s : '%s'" , Symbol (),m_trade.ResultComment());
               printf ( "Modify parameters : SL=%f,TP=%f" ,sl,tp);
              }
             //--- modified and must exit from expert
            res= true ;
           }
        }
     }
//--- result
   return (res);
  }
//+------------------------------------------------------------------+
//| Check for long position opening                                  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened( void )
  {
   bool res= false ;
//--- check for long position (BUY) possibility
   if (m_macd_current>m_signal_current && m_ema_current>m_ema_previous)
     {
       double price=m_symbol.Ask();
       double tp   =m_symbol.Bid()+m_take_profit;
       //--- check for free money
       if (m_account.FreeMarginCheck( Symbol (), ORDER_TYPE_BUY ,InpLots,price)< 0.0 )
         printf ( "We have no money. Free Margin = %f" ,m_account.FreeMargin());
       else
        {
         //--- open position
         if (m_trade.PositionOpen( Symbol (), ORDER_TYPE_BUY ,InpLots,price, 0.0 ,tp))
             printf ( "Position by %s to be opened" , Symbol ());
         else
           {
             printf ( "Error opening BUY position by %s : '%s'" , Symbol (),m_trade.ResultComment());
             printf ( "Open parameters : price=%f,TP=%f" ,price,tp);
           }
        }
       //--- in any case we must exit from expert
      res= true ;
     }
//--- result
   return (res);
  }
//+------------------------------------------------------------------+
//| Check for short position opening                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened( void )
  {
   bool res= false ;
//--- check for short position (SELL) possibility
   if (m_macd_current<m_signal_current && m_ema_current<m_ema_previous)
     {
       double price=m_symbol.Bid();
       double tp   =m_symbol.Ask()-m_take_profit;
       //--- check for free money
       if (m_account.FreeMarginCheck( Symbol (), ORDER_TYPE_SELL ,InpLots,price)< 0.0 )
         printf ( "We have no money. Free Margin = %f" ,m_account.FreeMargin());
       else
        {
         //--- open position
         if (m_trade.PositionOpen( Symbol (), ORDER_TYPE_SELL ,InpLots,price, 0.0 ,tp))
             printf ( "Position by %s to be opened" , Symbol ());
         else
           {
             printf ( "Error opening SELL position by %s : '%s'" , Symbol (),m_trade.ResultComment());
             printf ( "Open parameters : price=%f,TP=%f" ,price,tp);
           }
        }
       //--- in any case we must exit from expert
      res= true ;
     }
//--- result
   return (res);
  }
//+------------------------------------------------------------------+
//| main function returns true if any position processed             |
//+------------------------------------------------------------------+
bool CSampleExpert::Processing( void )
  {
//--- refresh rates
   if (!m_symbol.RefreshRates())
       return ( false );
//--- refresh indicators
   if ( BarsCalculated (m_handle_macd)< 2 || BarsCalculated (m_handle_ema)< 2 || BarsCalculated (m_handle_emas)< 2 )
       return ( false );
   if ( CopyBuffer (m_handle_macd, 1 ,InpBars, 2 ,m_buff_MACD_main)  != 2 ||
       CopyBuffer (m_handle_macd, 2 ,InpBars, 2 ,m_buff_MACD_signal)!= 2 ||
       CopyBuffer (m_handle_ema, 0 ,InpBars, 2 ,m_buff_EMA)         != 2 ||
       CopyBuffer (m_handle_emas, 0 ,InpBars, 2 ,m_buff_EMAS)       != 2 )
       return ( false );
//   m_indicators.Refresh();
//--- to simplify the coding and speed up access
//--- data are put into internal variables
   m_macd_current   =m_buff_MACD_main[ 0 ];
   m_signal_current =m_buff_MACD_signal[ 0 ];
   m_ema_current    =m_buff_EMA[ 0 ];
   m_ema_previous   =m_buff_EMAS[ 0 ];
//--- it is important to enter the market correctly,
//--- but it is more important to exit it correctly...
//--- first check if position exists - try to select it
   if (m_position.Select( Symbol ()))
     {
       if (m_position.PositionType()== POSITION_TYPE_BUY )
        {
         //--- try to close or modify long position
         if (LongClosed())
             return ( true );
         if (LongModified())
             return ( true );
        }
       else
        {
         //--- try to close or modify short position
         if (ShortClosed())
             return ( true );
         if (ShortModified())
             return ( true );
        }
     }
//--- no opened position identified
   else
     {
       //--- check for long position (BUY) possibility
       if (LongOpened())
         return ( true );
       //--- check for short position (SELL) possibility
       if (ShortOpened())
         return ( true );
     }
//--- exit without position processing
   return ( false );
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ( void )
  {
//--- create all necessary objects
   if (!ExtExpert.Init())
       return ( INIT_FAILED );
//--- secceed
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Expert new tick handling function                                |
//+------------------------------------------------------------------+
void OnTick ( void )
  {
   static datetime limit_time= 0 ,ExtTimeOut= 0 ; // last trade processing time + timeout
//--- don't process if timeout
   limit_time= iTime ( Symbol (), Period (), 0 );
   if (ExtTimeOut==limit_time)
       return ;
//--- change limit time by timeout in seconds if processed
   if (ExtExpert.Processing())
      ExtTimeOut=limit_time;
  }
//+------------------------------------------------------------------+
 
SanAlex:

这里有一个检查差异的方法--只替换上面的例子帖子

- 在这个专家。

谢谢你!我将试一试!问候,弗拉基米尔。

 
在进入和退出锁的问题上都有自己的看法。我在路上遇到的顾问,然后工作不正常,然后突然删除订单,然后突然把它不清楚什么原则。

,想自己写,但不能理解编程。采取的建议,决定开一个单独的分支机构。


顾问的工作条件

1.本身不手动交易所有交易(买和卖)

2.如果交易以+收盘,那么挂单 将被删除。

在挂单设置中采取最小+(可能调整)

3.当挂单触发时----另一个挂单被设置为1个订单的水平(即总数应该相等)

4.如果价格返回并形成锁定----那么所有的takei被删除。

唯一的区别是交易的形状 --- 它看起来像在图表中打开一个封闭的位置。5当打开任何部分的锁,在体积上的待定等于这部分被打开。在运动后15 -20点(调整),即如果我打开买,买的待定,反之亦然。


。很高兴听到任何建议。如果这样一个奇迹出现在光将被张贴为所有谁在它感兴趣的开放源代码。为MT4。
 
开发人员先生们,你们好!我是中风后的残疾人,1g。而且由于环境的原因,我自己根本不可能写出一个猫头鹰。需要一个相当简单的机器人。什么会从我创建的水平中打开姿势。我没有止损,只有相反的交易。算法很有趣,请帮助。第二个机器人将是炸弹,而新闻将是独特的,所有这些都纯粹是我的发展。 那么 以及 等。
 
亲爱的程序员们,你们好。

这个想法已经在我的脑海中酝酿了很久了。我试图手动操作,但我感到很困惑。我确信在交易的任何地方都没有这种算法(第3点)。

1.专家顾问在蜡烛的每一次分解中都会开出订单,高位--买入,低位--卖出。

2.TP等于工作时间框架上的一个ATR。

3.在TP上关闭订单后,专家顾问采取最无利可图的订单和关闭订单的30%的TP(将打印在专家顾问的变量中)。

将亏损订单的TP拖入负区(遵循先取后舍的原则)。

因此,它导致亏损的订单以亏损结束。然后,它再次找到最无利可图的订单,并继续修改它,直到它以亏损关闭。

在每一个这样的系列中,考虑到互换和佣金,我们将获得至少60%的利润。
 

帮助寻找最后的ZigZag信号

double ZigUp, ZigFrDn;
     ZigUp = iCustom(NULL,0,IndName,ExtDepth,ExtDeviation,ExtBackstep,0,1);
   for (int i=1; i<500; i++) 
     ZigDn = iCustom(NULL,0,IndName,ExtDepth,ExtDeviation,ExtBackstep,0,i);

根据条件,如果最后一次向上销售,Dn-buy。

它的工作,然后它不...(它可能根本不起作用)

 
Hi-Fi:

帮助寻找最后的ZigZag信号

根据条件,如果最后一次向上销售,Dn-buy。

它的工作,然后它不...(它可能根本不起作用)

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 07.10.2006                                                     |
//|  Описание : Возвращает номер бара экстремума ЗигЗага по его номеру.        |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (NULL или "" - текущий символ)          |
//|    tf - таймфрейм                  (      0     - текущий ТФ)              |
//|    ne - номер экстремума           (      0     - последний)               |
//|    dp - ExtDepth                                                           |
//|    dv - ExtDeviation                                                       |
//|    bs - ExtBackstep                                                        |
//+----------------------------------------------------------------------------+
int GetExtremumZZBar(string sy="", int tf=0, int ne=0, int dp=12, int dv=5, int bc=3) {
  if (sy=="" || sy=="0") sy=Symbol();
  double zz;
  int    i, k=iBars(sy, tf), ke=0;

  for (i=0; i<k; i++) {
    zz=iCustom(sy, tf, "ZigZag", dp, dv, bc, 0, i);
    if (zz!=0) {
      ke++;
      if (ke>ne) return(i);
    }
  }
  Print("GetExtremumZZBar(): Экстремум ЗигЗага номер ",ne," не найден");
  return(-1);
}
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 07.10.2006                                                     |
//|  Описание : Возвращает экстремум ЗигЗага по его номеру.                    |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (NULL или "" - текущий символ)          |
//|    tf - таймфрейм                  (      0     - текущий ТФ)              |
//|    ne - номер экстремума           (      0     - последний)               |
//|    dp - ExtDepth                                                           |
//|    dv - ExtDeviation                                                       |
//|    bs - ExtBackstep                                                        |
//+----------------------------------------------------------------------------+
double GetExtremumZZPrice(string sy="", int tf=0, int ne=0, int dp=12, int dv=5, int bs=3) {
  if (sy=="" || sy=="0") sy=Symbol();
  double zz;
  int    i, k=iBars(sy, tf), ke=0;

  for (i=1; i<k; i++) {
    zz=iCustom(sy, tf, "ZigZag", dp, dv, bs, 0, i);
    if (zz!=0) {
      ke++;
      if (ke>ne) return(zz);
    }
  }
  Print("GetExtremumZZPrice(): Экстремум ЗигЗага номер ",ne," не найден");
  return(0);
}