Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   in EA: EMA auf RSI (http://www.expert-advisor.com/forum/showthread.php?t=1935)

Dennis 13.02.12 15:40

in EA: EMA auf RSI
 
Hallo Leute,

bevor ich Fragen frage, betreibe ich immer erst einige Eigenrecherche. In diesem Fall hat sie leider nicht zum Ziel geführt. Deswegen hier mein Anliegen.

In der aktuellen Candle werden die RSIs der 3 aktuellsten Candles benötigt. Diese RSIs sollen mit einem EMA geglättet werden.

Hört sich recht simpel an, aber als MQL4-Anfänger habe ich's für den EA auch nach längerem Probieren leider nicht hingekriegt.

Im Indicator habe ich es durch Umfrimeln eines anderen Indicators umsetzen können. Aber im EA habe ich auch durch Lesen und Testen nicht herausgefunden, wie iMAOnArray angewendet werden muß.

Die Print-Funktionen dienen nur der Kontrolle der Werte.

Würde mich echt freuen, wenn mir da jemand weiterhelfen könnte ;)

EA:
Code:

extern int EMA = 10;
extern int RSI =  5;

int start()
{
    double RSI0 = iRSI (NULL, 0, RSI, PRICE_CLOSE, 0);
    double RSI1 = iRSI (NULL, 0, RSI, PRICE_CLOSE, 1);
    double RSI2 = iRSI (NULL, 0, RSI, PRICE_CLOSE, 2);

    Print ("RSI0: ", RSI0);
    Print ("RSI1: ", RSI1);
    Print ("RSI2: ", RSI2);
/*
    double MaRSI0 =
    double MaRSI1 =
    double MaRSI2 =

    Print ("MaRSI0: ", DoubleToStr (MaRSI0, 0));
    Print ("MaRSI1: ", DoubleToStr (MaRSI1, 1));
    Print ("MaRSI2: ", DoubleToStr (MaRSI2, 2));
*/
}

Indicator:
Code:

#property indicator_separate_window
#property indicator_buffers 2

#property indicator_color1 C'44,177,44' // High
#property indicator_color2 Blue        // Low

extern int EMA = 10;
extern int RSI =  5;

double RSIclose[];
double MaRSIclose[];

int init()
{
    IndicatorBuffers (2);
    IndicatorDigits (Digits);

    SetIndexBuffer (0, MaRSIclose);
    SetIndexStyle (0, DRAW_LINE);
    SetIndexLabel (0, "close");
    SetIndexDrawBegin (0, EMA);

    SetIndexBuffer (1, RSIclose);

    IndicatorShortName ("EMAonRSI  ["+EMA+",  "+RSI+"] ");
    return (0);
}

int start()
{
    int counted, i;
    counted = IndicatorCounted();

    if (counted < 1)
        for (i = Bars - 2 * EMA; i < Bars; i++)
        {
            RSIclose[i]  = 0.0;
            MaRSIclose[i] = 0.0;
        }

    counted = Bars - counted - 1;

    for (i = counted; i >= 0; i--)
        RSIclose[i]  = iRSI (NULL, 0, RSI, PRICE_CLOSE, i);
   
    for (i = counted; i >= 0; i--)
        MaRSIclose[i] = iMAOnArray (RSIclose, 0, EMA, 0, MODE_EMA, i);
   
    return (0);
}


naranjoe 14.02.12 21:32

Also ich bin etwas :confused:

Dein Indikator enthält zwar ein paar grobe Schnitzer, aber er funktioniert.

Bleibt folgendes Problem:
Du möchtest einen RSI der letzten 3 Kerzen glätten,
Warum benutzt du dann RSI mit 5 und EMA mit 10 ???

Dennis 15.02.12 10:40

Da habe ich mich wohl etwas mißverständlich ausgedrückt. Danke, daß Du Dir das mal angeguckt hast.

Der 5er RSI soll mit einem 10er EMA geglättet werden (= MaRSI). Und es werden die MaRSI der 3 aktuellsten Candles benötigt.

Da ich gerne dazulernen möchte: welche groben Schnitzer beinhaltet der Indikator? Wie müßte er gecodet sein?

naranjoe 15.02.12 20:53

Sorry, da habe ich wohl deinen Code etwas zu schnell überflogen, sollte so o.k. sein.
Wenn du mit iMAOnArray in deinem EA die RSI-Werte glätten möchtest, musst du natürlich erstmal ein Array mit Werten anlegen.
Der Ansatz in deinem EA Code ist daher nicht so gut.
Also iRSI auslesen und in Array schreiben.
Dann iMAOnArray darauf anwenden.

Gruß
naranjoe

Dennis 20.02.12 01:14

Danke für Deine Anregungen.

An Hand der ArraySetAsSeries - MQL4 Documentation habe ich den gewünschten Code hinbekommen.

Eine Frage hätte ich noch zu double EMAbuffer [45];
Erst ab 45 wird EMAonRSI korrekt berechnet. Der RSI wird spätestens ab 10 korrekt berechnet. Das habe ich jetzt nur durch Testen herausbekommen. Wie wird der Wert für [] normalerweise ermittelt?

Code:

extern int EMA = 10;
extern int RSI =  5;

int start()
{

double RSIbuffer [45];
double EMAbuffer [45];
int    i;
int    limit = ArraySize (RSIbuffer);
ArraySetAsSeries (RSIbuffer, true);
 
for (i = 0; i < limit; i++)
  RSIbuffer[i] = iRSI (NULL, 0, RSI, PRICE_CLOSE, i);

for (i = 0; i < limit; i++)
  EMAbuffer[i] = iMAOnArray (RSIbuffer, limit, EMA, 0, MODE_EMA, i);

for (i = 0; i < 3; i++)
    Print (" RSI ", i, "  ", DoubleToStr (RSIbuffer[i], Digits));

for (i = 0; i < 3; i++)
    Print (" EMAonRSI ", i, "  ", DoubleToStr (EMAbuffer[i], Digits));
}


Hier ist noch der etwas veränderte Indicator. Auch da wäre ich für weitere Verbesserungen im Coding dankbar:
Code:

#property indicator_separate_window
#property indicator_buffers 2

#property indicator_color1 C'44,177,44'
#property indicator_color2 Blue

extern int EMA = 10;
extern int RSI =  5;

double RSIclose[];
double MaRSIclose[];

int init()
{
    IndicatorDigits (Digits);

    SetIndexBuffer (0, MaRSIclose);
    SetIndexStyle (0, DRAW_LINE);
    SetIndexLabel (0, "EMAonRSI");
    SetIndexDrawBegin (0, EMA);

    SetIndexBuffer (1, RSIclose);
    SetIndexStyle (1, DRAW_LINE);
    SetIndexLabel (1, "RSI");
    SetIndexDrawBegin (0, RSI);

    IndicatorShortName ("EMAonRSI  ["+EMA+",  "+RSI+"] ");
    return (0);
}

int start()
{
    int counted, i;
    counted = IndicatorCounted();

    if (counted < 1)
        for (i = Bars - 2 * EMA; i < Bars; i++)
        {
            RSIclose[i]  = 0.0;
            MaRSIclose[i] = 0.0;
        }

    counted = Bars - counted - 1;

    for (i = counted; i >= 0; i--)
        RSIclose[i]  = iRSI (NULL, 0, RSI, PRICE_CLOSE, i);
   
    for (i = counted; i >= 0; i--)
        MaRSIclose[i] = iMAOnArray (RSIclose, 0, EMA, 0, MODE_EMA, i);
   
    return (0);
}


naranjoe 21.02.12 08:31

Versuch es mal hiermit
Code:

extern int EMA = 10;
extern int RSI =  5;
double RSIBuffer[60]; //Buffer für RSI Werte
double MAonRSI[3];    //Ergebnis für 3 Kerzen

void init()
{
 ArraySetAsSeries(RSIBuffer, true); //Zugriff auf Array für iMAOnArray umkehren
}

void start()
{
 for (int k = 0; k <= 2; k++) //k = die 3 letzten Kerzen
  {
    for (int i = 0; i <= 59; i++) // Index für RSI Array
      {
      RSIBuffer[i] = iRSI (NULL, 0, RSI, PRICE_CLOSE, i); //Array beschreiben
      }
       
    MAonRSI[k] = iMAOnArray(RSIBuffer, 0, EMA, 0, MODE_EMA, k); 
  }
    Comment ("MAonRSI Kerze 0: ", MAonRSI[0],
              "\n", "MAonRSI Kerze 1: ", MAonRSI[1],   
              "\n", "MAonRSI Kerze 2: ", MAonRSI[2]);
}

Für die korrekte Berechnung des EMA brauchst du viele Werte um ein genaues Ergebnis zu erzielen. Da das Resultat der vorherigen Berechnung mit einbezogen wird, stellt sich erst mit vielen einbezogenen Werten ein genaues Ergebnis ein. (In meinem Beispiel 60).

Was möchtest du denn an deinem Indikator verbessern?

Gruß
naranjoe

Dennis 21.02.12 20:28

Versuchen? Du wußtest doch bestimmt genau, daß Dein Code wunschgemäß funktionieren wird ;) ;) Danke Dir dafür! Dein Code sieht natürlich schon rein optisch straffer aus und er bringt sicher auch einen Speed-Vorteil.

MAonRSI[k] liefert erst ab RSIBuffer [76] korrekte Werte bis in die 5. Nachkommastelle. Hier muß man also probieren oder den Wert gleich ziemlich hoch ansetzen (Speed-Nachteil).

Wie ist "//Zugriff auf Array für iMAOnArray umkehren" gemeint? Denn ArraySetAsSeries (RSIBuffer, true); hatte ich ja bereits genauso gecodet in meinem 2. Versuch.

Die Comment-Funktion ist natürlich ganz praktisch. Beim Stöbern nach einer Erklärung des void-Befehls bin ich auf Information Storage and View - MQL4 Articles gestoßen. Mit den dort downloadbaren Dateien sind die Comments komfortabel gestaltbar. info.mq4 habe ich allerdings angepaßt, damit alles wunschgemäß angezeigt werden kann.

Wie ist das eigentlich mit dem void-Befehl? Ich meine schon gelesen zu haben, daß theoretisch auch komplexe EAs statt mit int start() genauso mit einzelnen void-Befehlen gecodet werden können.

Zum Indikator: Naja, Du meintest in #2, der Indikator enthält ein paar grobe Schnitzer. Daraufhin hatte ich ihn nach meinen bescheidenen Möglichkeiten versucht zu verbessern. Ist er jetzt ok so, wie er zuletzt gepostet ist?

Code:

#include <info3.mq4>

extern int EMA = 10;
extern int RSI =  5;

double RSIBuffer[76]; //Buffer für RSI Werte, erst ab [76] korrekte Werte bis in 5. Stelle
double MAonRSI[3];    //Ergebnis für 3 Kerzen

void init()
{
  ArraySetAsSeries (RSIBuffer, true); //Zugriff auf Array für iMAOnArray umkehren
  info_init();
}

void deinit()
{
  info_deinit();
}

void start()
{
  for (int k = 0; k <= 2; k++) //k = die 3 letzten Kerzen
  {
      for (int i = 0; i <= 75; i++) // Index für RSI Array
        {
            RSIBuffer[i] = iRSI (NULL, 0, RSI, PRICE_CLOSE, i); //Array beschreiben
        } 
      MAonRSI[k] = iMAOnArray (RSIBuffer, 0, EMA, 0, MODE_EMA, k);
  }
/*   
  // für normale Ausgabe im Chart:
  Comment ("MAonRSI  0:  ", DoubleToStr (MAonRSI[0], Digits),
      "\n", "MAonRSI  1:  ", DoubleToStr (MAonRSI[1], Digits),   
      "\n", "MAonRSI  2:  ", DoubleToStr (MAonRSI[2], Digits),
      "\n", "RSI  0:  ", DoubleToStr (RSIBuffer[0], Digits),
      "\n", "RSI  1:  ", DoubleToStr (RSIBuffer[1], Digits),   
      "\n", "RSI  2:  ", DoubleToStr (RSIBuffer[2], Digits));

  // für Ausgabe im Journal:
  for (int j = 2; j >= 0; j--)
  {
      Print (" MAonRSI ", j, "  ", DoubleToStr (MAonRSI[j], Digits));
      Print (" RSI ", j, "  ", DoubleToStr (RSIBuffer[j], Digits));
  }
*/
  // für komfortablere Ausgabe im Chart:
  info (0, "Account #" + AccountNumber() + " (" + AccountName() + "):", Blue, 10);
  info (1, "AccountBalance = " + DoubleToStr (AccountBalance(), 2), Blue);
  info (2, "AccountEquity  = " + DoubleToStr (AccountEquity(), 2), Blue);
  info (3, "MAonRSI 0  " + DoubleToStr (MAonRSI[0], Digits), Blue);
  info (4, "MAonRSI 1  " + DoubleToStr (MAonRSI[1], Digits), Blue);
  info (5, "MAonRSI 2  " + DoubleToStr (MAonRSI[2], Digits), Blue);
  info (6, "RSI 0  " + DoubleToStr (RSIBuffer[0], Digits), Blue);
  info (7, "RSI 1  " + DoubleToStr (RSIBuffer[1], Digits), Blue);
  info (8, "RSI 2  " + DoubleToStr (RSIBuffer[2], Digits), Blue);
}

info3.mq4:
Code:

color  lastusedColor    = Blue;
double lastusedFontSize = 10;
string lastusedFont    = "Verdana";

void info_init()
{
        for (int row = 0; row <= 10; row ++)
        {
                _LabelCreate (StringConcatenate ("InfoLabel_0", row),  10, 20 + 20 * row); // Zeilenabstand x * row
                _LabelCreate (StringConcatenate ("InfoLabel_1", row), 270, 15 + 15 * row);
        }
}

void _LabelCreate (string _Name, int _XDistance, int _YDistance, int _Corner = 0)
{
        int _GetLastError;

        if (!ObjectCreate (_Name, OBJ_LABEL, 0, 0, 0))
        {
                _GetLastError = GetLastError();
                if (_GetLastError != 4200)
                {
                        Print ("ObjectCreate (\"", _Name, "\", OBJ_LABEL, 0, 0, 0) - Error #", _GetLastError);
                        return(-1);
                }
        }
        if (!ObjectSet (_Name, OBJPROP_CORNER, _Corner))
        {
                _GetLastError = GetLastError();
                Print ("ObjectSet( \"", _Name, "\", OBJPROP_CORNER, ", _Corner,
                                                                                                        ") - Error #", _GetLastError);
        }
        if (!ObjectSet( _Name, OBJPROP_XDISTANCE, _XDistance ) )
        {
                _GetLastError = GetLastError();
                Print ("ObjectSet (\"", _Name, "\", OBJPROP_XDISTANCE, ", _XDistance,
                                                                                                                        ") - Error #", _GetLastError);
        }
        if (!ObjectSet (_Name, OBJPROP_YDISTANCE, _YDistance))
        {
                _GetLastError = GetLastError();
                Print ("ObjectSet (\"", _Name, "\", OBJPROP_YDISTANCE, ", _YDistance,
                                                                                                                        ") - Error #", _GetLastError);
        }
        if (!ObjectSetText (_Name, "", 10))
        {
                _GetLastError = GetLastError();
                Print ("ObjectSetText (\"", _Name, "\", \"\", 10) - Error #", _GetLastError);
        }
}

void info_deinit()
{
        int _GetLastError;
        for (int row = 0; row <= 10; row ++)
        {
                if (!ObjectDelete (StringConcatenate ("InfoLabel_0", row)))
                {
                        _GetLastError = GetLastError();
                        Print ("ObjectDelete (\"", StringConcatenate ("InfoLabel_0", row),
                                                                                                                        "\") - Error #", _GetLastError);
                }
                if (!ObjectDelete (StringConcatenate ("InfoLabel_1", row)))
                {
                        _GetLastError = GetLastError();
                        Print ("ObjectDelete (\"", StringConcatenate ("InfoLabel_1", row),
                                                                                                                        "\") - Error #", _GetLastError);
                }
        }
}

void info (int LabelNumber, string Text, color Color = -1,
                          double FontSize = -1.0, string Font = "-1")
{
        string LabelName;
        if (LabelNumber < 10 )  // hier 10 im Original
                LabelName = StringConcatenate ("InfoLabel_0", LabelNumber);
        else
                LabelName = StringConcatenate ("InfoLabel_" , LabelNumber);

        if (Color < 0) Color = lastusedColor;
        if (FontSize < 0) FontSize = lastusedFontSize;
        if (Font == "-1") Font = lastusedFont;

        lastusedColor = Color;
        lastusedFontSize = FontSize;
        lastusedFont = Font;

        if (!ObjectSetText (LabelName, Text, FontSize, Font, Color))
        {
                int _GetLastError = GetLastError();
                Print ("ObjectSetText (\"", LabelName, "\", \"", Text, "\", ", FontSize, ", ", Font,
                                                                                                                        ", ", Color, ") - Error #", _GetLastError);
        }
        ObjectsRedraw();
}

void info_clear()
{
        for (int n =  0;  n < 5; n ++) info (n, ""); // hier zwecks Erhöhung der Info-Lines nichts geändert
        for (    n = 10; n < 15; n ++) info (n, ""); // hier zwecks Erhöhung der Info-Lines nichts geändert
}


naranjoe 21.02.12 21:22

Das du für die EMA Kalkulation mehrere Werte einbeziehen musst, hatte ich ja breits erklärt. Hier gilt, je mehr desto genauer. Du kannst auch Werte um die 100 dafür verwenden. Auf den Speed wirkt sich das aber nicht aus, vieleicht erst bei mehreren 1000 Werten.

Das du ArraySetAsSeries verwendest hast war schon richtig, ich wollte es halt nur noch einmal im Code kommentieren.

Für einen EA brauchst du auf jeden Fall die Start(), die wird bei jedem Tick-Signal ausgeführt. Um den Code hier übersichtlicher zu gestalten kannst du einzelne Code-Blöcke wie z.b. das setzen einer Order oder die Ausgabe des Comment-Befehls in einzelne Void's auslagern. Eine void() liefert übrigens keinen Rückgabwert wie zum z.B. eine Bool() oder INT().

Dein Indikator ist o.k., kannst du ruhig so verwenden.

Gruß
naranjoe


Alle Zeitangaben in WEZ +2. Es ist jetzt 19:08 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum