Sie verpassen Handelsmöglichkeiten:
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Registrierung
Einloggen
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Wer weiß, ob ich eine Funktion an ein Nichtmitglied einer Klasse als Argument für einen Verweis (Adresse) auf eine andere Funktion übergeben kann, die überhaupt kein Mitglied einer Klasse ist?
Oder kann ich einer Funktion, die Mitglied einer Klasse ist, als Argument einen Verweis (eine Adresse) auf eine andere Funktion übergeben, die überhaupt nicht Mitglied einer Klasse ist?
Wer weiß, ob ich eine Funktion an ein Nichtmitglied einer Klasse als Argument für einen Verweis (Adresse) auf eine andere Funktion übergeben kann, die überhaupt kein Mitglied einer Klasse ist?
Oder kann ich einer Funktion, die Mitglied einer Klasse ist, als Argument einen Verweis (eine Adresse) auf eine andere Funktion übergeben, die überhaupt nicht Mitglied einer Klasse ist?
Nein. Nein.
Das können Sie nicht. In MQL5 gibt es keinen solchen Begriff wie "Funktionsadresse" oder "Funktionsreferenz".
Ich danke Ihnen!
Eine andere Frage.
Es gibt zwei Dateien mit Code in mql5.Die erste Datei ist die Hauptdatei - Indikator oder Skript. Diezweite Datei istmqh.
Vielleicht reagiere ich über, aber ich habe eine andere Frage. Bevor ich eine Anfrage zur Platzierung einer Marktorder (zur Eröffnung einer Position) sende, setze ich ein Handelsticket auf Null zurück, d.h. ich mache result.deal=0. Können wir erwarten, dass der Server in der MqlTradeResult-Antwortstruktur ein Null-Handels-Ticket zurückgibt, aber etwas später wird der Handel ausgeführt und die Position eröffnet? Oder garantiert die Rückgabe eines Null-Handels-Tickets durch den Server, dass die Position nicht eröffnet werden konnte und dass sie auf der Grundlage dieser Anfrage nicht weiter eröffnet werden wird?
OK, wegen des Mangels an Antworten und aufgrund dieser Zeile
struct MqlTradeResult
{
ulong deal; // Ticket zu deal, wenn es gemacht wurde
};
Daraus schließe ich, dass die Rückgabe eines Null-Geschäfts-Tickets durch den Server garantiert, dass die Position nicht geöffnet werden kann und dass sie auf der Grundlage dieser Anfrage nicht weiter geöffnet werden wird.
Ich verstehe die Struktur des Forums nicht ganz, wenn nicht dort, bitte leiten Sie mich in die richtige Richtung
Da ich kein Spezialist bin, mich aber für das Programmieren interessiere und von meinen eigenen Neigungen bei der Ausbildung ausgehe, versuche ich, durch die Analyse des vorhandenen Codes zu verstehen
Der Einfachheit halber nahm ich ein Stück benutzerdefinierten Code von MA, und versuchen zu verstehen, was darin vorkommt (ich spiegelte es in Kommentaren)
Im Allgemeinen, wenn nicht schwierig, bitte kommentieren Sie den Code, ich möchte verstehen, was nach jedem Befehl passiert. Ich danke Ihnen.
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])//Ich habe es herausgefunden &price[].
legen Sie es in den Ausdruck und sehen Sie, dass die Werte im ExtLineBuffer vom Index limit-1bis zum Index rates_total-1 zugewiesen werden, aber im Diagramm wird der Indikator im gesamten Raum gezeichnet, hmm, wo ist dann die Wertzuweisung an denIndikatorpuffer auf dem Intervall von 1 bis limit-1??
Ich verstehe die Struktur des Forums nicht ganz, wenn nicht dort, bitte leiten Sie mich in die richtige Richtung
Da ich kein Spezialist bin, mich aber für das Programmieren interessiere und von meinen eigenen Neigungen bei der Ausbildung ausgehe, versuche ich, durch die Analyse des vorhandenen Codes zu verstehen
Der Einfachheit halber habe ich einen Teil des benutzerdefinierten Codes von MA genommen und versucht zu verstehen, was darin passiert (ich habe es in Kommentaren wiedergegeben)
Ich möchte verstehen, was nach jedem Befehl passiert. Ich danke Ihnen.
Ich werde mich nicht im Detail äußern, es mag genügen, den grundlegenden Fehler in Ihrer Wahrnehmung zu korrigieren, und dann werden Sie das Puzzle selbst zusammensetzen - das ist viel nützlicher.
Der Grund für Ihre Verwirrung ist also, dass viele Indikatoren in mql5 (insbesondere dieser) ohne Indexierung der Indikatorpuffer geschrieben werden, d.h. mit dem Wert AsSeries=false.
Das bedeutet, dass der Index des ältesten Balkens in der Historie = 0 und der "frischeste" Balken = RatesTotal-1 ist.
// Ist etwas klar?
Der Sinn eines solchen Ansatzes ist ein gewisser Geschwindigkeitsgewinn, da die Indexierung beim Zugriff auf den Puffer keine [versteckte] Neuberechnung erfordert (sie bleibt "hardwaremäßig")
// Vielleicht der (irrige) Glaube, dass die Indizierung für Indikatorpuffer IMMER vom Ende der Geschichte zum Anfang erfolgt. In mql4 ist dies immer der Fall, aber in mql5 ist es nicht notwendig.
// Hier ist die Richtung der Indizierung standardmäßig immer vom Anfang der Historie zu ihrem Ende. Um die Indizierung umzukehren, sollten Sie die Funktion SetAsSeries(...) in expliziter Form verwenden.
// Hinweis: Die Entwickler empfehlen, keine Standardwerte zu verwenden (für den Fall, dass sie sich ändern) und IMMER die Funktion SetAsSeries() zu verwenden, um die Indizierungsrichtung festzulegen.
void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[])//Ich habe &price[] aussortiert
setzen Sie es auf den Ausdruck und sehen Sie, dass die Werte im ExtLineBuffer vom Index limit-1bis zum Index rates_total-1 zugewiesen sind, aber im Diagramm wird der Indikator im gesamten Raum gezeichnet, hmm, wo ist dann der Wert, der demIndikatorpuffer im Intervall von 1 bis limit-1 zugewiesen ist?
Vielen Dank für Ihr Feedback).
Ich habe über die Reihenfolge der Richtwirkung in Arrays und Empfehlungen zur expliziten Angabe der Richtwirkung in der Hilfe gelesen, aber ich hatte einige Zweifel, die nach der Aufhebung von Zwischendaten in den Variablen beseitigt wurden.
Bisher ist nur die Direktionalität festgelegt, d.h. der Kommentar zur Initialisierung war falsch und die Werte des Indikatorpuffers werden auf den angegebenen Bereich auf der linken Seite des Charts initialisiert.
Es gibt noch Fragen über
1. die Variable begin, ist das Terminal für ihren Wert verantwortlich, der an den Event-Handler übergeben wird?
2. Kann eine Variable vom Typ double an den Typ int übergeben werden?
3. es scheint, dass das Terminal auch für den Wert der Variablen prev_calculated verantwortlich ist
4. Es ist nicht klar, wo die Berechnung des Indikators auf dem Intervall von 0 bis Grenze-1 stattfindet.
Es gibt noch Fragen zu
1. die Variable begin, ist das Terminal dafür verantwortlich, dass ihr Wert an den Event-Handler gesendet wird?
3. es scheint, dass der Wert der Variablen prev_calculated auch für das Terminal verantwortlich ist
Höchstwahrscheinlich wurde die diskutierte Funktion für die erste Form des OnCalculate()-Funktionsaufrufs geschrieben. Siehe Referenz.
Wir haben noch Fragen zu
2) Kann eine Variable vom Typ double durch einen Wert vom Typ int ersetzt werden?
Ja, das können Sie. Siehe den Abschnitt über implizite Typkonvertierung. Der Compiler gibt oft eine Warnung über den möglichen Verlust von Daten aus, wenn eine implizite Typkonvertierung verwendet wird.
Dennoch gibt es Fragen über
4. ich verstehe nicht, wo der Indikator auf dem Intervall von 0 bis Grenze-1 berechnet wird.
Beantworten diese Zeilen Ihre Frage:
//--- set empty value for first limit bars for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0; //--- calculate first visible value ... и далее по коду
?Vielen Dank für Ihr Feedback).
Ich habe über die Reihenfolge der Richtwirkung in Arrays und Empfehlungen zur expliziten Angabe der Richtwirkung in der Hilfe gelesen, aber ich hatte einige Zweifel, die nach der Aufhebung von Zwischendaten in den Variablen beseitigt wurden.
Bisher ist nur die Direktionalität festgelegt, d.h. der Kommentar zur Initialisierung war falsch und die Werte des Indikatorpuffers werden auf den angegebenen Bereich auf der linken Seite des Charts initialisiert.
Es gibt noch Fragen zu
1. die Variable begin, ist das Terminal dafür verantwortlich, dass ihr Wert an den Event-Handler gesendet wird?
Dieser Parameter gibt dem Indikator an, wie viele anfängliche historische Werte der Eingabereihen ignoriert (übersprungen) werden sollen, weil sie falsch sind und nicht an den Berechnungen teilnehmen sollen. Woher kann eine solche Unrichtigkeit kommen, was ist ihr Ursprung? Dies hängt mit der Möglichkeit zusammen, Indikatoren zu erstellen, die nicht auf der Grundlage von Preisdaten, sondern auf der Grundlage von Daten anderer Indikatoren berechnet werden. In MT5 gibt es drei Mechanismen, die es ermöglichen, Daten eines anderen Indikators für die Eingabe eines Indikators zu erhalten.Methode 1. Abfolge der Schritte:
Erstellen Sie ein Handle für den Eingabe-Indikator mit einem der iIndicator(...)-Funktionen oder IndicatorCreate(...).
2. bei Bedarf die Werte aus den Puffern mit der Funktion CopyBuffer(...) übernehmen.
Der zweite Weg. Sie ist notwendig, wenn wir im ersten Fall nicht eine Preisreihe, sondern eine Indikatorreihe an den Eingangsindikator weitergeben wollen. D.h., in diesem Fall werden wir Werte erhalten, die vom Eingangsindikator (2) berechnet werden, der Daten eines anderen Indikators (1) auf seinem eigenen Input nimmt. D.h., wir wollen die Indikator-aus-Indikator-Kette aufbauen.
Abfolge der Schritte:
1. Erstellen Sie ein Handle für den ersten (1) Eingangsindikator mit einem der iIndicator(...)-Funktionen oder der Funktion IndicatorCreate(...).
2. Erstellen Sie ein Handle des zweiten (2) Indikators mit der gleichen Methode, aber geben Sie das Handle des ersten (1) als letzten Parameter an(applied_price), wenn Sie es erstellen.
Verwenden Sie die Funktion CopyBuffer(...), um die Werte aus den Indikatorpuffern nach Bedarf abzurufen.
Die dritte Methode wird auch für die Bildung von Indikatorenketten verwendet, aber im Gegensatz zur vorherigen Methode ist die Datenquelle (Eingabereihenfolge) nicht vor der Kompilierung festgelegt, sondern kann vom Benutzer direkt im Terminal eingestellt werden, indem der entsprechende Parameter beim Start des Indikators angegeben wird.
Ich werde es Ihnen überlassen, diese Mechanismen selbst zu verstehen. Ich habe im vorangegangenen Text viele direkte Links zu den wichtigsten Stellen in der Dokumentation angegeben, die Ihnen dabei helfen werden.
Konzentrieren wir uns nur auf die Parameter der Kurzform des Aufrufs von OnCalculate():
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
Ihr Zweck ist ganz klar dokumentiert. Hier möchte ich nur die Notwendigkeit (Sinnhaftigkeit) der Übergabe in diese Funktion erklären. Mit dem ersten und letzten Parameter ist hoffentlich alles klar genug. Um Berechnungen durchführen zu können, müssen wir über einen Puffer mit Eingabedaten (price[]) verfügen und dessen aktuelle Länge kennen. (Vergessen Sie nicht, dass die Länge des Textes zunimmt, wenn die Anführungszeichen das Terminal ausfüllen).
Darüber hinaus müssen wir aber auch von Anfang an wissen, dass die Daten der Eingabezeile absolut korrekt sind, oder die Anfangswerte sollten aufgrund ihrer (möglichen oder garantierten) Unkorrektheit ignoriert werden. In den meisten Fällen ist die Unrichtigkeit garantiert, wenn die Eingabedaten die Ausgabe eines anderen Indikators sind, aber wie sonst? Die meisten Indikatoren müssen zur Berechnung des Wertes eines beliebigen Balkens eine bestimmte Menge an historischen Daten verwenden. Aber wo sind diese "am Anfang der Zeit" zu finden? Sie sind dort nicht vorhanden, und daher sind sie gezwungen, ihre Ausgabewerte nicht vom Startbalken der Historie aus zu generieren, sondern später (nach rechts), von dem Balken aus, der links davon liegt und für den die erforderliche Menge an historischen Daten bereits existiert.
Dank der oben beschriebenen Details kann die Frage nun beantwortet werden
woher kommt sein Wert? // es handelt sich um den Parameter begin
Die Antwort lautet: Obwohl dieser Parameter vom Terminal an die Funktion übergeben wird, muss sich der Eingabe-Indikator um seinen Inhalt kümmern! Das Terminal selbst kann nur Preiseingabezeilen überprüfen (in diesem Fall wird der Wert von begin 0 sein und das ist ein korrekter Wert). Wenn Sie also einen Indikator schreiben (außer den rein experimentellen), sollten Sie sicherstellen, dass er dem Terminal den Index des Beginns der richtigen Daten in seinem Ausgabepuffer mitteilt. Ist das klar? Andernfalls können die "Nachkommen" dieses Indikators sehr unangenehme falsche Daten essen, und in einigen Fällen können sie sogar krank werden... :) Jetzt wird die Funktion PlotIndexSetInteger() verwendet, indem der Bezeichner der PLOT_DRAW_BEGIN-Eigenschaft angegeben wird. Wichtig! Für eine 100%ige Korrektheit der generierten Indikatoreigenschaft muss ein einziger Aufruf von PlotIndexSetInteger(....PLOT_DRAW_BEGIN, ...) in OnInit()! Warum? Weil unser Indikator selbst auf den Daten eines anderen Indikators gebildet werden kann, der einen anfänglichen Einzug in der Historie hat. Das heißt, wir haben einen Nicht-Null-Wert von begin in der Eingabe-Historie, und es gibt keine Möglichkeit, ihn in OnInit() zu empfangen.
PlotIndexSetInteger(MySymbol,PLOT_DRAW_BEGIN,MyBeginPeriod-1+begin);
Und wir müssen es (vorzugsweise einmal) in OnCalculate() machen, denn in OnInit ist der Wert von begin unbekannt.
Damit haben wir natürlich auch das Recht, eine vorläufige (wenn auch nicht sehr aussagekräftige) Forderung zu stellen
PlotIndexSetInteger(MySymbol,PLOT_DRAW_BEGIN,MyBeginPeriod);
in OnInit().
Dies ist genau das, was in dem Indikator (Custom Moving Average.mq5) geschieht, aus dem Sie Ihr Beispiel für die Untersuchung entnommen haben.
2. Kann eine Variable vom Typ double auch vom Typ int sein?
Ja, eine Variable vom Typ double kann problemlos mit einem Wert vom Typ int initialisiert werden, wenn sie durch eine Konstante definiert ist. // was genau das ist, was wir in Ihrem Beispiel tun können.
3. es scheint, dass das Terminal auch für den Wert der Variablen prev_calculated verantwortlich ist
4. es ist nicht klar, wo im Intervall von 0 bis Grenze-1 der Indikator berechnet wird
In diesem Fall können diese Werte nicht korrekt berechnet werden (wir haben nicht genug Historie für die Berechnungen), deshalb werden ihnen einfach Nullwerte zugewiesen.
// Ich würde es vorziehen, ihnen entsprechende Eingabedaten zuzuordnen, aber das ändert nichts am Kern der Sache.