Из серии "не знал но забыл"

 

Существует стандартный индикатор Хайкен - Аши

Появилось желание прикрутить туда звуковой сигнал из терминала при изменении цвета свечи. Непонятны некоторые моменты.

1) а где указатель что "сейчас рисуем белым цветом а сейчас красным" чтобы к ним привязать playsound на изменение окраски. Я не понимаю как они меняются.

2) Если это должен быть отдельный файл то в виде советника или в виде индикатора? Насколько я знаю для ручной торговли можно и так и так, но есть какие то нюансы.

3) должен ли этот индикатор находится на графике во время работы такой программы? Или же его надо уже засовывать как включаемый файл. Чтоб в сам текст индикатора не влезать.

//+------------------------------------------------------------------+
//|                                                  Heiken Ashi.mq4 |
//|                   Copyright 2006-2014, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2006-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "We recommend next chart settings (press F8 or select menu 'Charts'->'Properties...'):"
#property description " - on 'Color' Tab select 'Black' for 'Line Graph'"
#property description " - on 'Common' Tab disable 'Chart on Foreground' checkbox and select 'Line Chart' radiobutton"
#property strict

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Red
#property indicator_color2 White
#property indicator_color3 Red
#property indicator_color4 White
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 3
#property indicator_width4 3

//---
input color ExtColor1 = Red;    // Shadow of bear candlestick
input color ExtColor2 = White;  // Shadow of bull candlestick
input color ExtColor3 = Red;    // Bear candlestick body
input color ExtColor4 = White;  // Bull candlestick body
//--- buffers
double ExtLowHighBuffer[];
double ExtHighLowBuffer[];
double ExtOpenBuffer[];
double ExtCloseBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//|------------------------------------------------------------------|
void OnInit(void)
  {
   IndicatorShortName("Heiken Ashi");
   IndicatorDigits(Digits);
//--- indicator lines
   SetIndexStyle(0,DRAW_HISTOGRAM,0,1,ExtColor1);
   SetIndexBuffer(0,ExtLowHighBuffer);
   SetIndexStyle(1,DRAW_HISTOGRAM,0,1,ExtColor2);
   SetIndexBuffer(1,ExtHighLowBuffer);
   SetIndexStyle(2,DRAW_HISTOGRAM,0,3,ExtColor3);
   SetIndexBuffer(2,ExtOpenBuffer);
   SetIndexStyle(3,DRAW_HISTOGRAM,0,3,ExtColor4);
   SetIndexBuffer(3,ExtCloseBuffer);
//---
   SetIndexLabel(0,"Low/High");
   SetIndexLabel(1,"High/Low");
   SetIndexLabel(2,"Open");
   SetIndexLabel(3,"Close");
   SetIndexDrawBegin(0,10);
   SetIndexDrawBegin(1,10);
   SetIndexDrawBegin(2,10);
   SetIndexDrawBegin(3,10);
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtLowHighBuffer);
   SetIndexBuffer(1,ExtHighLowBuffer);
   SetIndexBuffer(2,ExtOpenBuffer);
   SetIndexBuffer(3,ExtCloseBuffer);
//--- initialization done
  }
//+------------------------------------------------------------------+
//| Heiken Ashi                                                      |
//+------------------------------------------------------------------+
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,pos;
   double haOpen,haHigh,haLow,haClose;
//---
   if(rates_total<=10)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtLowHighBuffer,false);
   ArraySetAsSeries(ExtHighLowBuffer,false);
   ArraySetAsSeries(ExtOpenBuffer,false);
   ArraySetAsSeries(ExtCloseBuffer,false);
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(close,false);
//--- preliminary calculation
   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
     {
      //--- set first candle
      if(open[0]<close[0])
        {
         ExtLowHighBuffer[0]=low[0];
         ExtHighLowBuffer[0]=high[0];
        }
      else
        {
         ExtLowHighBuffer[0]=high[0];
         ExtHighLowBuffer[0]=low[0];
        }
      ExtOpenBuffer[0]=open[0];
      ExtCloseBuffer[0]=close[0];
      //---
      pos=1;
     }
//--- main loop of calculations
   for(i=pos; i<rates_total; i++)
     {
      haOpen=(ExtOpenBuffer[i-1]+ExtCloseBuffer[i-1])/2;
      haClose=(open[i]+high[i]+low[i]+close[i])/4;
      haHigh=MathMax(high[i],MathMax(haOpen,haClose));
      haLow=MathMin(low[i],MathMin(haOpen,haClose));
      if(haOpen<haClose)
        {
         ExtLowHighBuffer[i]=haLow;
         ExtHighLowBuffer[i]=haHigh;
        }
      else
        {
         ExtLowHighBuffer[i]=haHigh;
         ExtHighLowBuffer[i]=haLow;
        }
      ExtOpenBuffer[i]=haOpen;
      ExtCloseBuffer[i]=haClose;
     }
//--- done
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

мои попытки - что то, нахимичить. может вам удастся что-то до химичить

//+------------------------------------------------------------------+
//|                                                         LN_2.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots   1
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  DodgerBlue, Red
#property indicator_label1  "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close"
//+----------------------------------------------+
//| Входные параметры индикатора                 |
//+----------------------------------------------+
input string   InpFont4              = "RU1"; // Obj:Name
input string   InpFont3              = "SU1"; // Obj:Name
input string   InpFont2              = "RU2"; // Obj:Name
input string   InpFont1              = "SU2"; // Obj:Name
bool   AttachSundToMond = true; // Attach the sunday bars to monday
//--- indicator buffers
double ExtOBuffer[];
double ExtHBuffer[];
double ExtLBuffer[];
double ExtCBuffer[];
double ExtColorBuffer[];
double BufHigh[];
double BufLow[];
double T;
double R1;
double S1;
datetime TimeShift;
datetime m_prev_bars = 0; // "0" -> D'1970.01.01 00:00';
bool     Redr;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   fObjHLine(InpFont3,0,InpFont3,0,clrCoral,1,STYLE_DASHDOTDOT,0,true,false,false,OBJ_ALL_PERIODS);
   fObjHLine(InpFont4,0,InpFont4,0,clrLimeGreen,1,STYLE_DASHDOTDOT,0,true,false,false,OBJ_ALL_PERIODS);
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtOBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtHBuffer,INDICATOR_DATA);
   SetIndexBuffer(2,ExtLBuffer,INDICATOR_DATA);
   SetIndexBuffer(3,ExtCBuffer,INDICATOR_DATA);
   SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(5,BufHigh,INDICATOR_CALCULATIONS);
   SetIndexBuffer(6,BufLow,INDICATOR_CALCULATIONS);

   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- sets first bar from what index will be drawn
   IndicatorSetString(INDICATOR_SHORTNAME,"LN_2");
//--- sets drawing line empty value
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//--- initialization done
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int Rason)
  {
   ObjectsDeleteAll(0,InpFont2);
   ObjectsDeleteAll(0,InpFont1);
   ObjectsDeleteAll(0,InpFont3);
   ObjectsDeleteAll(0,InpFont4);
   if(Redr)
      ChartRedraw();
  }
//+------------------------------------------------------------------+
//| Heiken Ashi                                                      |
//+------------------------------------------------------------------+
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,limit;
//--- preliminary calculations
   if(prev_calculated==0)
     {
      //--- set first candle
      ExtLBuffer[0]=low[0];
      ExtHBuffer[0]=high[0];
      ExtOBuffer[0]=open[0];
      ExtCBuffer[0]=close[0];
      limit=1;
     }
   else
      limit=prev_calculated-1;

//--- the main loop of calculations
   for(i=limit; i<rates_total && !IsStopped(); i++)
     {
      double haOpen=(ExtOBuffer[i-1]+ExtCBuffer[i-1])/2;
      double haClose=(open[i]+high[i]+low[i]+close[i])/4;
      double haHigh=MathMax(high[i],MathMax(haOpen,haClose));
      double haLow=MathMin(low[i],MathMin(haOpen,haClose));

      ExtLBuffer[i]=haLow;
      ExtHBuffer[i]=haHigh;
      ExtOBuffer[i]=haOpen;
      ExtCBuffer[i]=haClose;

      //--- set candle color
      if(haOpen<haClose)
         ExtColorBuffer[i]=0.0; // set color DodgerBlue
      else
         ExtColorBuffer[i]=1.0; // set color Red
     }
//---
   CreateHline(0,0,InpFont2,ExtCBuffer[rates_total-1],clrDodgerBlue,0,0,1,1,1,1,2);
   CreateHline(0,0,InpFont1,ExtOBuffer[rates_total-1],clrBlue,0,0,1,1,1,1,2);
//---
   if(!ObjectMove(0,InpFont2,0,time[rates_total-1],ExtCBuffer[rates_total-1]))
      return(rates_total);
   if(!ObjectMove(0,InpFont1,0,time[rates_total-1],ExtOBuffer[rates_total-1]))
      return(rates_total);
//---
     {
      static bool error=true;
      int start;
      if(prev_calculated==0)
        {
         error=true;
        }
      if(error)
        {
         start=1;
         error=false;
        }
      else
        {
         start=prev_calculated-1;
        }
      for(int u=start; u<rates_total; u++)
        {
         BufHigh[u]=BufHigh[u-1];
         BufLow[u]=BufLow[u-1];

         datetime NowTime=time[u]-TimeShift;
         datetime PreTime=time[u-1]-TimeShift;

         if(NewDay(NowTime,PreTime))
           {
            if(BufHigh[u]!=0)
              {
               T=(BufHigh[u]-BufLow[u]);
               R1=(T*0.55)+close[u-1];
               S1=close[u-1]-(T*0.55);
               BufHigh[u]=high[u];
               BufLow[u]=low[u];
              }
            else
              {
               BufHigh[u]=MathMax(BufHigh[u],high[u]);
               BufLow[u]=MathMin(BufLow[u],low[u]);
              }
           }
         datetime tm=time[rates_total-20];

         fObjMove(InpFont3,S1,tm);
         fObjMove(InpFont4,R1,tm);
        }
     }
   if(Redr)
      ChartRedraw();
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==m_prev_bars)
      return(rates_total);
   m_prev_bars=time_0;
//---
   int find_buy_level=ObjectFind(0,InpFont2);
   int find_sell_level=ObjectFind(0,InpFont1);

   int find_buy_levelY=ObjectFind(0,InpFont4);
   int find_sell_levelY=ObjectFind(0,InpFont3);

   if(find_buy_level==0 || find_buy_levelY==0)
     {
      double price=ObjectGetDouble(0,InpFont2,OBJPROP_PRICE);
      double price1=ObjectGetDouble(0,InpFont1,OBJPROP_PRICE);
      double price4=ObjectGetDouble(0,InpFont4,OBJPROP_PRICE);
      if(price1<price && price4<price)
        {
         PlaySound("tick.wav");
         //---
         return(rates_total);
        }
     }
   if(find_sell_level==0 || find_sell_levelY==0)
     {
      double price=ObjectGetDouble(0,InpFont2,OBJPROP_PRICE);
      double price1=ObjectGetDouble(0,InpFont1,OBJPROP_PRICE);
      double price3=ObjectGetDouble(0,InpFont3,OBJPROP_PRICE);
      if(price1>price && price3>price)
        {
         PlaySound("stops.wav");
         //---
         return(rates_total);
        }
     }
   if(Redr)
      ChartRedraw();
//--- done
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|  Создание горизонтального, ценового уровня                       |
//+------------------------------------------------------------------+
bool CreateHline(long ch_id,int sub_window,
                 string name,double price,
                 color clr,ENUM_LINE_STYLE style,
                 int width,bool back,
                 bool selectable,bool selected,
                 bool hidden,long z_order)
  {
   ObjectCreate(ch_id,name,OBJ_HLINE,sub_window,0,price);
   ObjectSetInteger(ch_id,name,OBJPROP_COLOR,clr);
   ObjectSetInteger(ch_id,name,OBJPROP_STYLE,style);
   ObjectSetInteger(ch_id,name,OBJPROP_WIDTH,width);
   ObjectSetInteger(ch_id,name,OBJPROP_BACK,back);
   ObjectSetInteger(ch_id,name,OBJPROP_SELECTABLE,selectable);
   ObjectSetInteger(ch_id,name,OBJPROP_SELECTED,selected);
   ObjectSetInteger(ch_id,name,OBJPROP_HIDDEN,hidden);
   ObjectSetInteger(ch_id,name,OBJPROP_ZORDER,z_order);
   return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void fObjHLine(string   aObjName,
               double   aPrice,
               string   aText       =  "HLine",
               int      aWindow     =  0,
               color    aColor      =  Red,
               color    aWidth      =  1,
               color    aStyle      =  0,
               int      aChartID    =  0,
               bool     aBack       =  true,
               bool     aSelectable =  true,
               bool     aSelected   =  false,
               long     aTimeFrames =  OBJ_ALL_PERIODS
              )
  {
   ObjectCreate(aChartID,aObjName,OBJ_HLINE,aWindow,0,aPrice);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_BACK,aBack);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_COLOR,aColor);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_SELECTABLE,aSelectable);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_SELECTED,aSelected);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_TIMEFRAMES,aTimeFrames);
   ObjectSetString(aChartID,aObjName,OBJPROP_TEXT,aText);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_WIDTH,aWidth);
   ObjectSetInteger(aChartID,aObjName,OBJPROP_STYLE,aStyle);
   ObjectMove(aChartID,aObjName,0,0,aPrice);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void fObjMove(string   aObjName,
              double   aPrice,
              datetime aTime
             )
  {
   ObjectMove(0,aObjName,0,0,aPrice);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool NewDay(datetime aNowTime,datetime aPreTime)
  {
   long NowDay=aNowTime/86400;
   long PreDay=aPreTime/86400;
   if(AttachSundToMond)
     {
      if(NowDay!=PreDay)
        {
         MqlDateTime nts,pts;
         TimeToStruct(aNowTime,nts);
         TimeToStruct(aPreTime,pts);
         if(nts.day_of_week==1 && pts.day_of_week==0)
           {
            return(false);
           }
         return(true);
        }
     }
   else
     {
      return(NowDay!=PreDay);
     }
   return(false);
  }
//+------------------------------------------------------------------+


 

Файлы:
me8p93.PNG  106 kb
 
Mickey Moose:

Существует стандартный индикатор Хайкен - Аши

Появилось желание прикрутить туда звуковой сигнал из терминала при изменении цвета свечи. Непонятны некоторые моменты.

1) а где указатель что "сейчас рисуем белым цветом а сейчас красным" чтобы к ним привязать playsound на изменение окраски. Я не понимаю как они меняются.

2) Если это должен быть отдельный файл то в виде советника или в виде индикатора? Насколько я знаю для ручной торговли можно и так и так, но есть какие то нюансы.

3) должен ли этот индикатор находится на графике во время работы такой программы? Или же его надо уже засовывать как включаемый файл. Чтоб в сам текст индикатора не влезать.

в конце OnCalculate проверить "а не закрылся ли бар, не открылся ли новый" и сравнить ExtHighLowBuffer[1] и ExtLowHighBuffer[1] ,
глянуть не изменился ли результат от предудущего (от [2]) и если что, дать свисток.

 
SanAlex:

мои попытки - что то, нахимичить. может вам удастся что-то до химичить


 

Благодарю. но тут влезание в сам файл индикатора, его не надо трогать вообще


Maxim Kuznetsov:

в конце OnCalculate проверить "а не закрылся ли бар, не открылся ли новый" и сравнить ExtHighLowBuffer[1] и ExtLowHighBuffer[1] ,
глянуть не изменился ли результат от предудущего (от [2]) и если что, дать свисток.

Думаешь все дело в 1 баре?

 
Mickey Moose:

Существует стандартный индикатор Хайкен - Аши

Появилось желание прикрутить туда звуковой сигнал из терминала при изменении цвета свечи. Непонятны некоторые моменты.

1) а где указатель что "сейчас рисуем белым цветом а сейчас красным" чтобы к ним привязать playsound на изменение окраски. Я не понимаю как они меняются.

2) Если это должен быть отдельный файл то в виде советника или в виде индикатора? Насколько я знаю для ручной торговли можно и так и так, но есть какие то нюансы.

3) должен ли этот индикатор находится на графике во время работы такой программы? Или же его надо уже засовывать как включаемый файл. Чтоб в сам текст индикатора не влезать.

Обратите внимание на эту часть кода

   for(i=pos; i<rates_total; i++)
     {
      haOpen=(ExtOpenBuffer[i-1]+ExtCloseBuffer[i-1])/2;
      haClose=(open[i]+high[i]+low[i]+close[i])/4;
      haHigh=MathMax(high[i],MathMax(haOpen,haClose));
      haLow=MathMin(low[i],MathMin(haOpen,haClose));
      if(haOpen<haClose)
        {
         ExtLowHighBuffer[i]=haLow;
         ExtHighLowBuffer[i]=haHigh;
        }
      else
        {
         ExtLowHighBuffer[i]=haHigh;
         ExtHighLowBuffer[i]=haLow;
        }
      ExtOpenBuffer[i]=haOpen;
      ExtCloseBuffer[i]=haClose;
     }

Цвет свечи зависит от ……………

Алерты можно поставить прямо в код. Но надо учесть, что направление свечи и соответственно цвет может поменяться несколько раз подряд. Соответственно будет «дребезжание». Или внести ещё условие, не по текущему бару, а по первому, соответственно будет запаздывание.

 
Mickey Moose:

Благодарю. но тут влезание в сам файл индикатора, его не надо трогать вообще

Ааа.

Ну тогда можно сделать индикатор читающий буферы этого х.йкин уши и анализировать эти значения аналогично этой части кода.

Второй вариант: сделать копию индикатора с изменённым именем и встроенным свистком.

 
Alexey Viktorov:

Ааа.

Ну тогда можно сделать индикатор читающий буферы этого х.йкин уши и анализировать эти значения аналогично этой части кода.

Второй вариант: сделать копию индикатора с изменённым именем и встроенным свистком.

Вот первый вариант я и хочу реализовать, вопрос в импорте значений, и в виде сов. или индюка лучше

 
Mickey Moose:

Вот первый вариант я и хочу реализовать, вопрос в импорте значений, и в виде сов. или индюка лучше

Так и импортируйте значения посредством iCustom() и абсолютно не важно в советник или индикатор.

 
Alexey Viktorov:

Так и импортируйте значения посредством iCustom() и абсолютно не важно в советник или индикатор.

Хорошо, а если брать данные отсюда? К какому буферу идет обращение через iCustom и должен ли он быть на графике

(цель сделать макет привязки любых действий к любому индикатору так как эти данные в таблице у всех одинаковы)

Файлы:
gjrlom.png  7 kb
 
Mickey Moose:

Хорошо, а если брать данные отсюда? К какому буферу идет обращение через iCustom и должен ли он быть на графике

(цель сделать макет привязки любых действий к любому индикатору так как эти данные в таблице у всех одинаковы)

сравнивать нужно open и close, как с обычными свечками

 

Как я понял все должно быть вот тут и примерно так не ставя его на график? C получением значения буфера напрямую

double RandomValue0;
double RandomValue1;

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[])
  {
    
RandomValue0=iCustom(NULL,0,"Heiken_Ashi",0,1)
RandomValue1=iCustom(NULL,0,"Heiken_Ashi",1,1)

if (RandomValue0<RandomValue1)
PlaySound(file1.wav);
else
PlaySound(file2.wav);

//--- return value of prev_calculated for next call
   return(rates_total);
Причина обращения: