Как перенести индикатор Ehlers StochasticRSI с mql4 на C ++ (с MT4 на QChartist)? - PullRequest
0 голосов
/ 27 января 2019

Я создатель программного обеспечения QChartist TA.Я хочу перенести индикатор MT4 на свое программное обеспечение на C ++.

Вот код mql4 индикатора для MT4:

//+------------------------------------------------------------------+
//|                                                StochasticRSI.mq4 |
//|                                                                  |
//| Stochastic RSI                                                   |
//|                                                                  |
//| Algorithm taken from book                                        |
//|     "Cybernetics Analysis for Stock and Futures"                 |
//| by John F. Ehlers                                                |
//|                                                                  |
//|                                              contact@mqlsoft.com |
//|                                          http://www.mqlsoft.com/ |
//+------------------------------------------------------------------+
#property copyright "Coded by Witold Wozniak"
#property link      "www.mqlsoft.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue

#property indicator_level1 0
#property indicator_minimum -1
#property indicator_maximum 1

double StocRSI[];
double Trigger[];
double Value3[];

extern int RSILength = 8;
extern int StocLength = 8;
extern int WMALength = 8;
int buffers = 0;
int drawBegin = 0;

int init() {
    drawBegin = RSILength;
    initBuffer(StocRSI, "Stochastic RSI", DRAW_LINE);
    initBuffer(Trigger, "Trigger", DRAW_LINE);
    initBuffer(Value3);
    IndicatorBuffers(buffers);
    IndicatorShortName("Stochastic RSI [" + RSILength + ", " + StocLength + ", " + WMALength + "]");
    return (0);
}

int start() {
    if (Bars <= drawBegin) return (0);
    int countedBars = IndicatorCounted();
    if (countedBars < 0) return (-1);
    if (countedBars > 0) countedBars--;
    int s, limit = Bars - countedBars - 1;
    for (s = limit; s >= 0; s--) {
        double rsi = iRSI(0, 0, RSILength, MODE_CLOSE, s); 

        double hh = rsi, ll = rsi;
        for (int i = 0; i < StocLength; i++) {
            double tmp = iRSI(0, 0, RSILength, MODE_CLOSE, s + i);
            hh = MathMax(hh, tmp);
            ll = MathMin(ll, tmp);

        }

        double Value1 = rsi - ll;
        double Value2 = hh - ll;

        Value3[s] = 0.0;

        if (Value2 != 0.0) {
            Value3[s] = Value1 / Value2;

        }        
    }
    for (s = limit - 1; s >= 0; s--) {
        StocRSI[s] = 2.0 * (iMAOnArray(Value3, 0, WMALength, 0, MODE_LWMA, s) - 0.5);
        Trigger[s] = StocRSI[s + 1];

    }
    return (0);   
}

void initBuffer(double array[], string label = "", int type = DRAW_NONE, int arrow = 0, int style = EMPTY, int width = EMPTY, color clr = CLR_NONE) {
    SetIndexBuffer(buffers, array);
    SetIndexLabel(buffers, label);
    SetIndexEmptyValue(buffers, EMPTY_VALUE);
    SetIndexDrawBegin(buffers, drawBegin);
    SetIndexShift(buffers, 0);
    SetIndexStyle(buffers, type, style, width);
    SetIndexArrow(buffers, arrow);
    buffers++;
}

А это код C ++ для QChartist, который не 't работа:

//+------------------------------------------------------------------+
//|                                                StochasticRSI.mq4 |
//|                                                                  |
//| Stochastic RSI                                                   |
//|                                                                  |
//| Algorithm taken from book                                        |
//|     "Cybernetics Analysis for Stock and Futures"                 |
//| by John F. Ehlers                                                |
//|                                                                  |
//|                                              contact@mqlsoft.com |
//|                                          http://www.mqlsoft.com/ |
//+------------------------------------------------------------------+

/*
#property copyright "Coded by Witold Wozniak"
#property link      "www.mqlsoft.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue

#property indicator_level1 0
#property indicator_minimum -1
#property indicator_maximum 1
*/

static arrayofdoubles StocRSI;
static arrayofdoubles Trigger;
static arrayofdoubles Value3;

char* StochasticRSI (char* period)
{

int RSILength = 5;
int StocLength = 5;
int WMALength = 5;
int buffers = 0;
int drawBegin = 0;

    static char periodd[1000];
    strncpy(periodd, period, 1000);
    int intperiod=atoi(periodd);
    // Put your indicator C++ code here

if (bars <= drawBegin) return (0);
    int countedBars = cntbarsedit;
    //if (countedBars < 0) return (-1);
    if (countedBars > 0) countedBars--;
    int s, limit = bars - countedBars - 1;

    for (s = limit; s >= 0; s--) {
        double rsi = irsi( 60, RSILength, MODE_CLOSE, s);
    //if (s==3) { sprintf(debugmsg,"%f",rsi);MessageBox( NULL, debugmsg,"Debug",MB_OK); }
        double hh = rsi, ll = rsi;
        for (int i = 0; i < StocLength; i++) {
            double tmp = irsi(60, RSILength, MODE_CLOSE, s + i);

            hh = mathmax(hh, tmp);
            ll = mathmin(ll, tmp);
        }

        double Value1 = rsi - ll;
        double Value2 = hh - ll;

        Value3[s] = 0.0;
        if (Value2 != 0.0) {
            Value3[s] = Value1 / Value2;
        }        
    }
    for (s = limit - 1; s >= 0; s--) {
        StocRSI[s] = 2.0 * (imaonarray(Value3, 0, WMALength, 0, MODE_LWMA, s) - 0.5);
        Trigger[s] = StocRSI[s + 1];

    }

return 0;
}

Для более подробной информации, пожалуйста, прочитайте мой пост здесь: https://www.forexfactory.com/showthread.php?t=874824

1 Ответ

0 голосов
/ 31 января 2019

Вот решение:

В QChartist.cpp:

Функция irsi:

double irsi(int timeframe,int period,int applied_price,int shift)
{
int RSIPeriod=period;
//---- buffers
static arrayofdoubles RSIBuffer;
static arrayofdoubles PosBuffer;
static arrayofdoubles NegBuffer;

int    i,counted_bars=cntbarsedit;
   double rel,negative,positive;
int Bars=bars;
//----
   if(Bars<=RSIPeriod) return(0);
//---- initial zero
   if(counted_bars<1)
      for(i=1;i<=RSIPeriod;i++) RSIBuffer[Bars-i]=0.0;
//----
   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
    //i=999;
   while(i>=0)
     {
      double sumn=0.0,sump=0.0;
      if(i==Bars-RSIPeriod-1)
        {
         int k=Bars-2;
         //---- initial accumulation
         while(k>=i)
           {
            rel=lowa[k]-lowa[k+1];
            if(rel>0) sump+=rel;
            else      sumn-=rel;
            k--;
           }
         positive=sump/RSIPeriod;
         negative=sumn/RSIPeriod;
        }
      else
        {
         //---- smoothed moving average
         rel=lowa[i]-lowa[i+1];
         if(rel>0) sump=rel;
         else      sumn=-rel;
         positive=(PosBuffer[i+1]*(RSIPeriod-1)+sump)/RSIPeriod;
         negative=(NegBuffer[i+1]*(RSIPeriod-1)+sumn)/RSIPeriod;
        }
      PosBuffer[i]=positive;
      NegBuffer[i]=negative;
      if(negative==0.0) RSIBuffer[i]=0.0;
      else RSIBuffer[i]=100.0-100.0/(1+positive/negative);
      if (i==shift) { return RSIBuffer[i]; break; }
      i--;
     }
//----
   return(0);
}

И функция imaonarray:

double imaonarray(arrayofdoubles& array,int total,int period,int ma_shift,int ma_method,int shift)
{

arrayofdoubles ExtMapBuffer;

switch(ma_method)
     {
      case 0 : 
      // SMA
      double sum;
    int per;
    sum=0;
    int i;int p;
    p=total;
    if (p<period) p=period;
    per=period;

    for (i=1;i<=per-1;i++) {
        sum=sum+array[p];
        p--;
                           }
    while (p>=0) {
        sum=sum+array[p];
        if (p==shift+ma_shift) { return sum/per; break; }
        sum=sum-array[p+per-1];
        p--;
                 }
      break;
      case 1 : /*ema not implemented yet*/ break;
      case 2 : /*smma not implemented yet*/ break;
      case 3 : /*lwma*/ 
    sum=0.0; double lsum=0.0;
       double price;
       int    weight=0;
    //---- initial accumulation
        p=total;
       if(p<period) p=period;
       for(i=1;i<=period;i++,p--)
         {
          price=array[p]; //iapplied_price(applied_price,timeframe,p);
          sum+=price*i;
          lsum+=price;
          weight+=i;
         }
    //---- main calculation loop
       p++;
       i=p+period;
       while(p>=0)
         {
          ExtMapBuffer[p]=sum/weight;
        if (p==shift+ma_shift) { return ExtMapBuffer[p]; break; }
          if(p==0) break;
          p--;
          i--;
          price=array[p]; //iapplied_price(applied_price,timeframe,p);
          sum=sum-lsum+price*period;
          lsum-=array[i]; //iapplied_price(applied_price,timeframe,i);
          lsum+=price;
         }

    break;
     }


return 0;
}

И вот код для индикатора StochasticRSI:

//+------------------------------------------------------------------+
//|                                                StochasticRSI.mq4 |
//|                                                                  |
//| Stochastic RSI                                                   |
//|                                                                  |
//| Algorithm taken from book                                        |
//|     "Cybernetics Analysis for Stock and Futures"                 |
//| by John F. Ehlers                                                |
//|                                                                  |
//|                                              contact@mqlsoft.com |
//|                                          http://www.mqlsoft.com/ |
//+------------------------------------------------------------------+

/*
#property copyright "Coded by Witold Wozniak"
#property link      "www.mqlsoft.com"

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue

#property indicator_level1 0
#property indicator_minimum -1
#property indicator_maximum 1
*/

static arrayofdoubles StocRSI;
static arrayofdoubles Trigger;
static arrayofdoubles Value3;
static arrayofdoubles StocRSImax;
static arrayofdoubles StocRSImin;

char* StochasticRSI (char* period)
{

int RSILength = 5;
int StocLength = 5;
int WMALength = 5;
int buffers = 0;
int drawBegin = 0;

    static char periodd[1000];
    strncpy(periodd, period, 1000);
    int intperiod=atoi(periodd);
    // Put your indicator C++ code here

if (bars <= drawBegin) return (0);
    int countedBars = cntbarsedit;
    //if (countedBars < 0) return (-1);
    if (countedBars > 0) countedBars--;
    int s, limit = bars - countedBars - 1;
    //limit=999;
    for (s = limit; s >= 0; s--) {
        double rsi = irsi( 60, RSILength, MODE_CLOSE, s);
     //if (s==3) { sprintf(debugmsg,"%f",rsi);MessageBox( NULL, debugmsg,"Debug",MB_OK); }
        double hh = rsi, ll = rsi;
        for (int i = 0; i < StocLength; i++) {
            double tmp = irsi(60, RSILength, MODE_CLOSE, s + i);

            hh = mathmax(hh, tmp);
            ll = mathmin(ll, tmp);
        }
    //if (s==3) { sprintf(debugmsg,"%f",hh);MessageBox( NULL, debugmsg,"Debug",MB_OK); }
    //if (s==3) { sprintf(debugmsg,"%f",ll);MessageBox( NULL, debugmsg,"Debug",MB_OK); }    
        double Value1 = rsi - ll;
        double Value2 = hh - ll;

        Value3[s] = 0.0;
        if (Value2 != 0.0) {
            Value3[s] = Value1 / Value2;
        }      
    //if (s==3) { sprintf(debugmsg,"%f",Value3[s]);MessageBox( NULL, debugmsg,"Debug",MB_OK); }  
    }
    for (s = limit - 1; s >= 0; s--) {

        StocRSI[s] = 2.0 * (imaonarray(Value3, 100, WMALength, 0, MODE_LWMA, s) - 0.5);
    //if (s==3) { sprintf(debugmsg,"%f",StocRSI[s]);MessageBox( NULL, debugmsg,"Debug",MB_OK); }
        Trigger[s] = StocRSI[s + 1];
    StocRSImax[s]=1;
    StocRSImin[s]=-1;
    }

return 0;
}
...