Adaptive intelligente Netzhandelsstrategie

Schriftsteller:ChaoZhang, Datum: 2024-01-16 14:51:48
Tags:

img

Übersicht

Diese Strategie ist eine anpassungsfähige intelligente Gitterhandelsstrategie, die auf der TradingView-Plattform basiert und in Pine Script v4 geschrieben wurde.

Strategie Logik

Wesentliche Merkmale

  1. Pyramiden und Geldmanagement:

    • Ermöglicht bis zu 14 Ergänzungen in derselben Richtung (Pyramiden),
    • Verwendet eine bargeldbasierte Strategie zur Verwaltung von Positionsgrößen,
    • Das Anfangskapital wird für Simulationszwecke auf 100 USD festgesetzt.
    • Für jeden Handel wird eine kleine Provision von 0,1% erhoben.
  2. Grid-Grenzen:

    • Benutzer können automatisch berechnete Grenzen verwenden oder manuell die oberen und unteren Grenzen des Rasters festlegen,
    • Die automatischen Grenzen können entweder aus dem jüngsten High & Low des Preises oder aus einem einfachen gleitenden Durchschnitt (SMA) abgeleitet werden.
    • Die Benutzer können den Rückblickzeitraum für die Grenzberechnung definieren und die Abweichung so anpassen, dass die Grenzen erweitert oder eingeschränkt werden.
  3. Netzlinien:

    • Die Strategie erlaubt eine anpassbare Anzahl von Netzlinien innerhalb der Grenzen mit einem empfohlenen Bereich zwischen 3 und 15.
    • Die Rasterlinien sind gleichmäßig zwischen den oberen und unteren Grenzen verteilt.

Strategie Logik

  • Eintrag:

    • Das Skript platziert Bestellungen, wenn der Preis unter eine Gitterlinie fällt und keine bestehende Bestellung mit dieser Gitterlinie verknüpft ist.
    • Jede Bestellmenge wird auf der Grundlage des Anfangskapitals geteilt durch die Anzahl der Stromnetzlinien berechnet, die an den aktuellen Preis angepasst wurde.
  • Ausgang:

    • Verkaufsaufträge werden ausgelöst, wenn der Preis über eine Gitterlinie steigt, vorausgesetzt, dass eine offene Order für die nächste untere Gitterlinie vorliegt.
  • Adaptives Gitter:

    • Wenn auf automatische Grenzen gesetzt, passt sich das Netz an die sich ändernden Marktbedingungen an, indem es die oberen und unteren Grenzen neu berechnet und das Netz entsprechend anpasst.

Analyse der Vorteile

Die Strategie integriert den systematischen Charakter und die effiziente Ausführung des Grid-Handels. Pyramiden ermöglicht und Geldmanagement kann Risiken effektiv kontrollieren. Das automatisch anpassende Grid passt zu verschiedenen Marktbedingungen. Die anpassbaren Parameter entsprechen verschiedenen Handelsstilen.

Risikoanalyse

Ein Preisbruch über die Netzgrenzen hinaus kann zu schweren Verlusten führen. Die Parameter sollten angemessen angepasst oder mit einem Stop-Loss kombiniert werden, um Risiken zu kontrollieren. Auch erhöht übermäßiger Handel die Transaktionskosten.

Optimierungsrichtlinien

Ein Stop-Loss kann auch dazu beitragen, Risiken durch extreme Marktbewegungen zu vermeiden.

Schlussfolgerung

Diese Strategie erzeugt systematisch Ein- und Ausgänge beim Verwalten von Positionen. Durch Parameter-Tuning passt sie sich verschiedenen Präferenzen an. Sie verbindet die regelbasierte Natur des Grid-Tradings mit der Flexibilität des Trend-Tradings, wodurch die Komplexität des Betriebs erleichtert und gleichzeitig die Robustheit beibehalten wird.


/*backtest
start: 2024-01-08 00:00:00
end: 2024-01-15 00:00:00
period: 5m
basePeriod: 1m
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