Merkmale der Sprache mql5, Feinheiten und Techniken - Seite 208

 
mktr8591:

Offenbar habe ich die Handelssituation missverstanden.

Ich habe mir das so vorgestellt: Der schwebende Limitauftrag wurde von mehreren Geschäften ausgeführt. Die ganze Zeit hing es in Live-Aufträgen und das Feld ORDER_TIME_SETUP war keine Konstante. Nach dem letzten Handel ging er in die Geschichte ein. In diesem Moment wurde ORDER_TIME_SETUP zu einer Konstante.

Oder war es das nicht?

ORDER_TIME_SETUP ist immer eine Konstante. In der Historie wurde ORDER_TIME_DONE angezeigt.

 
fxsaber:

ORDER_TIME_SETUP ist immer eine Konstante. Bei einem Treffer in der Historie erschien ORDER_TIME_DONE.

Hier setze ich nun die verzögerte Grenze. Dann ändere ich es von Hand und per Skript und ORDER_TIME_SETUP ändert sich.

Was mache ich falsch?

 
Особенности языка mql5, тонкости и приёмы работы
Особенности языка mql5, тонкости и приёмы работы
  • 2020.04.09
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql5, примеры решения тех, или иных задач...
 
mktr8591:

Hier stelle ich nun einen verzögerten Begrenzer ein. Dann ändere ich sie manuell und das Skript und ORDER_TIME_SETUP ändern sich.

Was mache ich falsch?

Die eingestellte Zeit wird dadurch nicht verändert.

 

Das habe ich in der Tat. Aber ich konnte mich überhaupt nicht daran erinnern. Ich glaube, es ist ein Fehler.


fxsaber:

Ich weiß nicht, was mit der wiederholten teilweisen Ausführung passieren wird.

Jetzt weiß ich, dass es sich bei diesem Broker (ich tippe auf einen Fehler in der Software) nicht mehr ändern wird.

 
// Возвращает снепшот котирования символа.
int QuotesSnapshot( const string Symb = NULL, const datetime From = 0 )
{    
  int Snapshot = INT_MAX;

  MqlTick Ticks[];
  
#define  DAY (24 * 3600)  
  const int Size = CopyTicksRange(Symb, Ticks, COPY_TICKS_INFO, From ? From * 1000 : SymbolInfoInteger(Symb, SYMBOL_TIME) / DAY * DAY * 1000);
#undef  DAY  
  
  for (int i = 1; i < Size; i++)
  {
    const int Interval = (int)(Ticks[i].time_msc - Ticks[i - 1].time_msc);
    
    if (Interval < Snapshot)
      Snapshot = Interval;
  }
  
  return(Snapshot);
}

Manchmal ist es nützlich zu wissen, wie oft Tics gesendet werden.

 

Eine CloseBy-Transaktion erzeugt zwei Abschlüsse. Der Swap der ersten Transaktion (erste Position in CloseBy) enthält die Summe der Swaps der beiden Positionen. Der Swap des zweiten Geschäfts ist Null.

Wenn die Position teilweise über CloseBy geschlossen wird, wird der verbleibende Teil der offenen Position nicht mehr getauscht, sondern auf Null gesetzt.


// Демонстрация работы со свопами во время частичного закрытия через CloseBy.

#define  REPORT_TESTER             // В тестере будут автоматически записываться отчеты
#define  REPORT_BROWSER            // Создание отчета с запуском браузера - требует разрешения DLL.
#include <Report.mqh> // https://www.mql5.com/ru/code/18801

#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnTick()
{
  static bool FirstRun = true;
  
  if (FirstRun)
  {
    if (!OrderSelect(0, SELECT_BY_POS))
      FirstRun = OrderSend(_Symbol, OP_BUY, 100, Ask, 0, 0, 0);
    else if (OrderSwap())
    {
      const TICKET_TYPE Ticket = OrderTicket();
      
//      FirstRun = !(OrderCloseBy(OrderSend(_Symbol, OP_SELL, 0.01, OrderClosePrice(),0, 0, 0), Ticket) &&
      FirstRun = !(OrderCloseBy(Ticket, OrderSend(_Symbol, OP_SELL, 0.01, OrderClosePrice(),0, 0, 0)) &&
                   OrderSelect(0, SELECT_BY_POS) && OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0));      
    }    
  }    
}


Ergebnis.


Es kann also durchaus sein, dass bei der kleinsten Position, die noch nie einen Rollover durchlaufen hat, ein großer Swap stattfindet. Und Zero Swap für eine große Position, die umgeschlagen ist.

 

Berechnung der Anzahl der Überschläge (nicht die schnellste Option).

#define  DAY  (24 * 3600)
#define  WEEK (DAY * 7)

// Возврящает количество "четвергов" между двумя датами.
int GetAmountWeekDay( const datetime Begin, const datetime End, const int DayWeek = -1 )
{
  const datetime OffsetTime = (DayWeek - WEDNESDAY) * DAY;
  
  return((DayWeek != -1) ? (int)((End - OffsetTime) / WEEK - (Begin - OffsetTime) / WEEK) : 0);
}

// Возврящает количество рабочих дней между двумя датами.
int GetAmountWorkingDays( const datetime Begin, const datetime End )
{
  const int Res = (int)(End / DAY - Begin / DAY);
  
  return(Res ? Res - GetAmountWeekDay(Begin, End, SATURDAY) - GetAmountWeekDay(Begin, End, SUNDAY) : 0);
}

// Возвращает количество ролловеров (включая тройные) между двумя датами.
int GetRolloverAmounts( datetime TimeOpen, datetime TimeClose,
                        datetime RolloverTime = 0, const int Rollover3Days = WEDNESDAY )
{
  RolloverTime = RolloverTime % DAY;
  
  TimeOpen -= RolloverTime;
  TimeClose -= RolloverTime;
  
  const int Res = GetAmountWorkingDays(TimeOpen, TimeClose);
  
  return(Res ? Res + (GetAmountWeekDay(TimeOpen, TimeClose, Rollover3Days) << 1) : 0);
}

#undef  WEEK
#undef  DAY


Beispiel für die Verwendung.

// Сравниваем реальные и вычисленные значения свопов.

#include <MT4Orders.mqh>

input datetime inRolloverTime = 0; // Время ролловера
input int inCount = 100; // Маскимальное количество распечаток

// Вычисляет своп закрытой позиции.
double CalcOrderSwap( const datetime RolloverTime = 0 )
{
  return(((OrderType() <= OP_SELL) &&
          (SymbolInfoInteger(OrderSymbol(), SYMBOL_SWAP_MODE) == SYMBOL_SWAP_MODE_POINTS))
             // https://www.mql5.com/ru/forum/170952/page208#comment_24667438
           ? GetRolloverAmounts(OrderOpenTime(), OrderCloseTime(), RolloverTime,
             (int)SymbolInfoInteger(OrderSymbol(), SYMBOL_SWAP_ROLLOVER3DAYS)) *
             SymbolInfoDouble(OrderSymbol(), OrderType() ? SYMBOL_SWAP_SHORT : SYMBOL_SWAP_LONG) *
             SymbolInfoDouble(OrderSymbol(), SYMBOL_TRADE_TICK_VALUE) *
             OrderLots()
           : 0);
}

#define  TOSTRING(A) " " + #A + " = " + (string)(A)

void OnStart()
{  
  for (int i = OrdersHistoryTotal() - 1, Count = 0; (i >= 0) && (Count < inCount); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && OrderSwap())
    {
      OrderPrint();
      Print((string)Count++ + TOSTRING(OrderSwap()) + TOSTRING(CalcOrderSwap(inRolloverTime)) + "\n");
    }
}


Ergebnis.

#2122237 2021.09.09 23:09:15.512 sell 0.18 GBPCAD 1.75119 0.00000 1.75286 2021.09.10 04:27:40.506 1.75286 -0.84 -0.80 -20.07 7;[0] 7
97 OrderSwap() = -0.8 CalcOrderSwap(inRolloverTime) = -0.8048844238618312
 
fxsaber #:

Eine CloseBy-Transaktion erzeugt zwei Abschlüsse. Der Swap der ersten Transaktion (erste Position in CloseBy) enthält die Summe der Swaps der beiden Positionen. Der Swap des zweiten Geschäfts ist Null.

Wenn eine Position über CloseBy teilweise geschlossen wird, wird der verbleibende Teil der offenen Position nicht mehr getauscht, sondern auf Null gesetzt.

...

Es kann also durchaus sein, dass bei einer Mindestposition, die noch nie einen Rollover durchlaufen hat, ein großer Swap stattfindet. Und Zero Swap für eine große Position, die sich verlängert hat.

Erstaunlich!

Liegt es an der Rundung (um keinen Cent zu verlieren oder aufzurunden)?

Oder ist es nur ein selten genutzter Vorgang, so dass es keine Rolle spielt?

 
Andrey Khatimlianskii #:

Erstaunlich!

Liegt es an der Rundung (um keinen Cent zu verlieren oder aufzurunden)?

Definitiv nicht, da Teilabschlüsse (OrderClose, nicht vollständige OrderLots) den Swap entsprechend belasten.

Oder handelt es sich nur um einen selten genutzten Vorgang, so dass er keine Rolle spielt?

Ich glaube nicht, dass man sich viele Gedanken über die Szenarien gemacht hat.