Selbstanpassungsfähige Quantengitter-Handelsstrategie

Schriftsteller:ChaoZhang, Datum: 2024-02-02 18:08:22
Tags:

img

Übersicht

Diese Strategie stellt ein dynamisches Handelsnetz her, um in volatilen Märkten stetige Gewinne zu erzielen. Sie berechnet automatisch den Abstand zwischen dem Netz und die obere/untere Grenze basierend auf der vorgegebenen Anzahl von Netzlinien. Wenn der Preis durch jede Netzlinie bricht, werden lange/kurze Positionen in Chargen aufgebaut. Gewinne werden erzielt, wenn der Preis die ursprünglichen Netzlinien wieder erreicht. Die Strategie unterstützt sowohl die manuelle als auch die automatische Anpassung der Netzparameter, um sich an sich ändernde Marktbedingungen anzupassen.

Strategie Logik

  1. Berechnung der Netzgrenzen und der Netzliniepreis-Array auf der Grundlage von Eingabeparametern.

  2. Wenn der Preis ohne entsprechende Aufträge unter eine Gitterlinie fällt, werden Long-Orders zum Gitterliniepreis platziert. Wenn der Preis mit bestehender Position über die vorherige Gitterlinie (die erste ausgeschlossen) steigt, werden die Long-Orders der vorherigen Linie geschlossen.

  3. Wenn die automatische Anpassung aktiviert ist, werden die oberen/unten Grenzwerte, der Abstand zwischen den Netzen und die Netz-Arrays regelmäßig auf der Grundlage der aktuellen Kerzen-Daten neu berechnet.

Analyse der Vorteile

  1. Lange/kurze Positionen werden in Chargen auf verschiedenen Preisniveaus aufgebaut und geschlossen, um einen Gesamtgewinn zu erzielen.

  2. Unterstützung sowohl der manuellen als auch der automatischen Parameteranpassung. Die manuelle Anpassung bietet eine bessere Steuerung, erfordert jedoch Eingriffe. Die automatische Anpassung reduziert die Arbeitsbelastung und passt sich an die sich verändernden Marktdynamiken an.

  3. Wenn der Preis alle Netzlinien überschreitet, sind die Risiken begrenzt.

  4. Die Grid-Abstandsbereinigung wird angepasst, um den Gewinn/Verlust pro Handel anzupassen.

Risikoanalyse

  1. Das Risiko, in der Schlagbahn gefangen zu sein, kann zu Verlusten führen, wenn die Preise häufig im Netzbereich schwanken.

  2. Es bedarf eines ausreichenden Anfangskapitals, denn eine unzureichende Finanzierung kann nicht ausreichend Netzlinien unterstützen.

  3. Extreme Grid-Zahlen beeinträchtigen die Gewinne. Zu wenige Grids können die Volatilität nicht voll ausnutzen, während zu viele Grids zu minimalen Gewinnen pro Handel führen. Umfangreiche Tests sind erforderlich, um optimale Einstellungen zu bestimmen.

  4. Die automatische Anpassung besteht aus Risiken der Preismanipulation, die sich auf kürzliche Kerzenlehnen stützen, die durch kurzfristige Kursoperationen beeinflusst werden können.

Optimierung

  1. Einführung einer Stop-Loss-Logik wie z.B. der Trailing-Stop-Loss, um das Abwärtsrisiko pro Richtung weiter zu begrenzen.

  2. Optimieren Sie Netzparameter durch maschinelles Lernen. Testen Sie verschiedene Parameter unter Marktbedingungen und trainieren Sie ML-Modelle, um optimale, anpassungsfähige Parameter zu erhalten.

  3. Beurteilen Sie die aktuelle Trendstärke mit Indikatoren wie MACD und RSI, um die Grid Quantity und Parameter-Tuning zu steuern.

  4. Verstärkung der Risikokontrolle durch Festlegung des maximal zulässigen Abzugsprozentsatzes.

Schlussfolgerung

Diese Strategie nutzt die Eigenschaften von volatilen Märkten voll aus und erzielt durch dynamisches Netz-Trading-Framework, das sowohl Parameterflexibilität als auch einfache Bedienung bietet, stetige Gewinne.


/*backtest
start: 2024-01-02 00:00:00
end: 2024-02-01 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds    = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool)                             // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc      = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"])     // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev      = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1)  // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound    = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float)                      // for manual grid bounds only. The upperbound price of your grid
i_lowerBound    = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float)                      // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty       = input(group="Grid Lines",  title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer)       // how many grid lines are in your grid

f_getGridBounds(_bs, _bl, _bd, _up) =>
    if _bs == "Hi & Low"
        _up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl)  * (1 - _bd)
    else
        avg = sma(close, _bl)
        _up ? avg * (1 + _bd) : avg * (1 - _bd)

f_buildGrid(_lb, _gw, _gq) =>
    gridArr = array.new_float(0)
    for i=0 to _gq-1
        array.push(gridArr, _lb+(_gw*i))
    gridArr

f_getNearGridLines(_gridArr, _price) =>
    arr = array.new_int(3)
    for i = 0 to array.size(_gridArr)-1
        if array.get(_gridArr, i) > _price
            array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
            array.set(arr, 1, i == 0 ? i : i-1)
            break
    arr

var upperBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound  // upperbound of our grid
var lowerBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth       = (upperBound - lowerBound)/(i_gridQty-1)                                                       // space between lines in our grid
var gridLineArr     = f_buildGrid(lowerBound, gridWidth, i_gridQty)                                                 // an array of prices that correspond to our grid lines
var orderArr        = array.new_bool(i_gridQty, false)                                                              // a boolean array that indicates if there is an open order corresponding to each grid line

var closeLineArr    = f_getNearGridLines(gridLineArr, close)                                                        // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
strategy.initial_capital = 50000
for i = 0 to (array.size(gridLineArr) - 1)
    if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
        buyId = i
        array.set(orderArr, buyId, true)
        strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
    if close > array.get(gridLineArr, i) and i != 0
        if array.get(orderArr, i-1)
            sellId = i-1
            array.set(orderArr, sellId, false)
            strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))

if i_autoBounds
    upperBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
    lowerBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
    gridWidth   := (upperBound - lowerBound)/(i_gridQty-1)
    gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)

closeLineArr    := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)



Mehr