Expert Advisors: Arbitrage Synthetisch - Seite 3

 
bas:

Maxim Dmitrievsky, wenn es kein Geheimnis ist, was war der Ping zum Server dieses Bots? Und was ist die durchschnittliche Ausführungszeit? Ich habe 10ms und 200ms, und das ist oft nicht genug, um ausgeführt zu werden, während die Arbitrage besteht.

Und wie bestimmen Sie, welches der beiden verbleibenden Paare, außer dem führenden, "aufholen" wird? Ich verwende zum Beispiel einfach historische Statistiken. Wenn der EURUSD führt, ist es normalerweise nicht das Kreuz, das ihn einholt, sondern das zweite usd-Leg, aber das ist nicht bei allen Triples der Fall.


leider ist dieses Thema schon tot. pings waren null. 200 ms sind schon viel für Latenz-Arbitrage (man bedenke 400 ms, weil das Geschäft noch geschlossen werden muss + Slippages/Markups).

Die Hauptidee war, dass, wenn die synthetische bereits geändert hat und das Währungspaar hat nicht, dann wahrscheinlich gibt es eine Delle in der Notierung und es wird bald mit ihm auszugleichen. und es wäre sinnlos, eine Menge Zeit auf sie zu verbringen. Traded mit diesem Bot für eine kurze Zeit, legte auf ein paar Reals - auf einem ein wenig verdient auf der anderen ein wenig verloren, machte Abzüge.

Ich habe den Bot vor allem für die Tatsache, dass eine Menge Fragen entstanden auf dieser Strategie in den letzten ein halbes Jahr Menschen. Um meine Meinung zu teilen. Viele Leute schreiben oder denken darüber nach, aber es waren keine freien Beispiele zu spüren. Eine weitere Optimierung ist sinnlos, da moderne Broker nicht für hft ausgelegt sind, und generell ist 3-Punkt-Arbitrage ein Mythos, es gibt keine solche Arbitrage, weder in einbeiniger noch in 3-beiniger Form.

 

Bei einigen Währungen (TRY, NZD) können die Abweichungen stundenlang andauern, aber das kann man nicht im Voraus herausfinden, und es ist nicht interessant, so lange auf einem Geschäft zu sitzen.

Die Synthetik besteht aus zwei Paaren. Normalerweise holt nur eines von ihnen auf, und das dritte bleibt stehen. Deshalb habe ich gefragt, wie man feststellen kann, welches der beiden Paare aufholen wird.

Und die Schließung erfolgt, nachdem die Arbitrage zusammengebrochen ist, wobei die Ausführungszeit nicht so wichtig ist.

Warum "gibt es nicht"? Ich beobachte es regelmäßig), aber ich habe nicht genug Geschwindigkeit.

 
bas:

Bei einigen Währungen (TRY, NZD) können die Abweichungen stundenlang andauern, aber das kann man nicht im Voraus herausfinden, und es ist nicht interessant, so lange auf einem Geschäft zu sitzen.

Die Synthetik besteht aus zwei Paaren. Normalerweise holt nur eines von ihnen auf, und das dritte bleibt stehen. Deshalb habe ich gefragt, wie man feststellen kann, welches der beiden Paare aufholen wird.

Und die Schließung erfolgt, nachdem die Arbitrage zusammengebrochen ist, wobei die Ausführungszeit nicht so wichtig ist.

Warum "gibt es nicht"? Ich sehe es regelmäßig), aber ich habe nicht genug Geschwindigkeit.


Es gibt sie nicht wegen der Geschwindigkeit.

und es tritt oft wegen Verzögerungen bei der Angebotserstellung auf, man erhält ein indikatives Angebot, das entweder verzögert oder gar nicht real ist.

Diese Verzerrungen, von denen Sie sprechen, werden später von den Maklerfirmen korrigiert, wenn sie sie bemerken...

Deshalb habe ich gefragt, wie man feststellen kann, welche der beiden Möglichkeiten sich durchsetzen wird.

Im Grunde kann man das nicht, nur experimentell oder durch den Handel mit drei Beinen. Oder zumindest mit 33% Wahrscheinlichkeit, dass es unser Paar ist, das hinterherhinkt, was keine kleine Zahl ist :)

 
Okay, es gibt sie nicht, also gibt es sie auch nicht)
 
bas:
Na gut, es gibt sie nicht, also gibt es sie auch nicht.)

Nein, aber du versuchst es trotzdem, wenn du willst, ich bin nicht die Wahrheit in letzter Instanz :))

Ich überprüfe alles anhand meiner eigenen Erfahrungen... und auch anhand der Erfahrungen anderer. Und wenn die Zeit zu schade ist, ist es besser, es nicht zu tun.

Wie in Yeralash - "Hier gibt es keine Fische!" (mehrere Male)

- Wer sagt das?

- Wer ist wer, der Direktor des Stadions!

 
Maxim Dmitrievsky:

Nein, versuchen Sie es ruhig, wenn Sie wollen, ich bin schließlich nicht die Wahrheit :)

Ich überprüfe alles anhand meiner eigenen Erfahrungen... und auch anhand der Erfahrungen anderer. Und wenn die Zeit zu schade ist, ist es besser, es nicht zu tun.

Wie in Yeralash - "Hier gibt es keine Fische!" (mehrere Male)

- Wer sagt das?

- Wer ist wer, der Direktor des Stadions!


- Der Direktor der Eissporthalle.

 

Wenn Sie ein Beispiel für ein Dreieck posten, können Sie es ästhetisch ansprechender gestalten, nämlich OnTimer, das Ticks überspringt, durch OnChartEvent ersetzen, das Ticks von allen Instrumenten empfängt, den Indikator von hier - https://www.mql5.com/de/articles/234

Im Allgemeinen, ja, kein Fisch, Pipsing ist nicht für den Einzelhandel, wenn Sie den Spread + Kommission zu berücksichtigen, auf dem Hauptdreieck wird es nur 3 Trades pro Jahr mit einem mageren Gewinn, und dass Broker kann es nicht geben, weil in einer idealen Welt EURUSD / GBPUSD = EURGBP, und wenn das Gegenteil passiert, ist es ein Nicht-Markt-Kurs :)

#include <AIV/Trades.mqh>
#include <AIV/Charts.mqh>

input int InpMagic = 0;
input double InpFactor = 2;
input double InpVolume = 0.01;
input double InpCommission = 30;
input string iACName = "EURUSD";
input string iBCName = "GBPUSD";
input string iABName = "EURGBP";

int iDirection;

SSymbol iACData = {0};
SSymbol iBCData = {0};
SSymbol iABData = {0};

SSeries iSeries[];

CSets * iSets;
CHelpers * iHelpers;
CPositions * iPositions;

void OnDeinit(const int reason)
{
    delete(iSets);
    delete(iHelpers);
    delete(iPositions);
}

int OnInit()
{
    long chart = ChartID();

    iSets = new CSets();
    iHelpers = new CHelpers();
    iPositions = new CPositions();

    iCustom(iACName, PERIOD_M1, "AIV\\Spy", chart, 1);
    iCustom(iBCName, PERIOD_M1, "AIV\\Spy", chart, 2);
    iCustom(iABName, PERIOD_M1, "AIV\\Spy", chart, 3);

    return 0;
}

void Trade()
{
    int positions = PositionsTotal();

    double incomeAC = iPositions.getPositionsIncome(iACName, 0, InpMagic);
    double incomeBC = iPositions.getPositionsIncome(iBCName, 0, InpMagic);
    double incomeAB = iPositions.getPositionsIncome(iABName, 0, InpMagic);

    // Volatilität der Instrumente angleichen

    double sizeAC = InpVolume / iHelpers.getTickCost(iACName);
    double sizeBC = InpVolume / iHelpers.getTickCost(iBCName);
    double sizeAB = InpVolume / iHelpers.getTickCost(iABName);

    // Wenn wir im Dreieck Gewinn gemacht haben, schließen wir die Positionen

    if (positions > 0)
    {
        if (incomeAC + incomeBC + incomeAB > 0) 
        {
            iPositions.closePositions(NULL, 0, InpMagic);
            return;
        }
    }
    else
    {
        int direction = isGap();

        // Wenn Synthetik über EURGBP liegt

        if (direction == 1) 
        {
            iDirection = direction;
            iPositions.openSimplePosition(iACName, iDirection * -1, sizeAC, 0, 0, 0, InpMagic);
            iPositions.openSimplePosition(iBCName, iDirection, sizeBC, 0, 0, 0, InpMagic);
            iPositions.openSimplePosition(iABName, iDirection, sizeAB, 0, 0, 0, InpMagic);
        }
        else if (direction == -1) // Wenn EURGBP höher ist
        {
            iDirection = direction;
            iPositions.openSimplePosition(iACName, iDirection, sizeAC, 0, 0, 0, InpMagic);
            iPositions.openSimplePosition(iBCName, iDirection * -1, sizeBC, 0, 0, 0, InpMagic);
            iPositions.openSimplePosition(iABName, iDirection * -1, sizeAB, 0, 0, 0, InpMagic);
        }
    }
}

int isGap()
{
    if (iACData.mUnit <= 0 || iBCData.mUnit <= 0 || iABData.mUnit <= 0)
    {
        return 0;
    }

    double X = iACData.mUnit / iBCData.mUnit;
    double Y = iABData.mUnit;
    double spread = 2 * (iACData.mMean + iBCData.mMean + iABData.mMean);

    double commission = 
        2 * iACData.mUnit * iHelpers.moneyToPips(iACName, InpVolume, InpCommission * InpVolume) + 
        2 * iBCData.mUnit * iHelpers.moneyToPips(iBCName, InpVolume, InpCommission * InpVolume) + 
        2 * iABData.mUnit * iHelpers.moneyToPips(iABName, InpVolume, InpCommission * InpVolume);

    // Wenn Abstand EURUSD / GBPUSD - EURGBP > Provision + Spread

    if (X - Y - spread - commission > 0)
    {
        return 1;
    }
    else if (Y - X - spread - commission > 0) // Umgekehrt.
    {
        return -1;
    }

    return 0;
}

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
    if (id > CHARTEVENT_CUSTOM) 
    {
        string message[];

        // Aggregate prices from 3 charts here, every "sparam" contains data in format "EURUSD:1.22350:30" or "GBPUSD:1.52450:15" or "EURGBP:1.22350:3"

        StringSplit(sparam, ':', message);

        if (ArraySize(message) < 3)
        {
            return;
        }

        string symbol = message[0];
        int event = id - CHARTEVENT_CUSTOM;
        double close = StringToDouble(message[1]);
        double spread = StringToDouble(message[2]) * SymbolInfoDouble(symbol, SYMBOL_POINT);

        if (symbol == iACName)
        {
            iACData.mName = symbol;
            iACData.mUnit = close;
            iACData.mMean = spread;
        }
        else if (symbol == iBCName)
        {
            iBCData.mName = symbol;
            iBCData.mUnit = close;
            iBCData.mMean = spread;
        }
        else if (symbol == iABName)
        {
            iABData.mName = symbol;
            iABData.mUnit = close;
            iABData.mMean = spread;
        }
 
        // Handel nur, wenn wir die Preise von allen 3 Paaren haben

        if (iACData.mUnit > 0 && iBCData.mUnit > 0 && iABData.mUnit > 0)
        {
            Trade();
        }
    }
}

Nur für den Fall und vereinfachten Code von Spy Indikator :)

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1

input long InpChart = 0;
input ushort InpEventId = 0;

int OnCalculate (
    const int bars,
    const int counted,
    const datetime& times[],
    const double& opens[],
    const double& highs[],
    const double& lows[],
    const double& closes[],
    const long& ticks[],
    const long& volumes[],
    const int& spreads[])
{
    string close = DoubleToString(closes[bars - 1]);
    string spread = DoubleToString(spreads[bars - 1]);
    EventChartCustom(InpChart, InpEventId, (long) Period(), bars, Symbol() + ":" + close + ":" + spread); // Ticks aus allen Diagrammen in einen einzigen Event-Handler übersetzen
    return bars;
}
 
Andy Sanders:

Nur für den Fall und vereinfachten Code von Spy Indikator :)

Alternative Variante.

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

Sie können es so machen, aber in meinem Fall übergebe ich ein Bündel von Daten "EURUSD:1.22350:30" durch sparam, um den EA-Code nicht mit separaten SymbolInfoTick-Aufrufen für jedes Symbol zu überladen

 

Und falls es jemanden interessiert, es gibt eine interessante Implementierung von Pair Trading mit Rebalancing und Holding, die nicht für Swap-Konten ist, sondern nur für echte Aktien
https://www.quantconnect.com/forum/discussion/1257/pairs-trading-with-coke--pepsi.