2
konzentrieren Sie sich auf
439
Anhänger

Eine praktische Untersuchung von Spot-Delivery-Arbitrage-Strategien: Die Fallstricke auf dem Weg vom Ideal zur Realität

Erstellt in: 2025-11-28 14:22:49, aktualisiert am: 2025-12-16 11:31:06
comments   0
hits   345

Eine praktische Untersuchung von Spot-Delivery-Arbitrage-Strategien: Die Fallstricke auf dem Weg vom Ideal zur Realität

Vorwort

Kürzlich fragte mich ein Freund, ob ich eine Arbitrage-Strategie entwickeln könnte, die auf der Inventor-Plattform fehlte. Ich dachte, es wäre nicht schwer, aber es dauerte fast einen Monat, bis die grundlegende Logik überhaupt funktionierte. Rückblickend waren die Hürden, auf die ich von der ersten Idee bis zur Umsetzung stieß, weitaus zahlreicher als erwartet.

Dieser Artikel dokumentiert die praktischen Probleme, die bei der Entwicklung dieser Arbitragestrategie auftraten, und die entwickelten Lösungen.Nur zu Lern- und Referenzzwecken; es hat keinen praktischen Investitionswert.

Die grundlegende Logik der Strategie

Zwischen dem Liefervertrag und dem Spotpreis besteht eine Preisdifferenz, die üblicherweise um einen bestimmten Durchschnittswert schwankt. Bei zu großen Preisabweichungen ergeben sich theoretisch Arbitragemöglichkeiten.

Die Ausgangsidee war einfach:

  • Überwachen Sie die Preisdifferenz zwischen Spot- und Lieferverträgen.
  • Eröffnen Sie eine Position, wenn die Preisdifferenz das Zweifache der Standardabweichung übersteigt.
  • Profitieren Sie, indem Sie Positionen schließen, sobald die Preisdifferenz wieder ihren ursprünglichen Wert erreicht.

Klingt toll, oder? In der Praxis werden Sie jedoch feststellen, dass allein der Schritt des “Eröffnens einer Position” unzählige Details beinhaltet.

Die erste Falle: die Stabilität der Preisspannen

Anfangs nutzten wir die Abweichung des Preisspreads als direkten Indikator, stellten aber fest, dass sich der Preisspread manchmal weiter ausdehnte und nicht zu seinem vorherigen Zustand zurückkehrte. Später erkannten wir…Nicht alle Preisspannen sind stabil.

Insbesondere mit Annäherung des Liefertermins kann sich das Verhalten des Spreads ändern. Daher wurde der ADF-Test hinzugefügt, um festzustellen, ob die Spread-Reihe stationär ist.

function adfTest(series, maxLag=null){
  const n = series.length;
  if(n<10) throw new Error('series too short');
  if(maxLag===null) maxLag = Math.floor(12*Math.pow(n/100, 1/4));
  
  // ... ADF检验的核心计算逻辑
  
  const res = ols(rows, Ys);
  const tstat = tStat(res.beta, res.cov, 1);
  return { tStat: tstat, pValue: pval, usedLag: p };
}

Anfangs führten wir zahlreiche Tests durch, darunter den Varianzverhältnistest, den Halbwertszeittest und den KS-Test. Wir stellten jedoch fest, dass zu viele Tests die Anzahl der Möglichkeiten zur Positionsöffnung deutlich reduzierten. Schließlich beschränkten wir uns auf den ADF-Test und legten den p-Wert-Schwellenwert auf 0,1 fest.

Noch wichtiger ist jedoch, dass ein zusätzliches Exemplar hinzugefügt wurde.Kontinuierlicher Ausfallzähler

if (!adfPass) {
  stationarityFailCount[deliverySymbol] = (stationarityFailCount[deliverySymbol] || 0) + 1;
} else {
  stationarityFailCount[deliverySymbol] = 0;
}

let consecutiveFails = stationarityFailCount[deliverySymbol];
let canTrade = consecutiveFails < CONFIG.consecutiveFailThreshold;

Der Handel ist untersagt, wenn der Test dreimal hintereinander fehlschlägt. Dies soll verhindern, dass in einem anormalen Marktzustand unüberlegt Positionen eröffnet werden.

Die zweite Falle: Die Verwirrung um Echtzeit-Gewinn- und Verluststatistiken.

Die Berechnung von Gewinnen und Verlusten bei einem Futures-Konto ist einfach; man muss nur die Veränderungen des USDT-Kurses betrachten. Bei Spot-Konten ist das anders; sie enthalten sowohl USDT als auch Kryptowährung. Wie berechnet man das?

Hier ist ein Detail, das leicht übersehen wird:Die Kosten für die Lagerung von Spotwaren ändern sich mit dem Handel.Wenn Sie beispielsweise eine Kryptowährung für 100 USDT kaufen, sie für 90 USDT verkaufen und sie dann für 85 USDT zurückkaufen, beträgt Ihr Einstandspreis nicht mehr die ursprünglichen 100 USDT. Die Berechnung des Wertes der Kryptowährung anhand des zum Zeitpunkt der Positionseröffnung festgelegten Preises spiegelt nicht die tatsächliche Gewinn- und Verlustsituation wider.

Die richtige Herangehensweise istErmitteln Sie den durchschnittlichen tatsächlichen Transaktionspreis aus dem Auftragsobjekt.

let openSpotPrice = (openSpotOrder && openSpotOrder.AvgPrice) ? 
  openSpotOrder.AvgPrice : record.openSpotPrice;
let closeSpotPrice = closeSpotOrder.AvgPrice || currentPair.spotPrice;

Anschließend wird die Rendite auf Basis des tatsächlichen Transaktionspreises berechnet:

// 正套:买现货+卖期货
if (record.direction === 'positive') {
  spotReturnRate = (closeSpotPrice - openSpotPrice) / openSpotPrice;
  deliveryReturnRate = (openDeliveryPrice - closeDeliveryPrice) / openDeliveryPrice;
} else {
  // 反套:卖现货+买期货
  spotReturnRate = (openSpotPrice - closeSpotPrice) / openSpotPrice;
  deliveryReturnRate = (closeDeliveryPrice - openDeliveryPrice) / openDeliveryPrice;
}

let totalReturnRate = spotReturnRate + deliveryReturnRate;
let requiredUSD = openSpotPrice * record.spotAmount;
let actualTotalPnl = totalReturnRate * requiredUSD;

Beachten Sie hier die Logik der Gewinn- und Verlustrechnung:

  • Reguläres SetZu diesem Zeitpunkt war der Spotmarkt long und der Terminmarkt short, daher beträgt der Gewinn/Verlust am Spotmarkt = (Schlusskurs - Eröffnungskurs) / Eröffnungskurs und der Gewinn/Verlust am Terminmarkt = (Eröffnungskurs - Schlusskurs) / Eröffnungskurs.
  • umkehrenDamals beinhaltete der Spothandel das Shorten von Waren, während der Futureshandel das Longen von Waren beinhaltete – also in entgegengesetzte Richtungen.

Schließlich werden die tatsächlichen Gewinne oder Verluste jeder einzelnen Transaktion zum Gesamtgewinn oder -verlust addiert:

accumulatedProfit += actualTotalPnl;
_G('accumulatedProfit', accumulatedProfit);

Die dritte große Falle: die Liquiditätsfalle

Das ist das eigentliche Problem. Warum bietet die Inventor Quantitative Platform nach 10 Jahren Betrieb so wenige Arbitragestrategien für Futures-Kontrakte? Die Antwort ist einfach:Unzureichende Liquidität auf dem Markt für Lieferverträge

Frage 1: Einzeltransaktion

Arbitrage ist kein Märchen, in dem man gleichzeitig Positionen eröffnet. Die Realität sieht anders aus:

  • Der Spot-Auftrag wurde ausgeführt, der Futures-Auftrag ist jedoch noch ausstehend.
  • Oder der Terminauftrag wurde ausgeführt, der Kassaauftrag jedoch storniert.

Dies ist ein klassisches Beispiel für ein einseitiges Risiko. Ein Teil des Risikos ist investiert, der andere noch nicht. In diesem Fall stellt jede Preisschwankung keine Arbitragemöglichkeit mehr dar, sondern eine einseitige Position.

Die Lösung besteht darin, sich anzuschließenRückrollmechanismus

if (!deliveryOrder) {
  Log('❌ 期货卖单失败,回滚现货');
  exchanges[0].CreateOrder(pair.spotSymbol, 'sell', -1, spotAmount);
  addCooldown(pair.deliverySymbol, pair.coin, '期货卖单失败,已回滚现货');
  return false;
}

Falls ein Teil der Transaktion fehlschlägt, platzieren Sie sofort eine Marktorder, um den bereits ausgeführten Teil zu schließen und so das Risiko dieses einzelnen Teils zu reduzieren.

Frage 2: Marktaufträge können auch abgelehnt werden.

Noch absurder ist, dass Marktorders manchmal auch fehlschlagen. Dies kann an Börsenrisikokontrollen oder unzureichender Markttiefe liegen; kurz gesagt, die Order wird einfach nicht ausgeführt.

Also habe ich es getan.Doppelmechanismus aus Marktorder und Limitorder

function createOrderWithFallback(exchange, symbol, direction, amount, limitPrice, orderType, maxRetry = 3) {
  let useMarketOrder = (limitPrice === -1);
  
  // 先尝试限价单
  if (!useMarketOrder) {
    orderId = exchange.CreateOrder(symbol, direction, limitPrice, amount);
    if (!orderId) {
      Log(`❌ 限价单提交失败,改用市价单`);
      useMarketOrder = true;
    }
  }
  
  // 限价单失败则用市价单
  if (useMarketOrder && !orderId) {
    orderId = exchange.CreateOrder(symbol, direction, -1, marketAmount);
  }
  
  // ... 检查订单状态,失败则重试
}

Das System kann maximal 3 Wiederholungsversuche unternehmen, wobei bei jedem Versuch eine Marktorder als Sicherheitsnetz verwendet wird.

Frage 3: Die Betragsfalle bei Spot-Kaufaufträgen

Diese Falle ist besonders gut versteckt und erfordert daher besondere Vorsicht. Die Menge für eine Terminmarktorder beträgt…Anzahl der MünzenDie beim Kauf einer Spotmarktorder bestellte Menge beträgt jedoch…USDT-Betrag

Hier wurde speziell eine Konvertierungslogik hinzugefügt:

function getActualAmount(useMarket) {
  if (isSpotBuy && useMarket) {
    // 现货市价买单:需要用USDT金额
    let currentPrice = getDepthMidPrice(exchange, symbol);
    let usdtAmount = amount * currentPrice;
    Log(`  💡 现货买单转换: ${amount.toFixed(6)} 币 → ${usdtAmount.toFixed(4)} USDT`);
    return usdtAmount;
  }
  return amount;
}

Der bei einer Limit-Order verwendete Kryptowährungsbetrag wird bei einer Market-Order automatisch in USDT umgerechnet.

Die vierte Falle: die Illusion von Arbitragemöglichkeiten

Ein weiteres ärgerliches Problem ist, dass ein Arbitragesignal erkannt wird und man bereit ist, eine Position zu eröffnen, die Gelegenheit aber bereits vorbei ist, wenn man den Auftrag erteilt.

Die Preise schwanken in Echtzeit, und die Marktbedingungen können sich zwischen der Signalerkennung und der tatsächlichen Ausführung einer Position geändert haben. Preisspannen können sich verringert haben, und Arbitragemöglichkeiten können verschwunden sein. Wenn Sie zu diesem Zeitpunkt dennoch unklugerweise eine Position eröffnen, werfen Sie nur unnötige Gebühren zum Fenster hinaus.

Also wurde es hinzugefügt.Sekundärer Bestätigungsmechanismus

// 开仓前重新获取实时价格并验证套利机会
Log('🔄 重新获取实时Depth盘口价格并验证套利机会...');

let realtimeSpotPrice = getDepthMidPrice(exchanges[0], pair.spotSymbol, true);
let realtimeDeliveryPrice = getDepthMidPrice(exchanges[1], pair.deliverySymbol, true);

let realtimeSpread = realtimeDeliveryPrice - realtimeSpotPrice;
let realtimeSpreadRate = realtimeSpread / realtimeSpotPrice;

// 重新计算实时Z-Score
let realtimeZScore = (realtimeSpreadRate - mu) / (sigma || 1e-6);

// 验证:实时Z-Score是否仍然满足开仓条件
if (absRealtimeZ < CONFIG.zScoreEntry) {
  Log('❌ 套利机会已消失!');
  Log('  取消开仓,避免亏损');
  return false;
}

Bevor Sie einen Auftrag erteilen, rufen Sie den Echtzeitpreis erneut ab, berechnen Sie den Z-Score neu und führen Sie den Auftrag nur dann aus, wenn Sie sicher sind, dass die Gelegenheit noch besteht.

Die fünfte Falle: Altlasten im Zusammenhang mit Termingeschäften.

Manchmal können nach dem Neustart einer Strategie oder der Schließung einer vorherigen Position Restpositionen im Futures-Konto verbleiben. Werden diese nicht berücksichtigt, überschneiden sich neue und alte Positionen, was zu einer unkontrollierbaren Positionsgröße führt.

Also wurde es hinzugefügt.Zwangsliquidation vor Eröffnung einer PositionDie Logik:

// 检查期货现有仓位并平仓
let existingPosition = getPositionBySymbol(pair.deliverySymbol);

if (existingPosition && Math.abs(existingPosition.Amount) > 0) {
  Log('⚠️ 检测到该合约的现有仓位,执行平仓操作...');
  
  let closeDirection = existingPosition.Type === PD_LONG ? 'closebuy' : 'closesell';
  let closeAmount = Math.abs(existingPosition.Amount);
  
  let closeOrder = createOrderWithFallback(
    exchanges[1],
    pair.deliverySymbol,
    closeDirection,
    closeAmount,
    -1,
    '期货'
  );
  
  if (!closeOrder) {
    Log('❌ 平仓现有持仓失败,终止开仓');
    addCooldown(pair.deliverySymbol, pair.coin, '平仓现有持仓失败');
    return false;
  }
}

Prüfen Sie vor dem Eröffnen einer Position diese zunächst. Sollten noch Positionen vorhanden sein, schließen Sie diese, um sicherzustellen, dass Ihr Konto bereinigt ist.

Die sechste große Falle: Die Verzögerungsfalle der Tickerdaten

Dies ist der gesamte Strategieentwicklungsprozess.Am besten versteckt und am tödlichstenEines der Probleme.

Nachdem die Strategie in Gang gesetzt wurde, wurde ein seltsames Phänomen beobachtet:

  • Es wurde ein Arbitrage-Signal erkannt, und es ist Zeit, eine Position zu eröffnen.
  • Der optimale Preis für eine Limit-Order wird berechnet, indem die Preisdifferenz vom Ticketpreis addiert und subtrahiert wird.
  • Daher blieb der Auftrag ausstehend und wartete auf seine Ausführung.
  • Nachdem lange Zeit keine Transaktion zustande gekommen war, wurde die Bestellung storniert.

Versuchen Sie es stattdessen mit Market-Orders? Das Ergebnis war noch schlechter:

  • Die Marktorder wurde erfolgreich ausgeführt.
  • Der Transaktionspreis wich jedoch völlig von der erwarteten Arbitragespanne ab.
  • Die geplante Arbitragemöglichkeit erwies sich nach Abschluss der Transaktion als unrentabel.

Was genau war passiert? Nach wiederholtem Vergleich der Live-Handelsdaten der Börse wurde das Problem schließlich entdeckt:

Ticker vs. Tiefe: Der grundlegende Unterschied zwischen Daten

Die Tickerdaten spiegeln den aktuellsten tatsächlichen Transaktionspreis wider.Das klingt gut, aber in Märkten mit geringer Liquidität, wie beispielsweise Lieferverträgen, entstehen Probleme:

时间轴:
10:00:00 - 有人以50000成交了1张合约 → Ticker价格更新为50000
10:00:05 - 盘口挂单:买49800 / 卖50200(但没有成交)
10:00:10 - 盘口挂单:买49850 / 卖50150(但没有成交)
...
10:05:00 - Ticker价格仍然是50000(因为5分钟内没有新的成交)

Ist Ihnen das Problem aufgefallen?Der Kurs von 50.000 war vor 5 Minuten bereits Geschichte.Der aktuelle Marktpreis (Orderbuchpreis) könnte jedoch bei 4985050150 liegen.

Wenn Sie den Tickerpreis von 50.000 verwenden, um Arbitragemöglichkeiten zu berechnen und Limit-Orders zu platzieren, dann gilt Folgendes:

  1. BeurteilungsfehlerArbitragesignale werden auf Basis veralteter Kurse berechnet.
  2. Bestellung fehlgeschlagenDer Preis der Limit-Order liegt zu weit vom tatsächlichen Marktpreis entfernt, sodass die Transaktion nicht abgeschlossen werden kann.
  3. MarktverlustEs wurde eine Marktorder verwendet, um einen Handel zu erzwingen, aber der tatsächliche Preis unterschied sich völlig von dem, was erwartet worden war.

Warum sind Ticker für Lieferverträge besonders unzuverlässig?

Die Liquidität von Lieferverträgen ist deutlich schlechter als die von Spotverträgen:

  • SpotmarktJede Sekunde finden unzählige Transaktionen statt, und die Tickerpreise werden nahezu in Echtzeit mit sehr geringer Verzögerung aktualisiert.
  • LiefervertragEs kann mehrere Minuten oder sogar länger dauern, bis eine Transaktion zustande kommt; der Tickerpreis hinkt deutlich hinterher.

Bei Verträgen mit geringer Liquidität kann die Abweichung zwischen dem Börsenkurs und dem tatsächlichen Orderbuchpreis Folgendes betragen:

  • Normalbereich: 0,1 % - 0,5 %
  • Schwankungsperiode: 1 % – 3 % oder sogar mehr

Für Arbitragestrategien ist diese Abweichung fatal. Der erwartete Preisvorteil mag nur 0,5 % betragen, doch der tatsächliche Transaktionspreis fällt völlig anders aus.

Lösung: Ticker durch Tiefendaten ersetzen

Da Ticker unzuverlässig ist, verwenden wir…Daten zur Orderbuchtiefe

function getDepthMidPrice(exchange, symbol, logDetail = false) {
    let depth = exchange.GetDepth(symbol);
    if (!depth || !depth.Bids || depth.Bids.length === 0 || 
        !depth.Asks || depth.Asks.length === 0) {
        Log(`❌ 获取${symbol}盘口失败`);
        return null;
    }
    
    let bestBid = depth.Bids[0].Price;  // 最优买价
    let bestAsk = depth.Asks[0].Price;  // 最优卖价
    let midPrice = (bestBid + bestAsk) / 2;  // 中间价
    
    if (logDetail) {
        let spread = bestAsk - bestBid;
        let spreadRate = spread / midPrice * 100;
        Log(`📊 ${symbol} 盘口: Bid=${bestBid.toFixed(2)}, Ask=${bestAsk.toFixed(2)}, Mid=${midPrice.toFixed(2)}, Spread=${spread.toFixed(2)} (${spreadRate.toFixed(3)}%)`);
    }
    
    return midPrice;
}

Vorteile von Tiefendaten:

  • EchtzeitSpiegelt den aktuellen tatsächlichen Stand des Orderbuchs ohne Verzögerung wider.
  • GenauigkeitIhre Bestellung wird mit diesen Orderbüchern abgeglichen, und dies ist der tatsächliche Marktpreis.
  • BedienbarkeitLimit-Orders, die auf Basis der Orderbuchpreise berechnet werden, haben eine höhere Wahrscheinlichkeit, ausgeführt zu werden.

Strategie des dualen Preissystems

Letztendlich übernommenHybridlösung aus Ticker und Tiefe

1. Verwenden Sie Ticker, um historische Datensequenzen zu verwalten.

// 用Ticker更新历史价差序列(保持连续性)
let spotTicker = exchanges[0].GetTicker(pair.spotSymbol);
let deliveryTicker = exchanges[1].GetTicker(pair.deliverySymbol);

pair.spotPrice = spotTicker.Last;
pair.deliveryPrice = deliveryTicker.Last;
pair.spread = pair.deliveryPrice - pair.spotPrice;

// 历史序列用于ADF检验、Z-Score计算
priceHistory[pair.deliverySymbol].push({
    time: Date.now(),
    spreadRate: pair.spread / pair.spotPrice,
    spread: pair.spread,
    spotPrice: pair.spotPrice,
    deliveryPrice: pair.deliveryPrice
});

Warum wird Ticker immer noch für historische Daten verwendet? Weil es notwendig ist.DatenkontinuitätWerden historische Daten ebenfalls mithilfe der Tiefenanalyse dargestellt, führen Schwankungen der Orderbuchpreise zu Diskontinuitäten in der historischen Sequenz, was die Genauigkeit der statistischen Analyse beeinträchtigt.

2. Nutzen Sie die Tiefenanalyse für Echtzeit-Beurteilungen und zur Überprüfung der Positionseröffnung.

// 开仓前用Depth重新验证套利机会
let realtimeSpotPrice = getDepthMidPrice(exchanges[0], pair.spotSymbol, true);
let realtimeDeliveryPrice = getDepthMidPrice(exchanges[1], pair.deliverySymbol, true);

// 基于Depth价格重新计算Z-Score
let realtimeSpread = realtimeDeliveryPrice - realtimeSpotPrice;
let realtimeSpreadRate = realtimeSpread / realtimeSpotPrice;
let realtimeZScore = (realtimeSpreadRate - mu) / (sigma || 1e-6);

// 二次验证:套利机会是否仍然存在
if (Math.abs(realtimeZScore) < CONFIG.zScoreEntry) {
    Log('❌ 套利机会已消失(基于Depth实时价格)');
    return false;
}

3. Berechnen Sie den Preis der Limit-Order unter Verwendung der Ordertiefe.

// 基于Depth价格和平均价差计算限价单价格
let spreadDeviation = realtimeSpread - avgSpread;
let adjustmentRatio = Math.min(
    Math.abs(spreadDeviation) * CONFIG.limitOrderSpreadRatio,
    spreadStd * 0.5
);

if (direction === 'positive') {
    spotLimitPrice = realtimeSpotPrice + adjustmentRatio;
    deliveryLimitPrice = realtimeDeliveryPrice - adjustmentRatio;
} else {
    spotLimitPrice = realtimeSpotPrice - adjustmentRatio;
    deliveryLimitPrice = realtimeDeliveryPrice + adjustmentRatio;
}

Der so berechnete Limit-Order-Preis basiert auf dem tatsächlichen Orderbuch, was die Ausführungswahrscheinlichkeit erheblich erhöht.

4. Gewinn und Verlust in Echtzeit unter Verwendung der Tiefe berechnen.

function calculateUnrealizedPnL(record, currentPair) {
    // 优先用Depth价格计算实时盈亏
    let currentSpotPrice = getDepthMidPrice(exchanges[0], currentPair.spotSymbol);
    let currentDeliveryPrice = getDepthMidPrice(exchanges[1], currentPair.deliverySymbol);
    
    // Depth获取失败才回退到Ticker
    if (!currentSpotPrice || !currentDeliveryPrice) {
        currentSpotPrice = currentPair.spotPrice;
        currentDeliveryPrice = currentPair.deliveryPrice;
    }
    
    // 计算盈亏...
}

Vergleich der tatsächlichen Kampfeffekte

Probleme bei der Verwendung von Ticker:

检测到套利信号(基于Ticker)
→ 计算限价单价格
→ 下单等待
→ 长时间不成交(价格已经不对了)
→ 改用市价单
→ 成交价格和预期差很多
→ 套利失败或微利

Verbesserungen nach Anwendung der Tiefenfunktion:

检测到套利信号(基于Ticker历史)
→ 用Depth重新验证(机会仍在)
→ 基于Depth计算限价单价格
→ 下单,价格贴近盘口
→ 较快成交
→ 成交价格符合预期
→ 套利成功

Optimierung der Preisgestaltung für Limit-Orders

Wenn wir Limit-Orders verwenden, wie legen wir den Preis fest? Setzen wir ihn zu hoch an, wird die Transaktion nicht ausgeführt; setzen wir ihn zu niedrig an, erzielen wir keinen guten Preis.

Ausgehend vom Tiefenpreis ist die Vorgehensweise hier folgende:Die Anpassung erfolgt dynamisch auf Basis der Abweichung zwischen der aktuellen Preisspanne und der durchschnittlichen Preisspanne.

let spreadDeviation = realtimeSpread - avgSpread;
let adjustmentRatio = Math.min(
  Math.abs(spreadDeviation) * CONFIG.limitOrderSpreadRatio,
  spreadStd * 0.5
);

// 限制调整幅度在合理区间
let minAdjustment = realtimeSpotPrice * 0.0005;
let maxAdjustment = realtimeSpotPrice * 0.005;
adjustmentRatio = Math.max(minAdjustment, Math.min(maxAdjustment, adjustmentRatio));

Wenn es sich um ein komplettes Set handelt (mit einem großen Preisunterschied):

  • Spot-Kaufpreis = Tiefenmittelpunkt + Anpassungsbereich
  • Verkaufspreis der Futures = Mitte der Kurstiefe - Anpassungsbereich

Dadurch können Transaktionen zu einem günstigen Preisunterschied abgeschlossen werden, ohne dass man zu weit vom Orderbuch entfernt ist und somit eine Transaktion verpasst.

Abkühlungsphase

Jeder fehlgeschlagene Versuch, eine Position zu eröffnen, deutet auf ein Problem im Markt hin, das auf unzureichende Liquidität oder übermäßige Volatilität zurückzuführen sein kann. In solchen Fällen sollte man es nicht sofort erneut versuchen, sondern Ruhe bewahren.

Deshalb wurde für jedes fehlgeschlagene Handelspaar eine Strafe eingeführt.10-minütige Abkühlphase

function addCooldown(deliverySymbol, coin, reason) {
  pairCooldowns[deliverySymbol] = Date.now() + CONFIG.cooldownDuration;
  Log(`⏸️ ${deliverySymbol} 进入10分钟冷却期`);
  Log(`   原因: ${reason}`);
  _G('pairCooldowns', pairCooldowns);
}

Während der Abkühlungsphase werden für dieses Handelspaar keine Positionen eröffnet, um wiederholte Fehlschläge und unnötige Transaktionsgebühren zu vermeiden.

Aktuelle Schwächen und Verbesserungspotenziale

Diese Strategie befindet sich noch in der Entwicklung und es gibt viele Bereiche, die optimiert werden können:

1. Verzögerungsproblem Aktuell werden die Preise per Polling abgerufen, was zu erheblichen Verzögerungen führt. Die Umstellung auf WebSocket für Echtzeit-Preisaktualisierungen würde die Reaktionszeit deutlich verbessern.

2. Optimierung des Risikomanagements Die derzeitige Stop-Loss-Methode ist relativ einfach und unkompliziert, und Sie können Folgendes in Betracht ziehen:

  • Dynamischer Stop-Loss (angepasst an die Volatilität)
  • Zeitbasierter Stop-Loss (Zwangsliquidation aufgrund übermäßiger Haltedauer)
  • Maximale Rückzugskontrolle

3. Slippage-Management Die Preisstrategie für Limit-Orders kann intelligenter gestaltet werden, beispielsweise durch dynamische Anpassung auf Basis von Faktoren wie der Orderbuchtiefe und dem jüngsten Transaktionsvolumen.

4. Weitere Anwendungen von Tiefendaten Es kann das Ungleichgewicht im Orderbuch analysieren, Preistrends vorhersagen und die Erfolgsquote von Arbitragegeschäften verbessern.

Zusammenfassen

Arbitragestrategien klingen verlockend, doch in der Praxis zeigt sich, dass zwischen Ideal und Realität unzählige Fallstricke lauern.

  • Fallstricke beim Stationaritätstest
  • Fallstricke in der Gewinn- und Verlustrechnung
  • Die Falle unzureichender Liquidität
  • Die Fallstricke von Einzeltransaktionen
  • Fallstricke bei Marktorderfehlern
  • Fallstricke bei der Höhe des Spotkaufs
  • Die Falle schwindender Arbitragemöglichkeiten
  • Die Grube der Restpositionen
  • Der gravierendste Fehler ist die Verzögerung im Ticker-Mechanismus.

Insbesondere die Problematik der verzögerten Tickerdaten stellt ein Problem im gesamten Strategieentwicklungsprozess dar.Am leichtesten zu übersehen, aber mit der größten WirkungDie Fallstricke. Für Liefervertragsmärkte mit geringer Liquidität:

Grundprinzip: Ticker nutzen, um die historische Kontinuität zu wahren, und Depth nutzen, um Chancen in Echtzeit zu ergreifen.

  • Ticker eignet sich für die Analyse historischer Daten (ADF-Test, Z-Score-Berechnung).
  • Die Markttiefe eignet sich für Echtzeit-Beurteilungen und Handelsausführung (Überprüfung der Positionseröffnung, Preisgestaltung von Limit-Orders, Gewinn- und Verlustberechnung).

Dieser Artikel dokumentiert die aufgetretenen Probleme und deren Lösungen während des Erkundungsprozesses und soll hoffentlich als Orientierungshilfe für alle dienen.Zur Klarstellung: Dieser Artikel dient ausschließlich Bildungs- und Diskussionszwecken. Der Code befindet sich noch in der Entwicklung und sollte nicht direkt im Live-Handel eingesetzt werden.

Wenn Sie eine ähnliche Strategie verfolgen, sprechen Sie mich gerne darauf an. Der Markt ist komplex, und genau diese Komplexität macht den quantitativen Handel so anspruchsvoll.

Quellcode der Strategie: https://www.fmz.com/strategy/519280