Speed von GetPositionProperties()

Einloggen oder registrieren, um einen Kommentar zu schreiben
Christian Linden
421
Christian Linden  

Hallo,

ich prüfe, ob eine Position offen ist und, wenn ja, GetPositionProperties und Print einiger dieser. Die Values sind aber leider 0.00000.
Woran liegt das? Ein Geschwindigkeitsproblem?

Hier mein Code:

void OnTick()
{
  int total=PositionsTotal();
  if (total != 0)
  {
   GetPositionProperties();
   Print ("Anzahl PositionsTotal: ",total);
   Print("pos_oprice: ",DoubleToString(pos_oprice,5));
   Print("pos_cprice: ",DoubleToString(pos_cprice,5));
   Print("pos_spread: ",DoubleToString(pos_spread,5));
  }
}


-----------

GetPositionProperties ist in der globale Scope definiert:
  void GetPositionProperties()
   {
   pos_symbol     =PositionGetString(POSITION_SYMBOL);
   pos_comment    =PositionGetString(POSITION_COMMENT);
   pos_magic      =PositionGetInteger(POSITION_MAGIC);
   pos_oprice     =PositionGetDouble(POSITION_PRICE_OPEN);
   pos_cprice     =PositionGetDouble(POSITION_PRICE_CURRENT);
   pos_type       =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
   pos_volume     =PositionGetDouble(POSITION_VOLUME);
   pos_commission =PositionGetDouble(POSITION_COMMISSION);
   pos_swap       =PositionGetDouble(POSITION_SWAP);
   pos_profit     =PositionGetDouble(POSITION_PROFIT);
   pos_time       =(datetime)PositionGetInteger(POSITION_TIME);
   pos_id         =PositionGetInteger(POSITION_IDENTIFIER);
   pos_diffoc     =pos_oprice-pos_cprice;
   }

Der Output im Log ist leider der hier:

CO      0       14:18:50.472    Goldesel-fx_4 (EURUSD,M1)       Anzahl PositionsTotal: 1
ED      0       14:18:50.472    Goldesel-fx_4 (EURUSD,M1)       pos_oprice: 0.00000
CM      0       14:18:50.472    Goldesel-fx_4 (EURUSD,M1)       pos_cprice: 0.00000
ND      0       14:18:50.472    Goldesel-fx_4 (EURUSD,M1)       pos_spread: 0.00006

Der Spread ist angekommen, wieso die Preise nicht?

Vielen Dank & guten Rutsch,
Christian

Chris70
543
Chris70  
Die Position wurde nicht ausgewählt. Dazu vor den Abfragen 1x entweder PositionGetSymbol, PositionSelect (Achtung: dabei die Unterschiede bei Hedging-Mode vs. Netting Mode beachten) oder PositionSelectByTicket auführen.
Chris70
543
Chris70  

Beispiel (nicht getestet):

int total=PositionsTotal();
for (int p=0;p<total;p++)
  {
   if (PositionGetSymbol(p)==_Symbol)
     {
      GetPositionProperties();
      Print ("Anzahl PositionsTotal: ",total);
      Print("pos_oprice: ",DoubleToString(pos_oprice,5));
      Print("pos_cprice: ",DoubleToString(pos_cprice,5));
      Print("pos_spread: ",DoubleToString(pos_spread,5));
     }
  }

Es fällt außerdem auf, dass innerhalb der Funktion GetPositionProperties() der Wert für pos_spread gar nicht zugewiesen wird (abgesehen davon, dass formal der Spread ja gar keine Eigenschaft einer Position ist, sondern des zugehörigen Symbols).

Edit: alternativ (ebenfalls nicht getestet):

int total=PositionsTotal();
Print ("Anzahl PositionsTotal: ",total);

for (int p=0;p<total;p++)
  {
   PositionSelectByTicket(PositionGetTicket(p));
   GetPositionProperties();
   Print("Position Nr. ",p,", pos_oprice: ",DoubleToString(pos_oprice,5));
   Print("Position Nr. ",p,", pos_cprice: ",DoubleToString(pos_cprice,5));
   // usw.      
  }
Otto Pauser
2172
Otto Pauser  

Der wesentliche Punkt ist:

PositionSelect(_Symbol);

Erst danach liefert die Funktion PositionGetDouble() sinnvolle Werte.

Eine sinnvolle Erweiterung der Systembibliothek fehlt leider.

Um diesen Mangel zu beheben habe ich über lange Zeit dies Erweiterung geschaffen.

Diese Include-Datei vereint Trade.mqh, PositionInfo.mqh und Accountinfo.mqh zu einem sinnvollen ganzen, der TradeExt.mqh.

Eine 'light' Version ist TradeExtSimple.mqh.

Ein Anwendungsbeispiel:

#include <Trade\TradeExtSimple.mqh>

int OnInit()
{
   OnTick();      // sofortige Anzeige der Werte, nur in dieser Demo
   // ...
   // ...
   // ...
   return(INIT_SUCCEEDED);
}

void OnTick()
{
   if(!Trade.OnTick())    // sollte als erste Funktion aufgerufen werden
      return;
      
   Comment(    "\nAsk: " ,DoubleToString(Trade.Ask,_Digits),
               "\nBid: " ,DoubleToString(Trade.Bid,_Digits),
            "\nSpread: " ,Trade.Spread,
            "\nAcount: " ,Trade.AccBalance,
            "\nProfit: " ,DoubleToString(Trade.PosProfit,2),
           "\nPosOpen: " ,Trade.PosOpened,
           "\nPosType: " ,PosTypeToString(Trade.PosType)
          );
}

string PosTypeToString(POSTYPE aPosType)   // für dieses Demo
{
   switch(aPosType)
     {
      case POSITION_TYPE_BUY : return("BUY");
      case POSITION_TYPE_SELL: return("SELL");
     }
   return("NONE");
}

Ein Anwendungsbeispiel:

#include <Trade\TradeExtSimple.mqh>

void OnTick()
{
   if(!Trade.OnTick())
      return;
      
   if(Trade.PosOpened)        // Position existiert
      switch(Trade.PosType)
        {
         case POSITION_TYPE_BUY:
         
         break;
         case POSITION_TYPE_SELL:
         
         break;
        }
   else                       // keine Position offen
      {
      
      }
}

Sogar die Instanz von CTadeExt (Trade) wird in der mqh definiert.

Das stellt sicher, daß alle Programmteile (Module) die selbe Instanz verwenden!

Schaut euch das bitte an, es zahlt sich aus! Für euch!

In der Codebase könnten tausende Programmzeilen dadurch entfallen und die EAs wären wesentlich übersichtlicher.

Weiter Vorteile:

1. Das langsame auslesen der Systemvariablen wird pro Tick nur einmal durchgeführt

2. Die Variablen können im Debugger überwacht werden, was mit Funktionen nicht funktioniert.

Dateien:
Christian Linden
421
Christian Linden  
Chris70:
Die Position wurde nicht ausgewählt. Dazu vor den Abfragen 1x entweder PositionGetSymbol, PositionSelect (Achtung: dabei die Unterschiede bei Hedging-Mode vs. Netting Mode beachten) oder PositionSelectByTicket auführen.

ahja, hatte ich schonmal gewusst.. wieder vergessen bzw. den Wald vor Bäumen nicht mehr gesehen.. danke fürs FingerPointing!

Christian Linden
421
Christian Linden  
Chris70:

Beispiel (nicht getestet):

Es fällt außerdem auf, dass innerhalb der Funktion GetPositionProperties() der Wert für pos_spread gar nicht zugewiesen wird (abgesehen davon, dass formal der Spread ja gar keine Eigenschaft einer Position ist, sondern des zugehörigen Symbols).

Edit: alternativ (ebenfalls nicht getestet):

Ja, sorry für die Verwirrung, den pos_spread berechne ich mir an andere Stelle selbst. Allerdings nicht so wie ich dachte, weil ask-bid nicht viel mit dem Spread beim Öffnen meiner Position zu tun hat, danke für den Hinweis.

pos_oprice haben wir ja, wie kann ich den Spread zu Zeiten des pos_oprices festhalten?

Christian Linden
421
Christian Linden  
Otto Pauser:

Der wesentliche Punkt ist:

Erst danach liefert die Funktion PositionGetDouble() sinnvolle Werte.

Eine sinnvolle Erweiterung der Systembibliothek fehlt leider.

Um diesen Mangel zu beheben habe ich über lange Zeit dies Erweiterung geschaffen.

Diese Include-Datei vereint Trade.mqh, PositionInfo.mqh und Accountinfo.mqh zu einem sinnvollen ganzen, der TradeExt.mqh.

Eine 'light' Version ist TradeExtSimple.mqh.

Ein Anwendungsbeispiel:

Ein Anwendungsbeispiel:

Sogar die Instanz von CTadeExt (Trade) wird in der mqh definiert.

Das stellt sicher, daß alle Programmteile (Module) die selbe Instanz verwenden!

Schaut euch das bitte an, es zahlt sich aus! Für euch!

In der Codebase könnten tausende Programmzeilen dadurch entfallen und die EAs wären wesentlich übersichtlicher.

Weiter Vorteile:

1. Das langsame auslesen der Systemvariablen wird pro Tick nur einmal durchgeführt

2. Die Variablen können im Debugger überwacht werden, was mit Funktionen nicht funktioniert.

Sehr interessant, sieht mir nach einem feinen Tuning aus, schau' ich mir an, danke!

Chris70
543
Chris70  
Otto Pauser:

Der wesentliche Punkt ist:

PositionSelect(_Symbol);

Erst danach liefert die Funktion PositionGetDouble() sinnvolle Werte.

Das richtet sich jetzt trotzdem mehr an @lindomatic als an @Otto Pauser:

Bitte beachten, dass im Hedging-Mode - zumal ja mehrere Positionen für das gleiche Symbol vorliegen können - die Funktion PositionSelect() nicht immer wirklich das tut, was man gerade will, denn es wird die Position mit dem niedrigsten Ticket ausgewählt (siehe Dokumentation). Dann ist PositionSelectByTicket die bessere Wahl.

Außerdem ist es so, dass PositionGetSymbol(), selbst wenn der Name das überhaupt nicht suggeriert, die Selektion der Position auch schon bereits mit inclusive hat, daher ist im ersten meiner beiden obigen Beispiele ein zusätzliches Aufrufen von PositionSelect oder PositionSelectByTicket überflüssig. Aber manchmal will man ja tatsächlich nicht nur Infos über Positionen des Chart-Symbols haben, sondern auch Fremdpositionen (z.B. Multi-Currency-EAs), in diesen Fällen führt dann an der Variante "by ticket" oder dem expliziten Prüfen des Symbols kein Weg vorbei. Außerdem auch daran denken, dass manchmal ja mehrere EAs parallel arbeiten können, daher macht es Sinn, hier auch direkt zu prüfen, ob die magic-Nr der Position überhaupt zum vorliegenden EA gehört.

Otto Pauser
2172
Otto Pauser  
lindomatic: wie kann ich den Spread zu Zeiten des pos_oprices festhalten?

Meinst du festhalten zu Zeitpunkt des Deals?

Da brauchst du ja nur unmittelbar nach dem Deal den Spread abfragen.


Oder meinst du den Spread später wenn die Position schon existiert feststellen?

Das könntest du mittels CopyTicksRange feststellen.


Aber wozu ? Der Spread von damals ist Geschichte.

Viel interessanter ist den Spread vordem Absetzen einer Order zu kennen (Filter!)

Christian Linden
421
Christian Linden  
Chris70:

Das richtet sich jetzt trotzdem mehr an @lindomatic als an @Otto Pauser:

Bitte beachten, dass im Hedging-Mode - zumal ja mehrere Positionen für das gleiche Symbol vorliegen können - die Funktion PositionSelect() nicht immer wirklich das tut, was man gerade will, denn es wird die Position mit dem niedrigsten Ticket ausgewählt (siehe Dokumentation). Dann ist PositionSelectByTicket die bessere Wahl.

Außerdem ist es so, dass PositionGetSymbol(), selbst wenn der Name das überhaupt nicht suggeriert, die Selektion der Position auch schon bereits mit inclusive hat, daher ist im ersten meiner beiden obigen Beispiele ein zusätzliches Aufrufen von PositionSelect oder PositionSelectByTicket überflüssig. Aber manchmal will man ja tatsächlich nicht nur Infos über Positionen des Chart-Symbols haben, sondern auch Fremdpositionen (z.B. Multi-Currency-EAs), in diesen Fällen führt dann an der Variante "by ticket" oder dem expliziten Prüfen des Symbols kein Weg vorbei. Außerdem auch daran denken, dass manchmal ja mehrere EAs parallel arbeiten können, daher macht es Sinn, hier auch direkt zu prüfen, ob die magic-Nr der Position überhaupt zum vorliegenden EA gehört.

sehr gute Hinweise hier; ich stelle mit einer bool var sicher, dass nur eine Position geöffnet ist; nach dem Öffnen "meiner Position" setze ich glBuyPlaced oder glSellPlaced auf true und Positionen werden nur bei !=true geöffnet; das funktioniert auch, ich habe immer nur eine offen.

Mehreres parallel mag Zukunftsmusik sein. Wenn mein Ding aber funktioniert, brauch' ich das nicht =P

Christian Linden
421
Christian Linden  
Otto Pauser:

Meinst du festhalten zu Zeitpunkt des Deals?

Da brauchst du ja nur unmittelbar nach dem Deal den Spread abfragen.


Oder meinst du den Spread später wenn die Position schon existiert feststellen?

Das könntest du mittels CopyTicksRange feststellen.


Aber wozu ? Der Spread von damals ist Geschichte.

Viel interessanter ist den Spread vordem Absetzen einer Order zu kennen (Filter!)

Stimmt, kann ich direkt nach dem Deal 1x abfragen, ok.

Nein, später ist egal.

Ich brauche den Spread vom Deal, weil ich anhand dessen (oprice + deal_spread bzw. - deal_spread beim SellTrade) beim gewünschten Verlauf des Trades meinen selbstgebastelten TrailingStop setze, um aus dem potentiellen Verlust raus zu sein.

123
Einloggen oder registrieren, um einen Kommentar zu schreiben