Wie plotte ich werte aus einem Array (ohne unübersichtliches Indikator getechtel möglich?)? - Seite 2

Einloggen oder registrieren, um einen Kommentar zu schreiben
Bayne
971
Bayne  
Carl Schreiber:

Hmm - Du kannst hier nicht im Forum quasi Programmieraufträge erteilen - dafür gibt es die Freelancer!

Wenn Du das aber nicht willst, musst Du das lernen, am besten mit Beispielen aus der Codebase.

Mit "Letzteres" meinte ich nur das aufrücken eines Arrayindex in onCalculate(),

Also wenn es möglich ist quasi:




double Oncalculatr(){

if(iTime(...,0)!=oldbar)
    {Dostuff();
      ArrayIndex++;
     olddbar= iTime(...,0);}
}

Wobei oldbar in OnInit initialisiert würde und das Array mit den predictions gepullt würde...

Returnen würde ich einen String Datum um das ganze im EA zu prüfen und den predictions Preis Double.
Also dann wahrscheinlich durch einen Indikator Buffer :/

Habe heute leider keinen Rechner um das auszutesten, wenn das auch in oncalculate kein Problem darstellt, wär ja alles top.







Otto Pauser
1822
Otto Pauser  

Um eine neu bar festzustellen kannst du diesen code verwenden.

bool IsNewBar(void)              // returns true if new candle was born
{
   static datetime oldTime=WRONG_VALUE;
   datetime barTime=iTime(_Symbol,_Period,0);
   if(oldTime==WRONG_VALUE)
      oldTime=barTime;
   if(barTime==oldTime)
      return(false);
   else
      oldTime=barTime;
   return(true);
}

Dieser code wartet bewusst auf eine neue bar und spuckt nicht sofort true aus.

Beachte: bei einer neuen bar sind alle 4 werte (O,H,L,C) immer gleich.

In der OnCalculate sieht das dann so aus:

double OnCalculate()
{
   if(IsNewBar())
      {
         DoStuff();
         ArrayIndex++;
         DoMoreStuff();
      }
}

Und setz die Klammern vernünftig. Wie du das machst ist das sehr unübersichtlich.

Alte Regel der Lisp-Programmieung: UNTER jede öffnende { gehört eine schließende } da verlerst du nie die Übersicht.

Stell den Styler auf 'GNU' und verwende diesen.

Chris70
517
Chris70  
Bayne:

Dass ich die werte aus dem 2d array in seperaten speichern kann ist weniger die frage.

Benötige vielmehr sowas:(verlinkung auf post 74)

https://www.mql5.com/en/forum/319316/page8#comment_13055294

(@Christian die libary aus deinem link sieht auf den ersten blick nicht ganz danach aus etwas als chartlinie plotten zu können (korrigier mich wenn doch) vllt habe ich mit "plotten" auch nur das falsche Wort verwendet)

Also so wie im verlinkten beitrag, wie ist das möglich?

Hi Bayne & @all,

Das Forum hat zeitweise zuviel Zeit gefressen, daher war ich eine Weile absichtlich abstinenter; da Du Dich aber auf meinen Beitrag beziehst kann ich kurz was dazu sagen: in dem Beispiel mit der polynomen Regression handelt es sich nicht um einen Indikator, sondern um einen reinen Expert Advisor. Der "Plot" entsteht hier durch multiple Trend-Objekt-Segmente. Die Funktion, die ich für solche Zwecke gelegentlich verwende sieht so aus:

//+------------------------------------------------------------------+
//| continuous price line                                            |
//+------------------------------------------------------------------+
void PriceLine(double nextprice, datetime price_time,int identifier=0,color lineclr=clrBlue,int linewidth=3,ENUM_LINE_STYLE style=STYLE_SOLID,long chart_id=0,string labelstring="priceline")
  {
   if (MQLInfoInteger(MQL_OPTIMIZATION)){return;}   
   static int index[]; ArrayResize(index,MathMax(ArraySize(index),identifier+1),10);
   static double last_price[]; ArrayResize(last_price,MathMax(ArraySize(index),identifier+1),10);
   static datetime last_time[]; ArrayResize(last_time,MathMax(ArraySize(index),identifier+1),10);   
   static int highest_identifier=-1;
   if (identifier>highest_identifier)
     {
      highest_identifier=identifier;
      index[identifier]=0;
      last_time[identifier]=price_time;
      last_price[identifier]=nextprice;
     }
   string objlabel=labelstring+" "+IntegerToString(identifier)+"("+IntegerToString(index[identifier])+")";
   ObjectCreate(chart_id,objlabel,OBJ_TREND,0,last_time[identifier],last_price[identifier],price_time,nextprice);
   ObjectSetInteger(chart_id,objlabel,OBJPROP_COLOR,lineclr);
   ObjectSetInteger(chart_id,objlabel,OBJPROP_WIDTH,linewidth);
   ObjectSetInteger(chart_id,objlabel,OBJPROP_STYLE,style);
   ObjectSetInteger(chart_id,objlabel,OBJPROP_BACK,true);
   last_price[identifier]=nextprice;
   last_time[identifier]=price_time;
   index[identifier]++;
  }

Intuitiv stellt sich evtl. die Frage, ob die vielen Objekte zu Performance-Einbußen führen im Vergleich zur Verwendung eines Indikators. Wenn die Funktion nur bei neuen Bars aufgerufen wird und nicht mit jedem Tick, spielt es in der Praxis keine Rolle. Letztlich braucht ein Indikator ja ebenso Resourcen, um seine Grafik-Elemente zu erzeugen.

Eine kurze Anmerkung noch zum Stichwort "Repainting", weil es hier im Zusammenhang mit polynomer Regression angesprochen wurde. Ja, selbstverständlich ändert sich eine Regressionslinie ständig, nämlich bei jeglicher Veränderung der Berechnungsgrundlage, also neuen Daten/Preisen, von daher ist es ein klassischer Fall von Repainting. Dies gilt ebenso für die Extrapolation der Regressionslinie. Wir kennen das von der einfachen linearen Regression nach dem Motto y=ax+b, die man ja ebenfalls zu zukünftigen "x" extrapolieren kann, doch wenn sich die Koeffizienten a und b ändern, kommt natürlich was völlig anderes heraus. Das ist bei polynomer Regression natürlich genauso. Mit diesem Problem umzugehen ist aber eben genau die Funktion der "trace line", also die "Spur", die die Regressionslinie zieht. Die "trace line" erzählt also die ganze Geschichte, ohne Repainting, und stellt ein interessantes Handelssignal dar (Divergenz zum Preis zeigt beispielsweise das Momentum an).

Hier mal ein anderes Beispiel, wo mit der gleichen Funktion anstelle einer Regressionsline vom EA selbst berechnete EMA's (basierend auf Range Bar Close-Preisen) geplottet werden (die Range Bars und auch alles andere in diesem Beispiel sind übrigens ebenfalls reiner EA, ohne Indikator... ja.. ich weiß.. ungewöhnliches Vorgehen, doch so hat halt jeder seinen Programmierstil):

range bar EMA

Der Trick bei mehreren Linien (wie hier die hellblaue und dunkelblaue Linie): Bei Aufruf der Funktion werden "Identifier" zugewiesen (hier im Beispiel habe ich z.B. 0 bzw. 1 vergeben für den slow bzw. fast EMA) und die Funktion "merkt" sich (da als "static" deklariert) jeweils die letzte Koordinate (Preis+Zeit) separat für diese verschiedenen Identifier. So weiß die Funktion beim nächsten Aufruf den korrekten Bezugspunkt, also das letzte Linienende von dem aus das nächste Liniensegment gezeichnet werden muss.

12
Einloggen oder registrieren, um einen Kommentar zu schreiben