Es ist schade, dass so viele ausgezeichnete Strategien, Ideen und Indikatoren nicht in einem echten Bot verwendet werden können. Das sieht FMZ, das sich der Popularisierung quantitativer Handelstechnologie für viele Trader verschrieben hat, natürlich nicht in der Lage ist, diesen Drang zu unterdrücken, das Problem zu lösen!
Dieser Erfahrungsaustausch ist absolut zu bieten!
Nachdem wir also durch die Welt der Programmierung und Entwicklung von Code gereist sind, durch 9*9=81 Gruben gegangen sind, unzählige schlaflose Nächte überlebt haben und einen Berg leerer Red Bull-Dosen in der Ecke angehäuft haben, unterstützt und ist FMZ schließlich mit der Pine-Sprache kompatibel und alle Arten von Pine-Skripten von TradingView können verwendet werden.
Wenn es um die Pine-Sprache geht, habe ich mich erst vor kurzem selbst gelernt. Aber um ehrlich zu sein, ist die Pine-Sprache für den quantitativen Handel wirklich einfach zu benutzen und leicht zu lernen. Lassen Sie mich Ihnen eine Netzstrategie schreiben:
/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/
strategy(overlay=true)
varip beginPrice = 0
var spacing = input.float(-1, title="Spacing prices")
var dir = input.string("long", title="Directions", options = ["long", "short", "both"])
var amount = input.float(-1, title="Order quantity")
var numbers = input.int(-1, title="Number of grids")
var profit = input.int(-1, title="Profit spreads") / syminfo.mintick
if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
runtime.error("Parameter errors")
if not barstate.ishistory and beginPrice == 0
beginPrice := close
findTradeId(id) =>
ret = "notFound"
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == id
ret := strategy.opentrades.entry_id(i)
ret
// Real-time K-line stage
if not barstate.ishistory
// Retrieve grid
for i = 1 to numbers
// Going long
direction = dir == "both" ? "long" : dir
plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
strategy.order(direction+str.tostring(i), strategy.long, qty=amount, limit=beginPrice-i*spacing)
strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
// Going short
direction := dir == "both" ? "short" : dir
plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
FMZ
Natürlich ist diese Strategie eine Gitterstrategie, die auch Mängel hat, und es ist keine Gelddruckmaschine, die immer gewinnt. Der Schlüssel hängt von der Verwendung und den Parametern ab. Wir werden uns mehr darauf konzentrieren, wie man Strategien einfach schreibt, um unsere eigene Handelslogik umzusetzen und Geld zu verdienen, indem wir Strategien schreiben und selbst handeln. Es ist so cool, keine Hilfe zu bitten!
Ich erkläre euch allen, der Code ist einfach und leicht zu verstehen, mit einer so einfachen zu lernen und zu verwenden Pine Sprache, wenn Sie immer noch nicht eine Strategie schreiben können, dann werde ich... erzählen Sie im Detail!
Der Inhalt der/*backtest
und*/
zu Beginn ist der Backtest-Konfigurationscode von FMZ. Dies ist die Funktion von FMZ, nicht der Inhalt der Pine-Sprache. Natürlich können Sie diesen Teil weglassen, und Sie klicken manuell auf die Parametersteuerung, um die Backtest-Konfiguration und Parameter während des Backtestings festzulegen.
/*backtest
start: 2021-06-01 00:00:00
end: 2022-05-23 00:00:00
period: 1h
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
args: [["v_input_float_1",500],["v_input_string_1",2],["v_input_float_2",0.01],["v_input_int_1",20],["v_input_int_2",500],["RunMode",1,358374],["MinStock",0.001,358374]]
*/
Der nächste Code:
strategy(overlay=true)
varip beginPrice = 0
var spacing = input.float(-1, title="Spacing prices")
var dir = input.string("long", title="Directions", options = ["long", "short", "both"])
var amount = input.float(-1, title="Order quantity")
var numbers = input.int(-1, title="Number of grids")
var profit = input.int(-1, title="Profit points") / syminfo.mintick
strategy(overlay=true)
: Es wird verwendet, um einige Optionen des Skripts, Overlay=true, festzulegen, um dem Parameter einen wahren Wert zuzuweisenoverlay
, so dass beim Zeichnen des Diagramms, es auf dem Hauptdiagramm gezeichnet wird (K-Liniendiagramm ist das Hauptdiagramm, es kann so einfach verstanden werden).varip beginPrice = 0
: Eine Variable startPrice wird mit dem Schlüsselwort varip mit einem Anfangswert von 0 deklariert, der als Anfangspreis für das Raster verwendet wird.var spacing = input.float(-1, title="Spacing prices")
: Setzen Sie einen Strategieparameter, der Parametername ist var dir = input.string("long", title="Directions", options = ["long", "short", "both"])
: Setzen Sie einen Strategieparameter namens var amount = input.float(-1, title="Order quantity")
: Festlegen eines Parameters zur Steuerung des Handelsvolumens bei jedem Grid-Point-Handel.var numbers = input.int(-1, title="Number of grids")
: Die Anzahl der Gitterpunkte bei Einstellung 20 beträgt 20 Gitterpunkte in eine Richtung.var profit = input.int(-1, title="Profit spreads") / syminfo.mintick
: Stellen Sie vor dem Schließen der Position einen Parameter fest, mit dem die Gewinnspanne jeder Position in einem Gitterpunkt kontrolliert wird.Als Nächstes, schauen Sie sich den Code an:
if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
runtime.error("Parameter errors")
Es bedeutet, dass, wenn keine Parameter wie Abstand, Betrag, Zahlen und Gewinn festgelegt werden, ist der Standard -1, und die Strategie wird gestoppt (Sie können nicht blind arbeiten, ohne Parameter zu setzen)
Geht weiter!
if not barstate.ishistory and beginPrice == 0
beginPrice := close
Dies bedeutet, dass, wenn die Strategie in der Echtzeit-K-Linie-Stufe ist und startPrice == 0, den Wert von startPrice auf den aktuellen letzten Preis ändern. Es kann verstanden werden, dass, wenn die Strategie offiziell ausgeführt wird, der anfängliche aktuelle Preis der anfängliche Preis des Gritts ist. Da das Skript eine historische K-Line BAR-Stufe hat, wird die Strategie die Logik einmal in der historischen BAR-Stufe ausführen, und es ist definitiv sinnlos, das Grit auf dem historischen BAR zu arrangieren.
Was ist die historische BAR-Bühne?
Um ein einfaches Beispiel zu nennen, beginnt die Strategie im aktuellen Moment A zu laufen, und die Strategie erhält Daten mit 100 K-Line BARs. Im Laufe der Zeit werden 100 BARs zu 101, 102...N. Wenn sie ab dem Moment A laufen beginnt, ist die 101. BAR die Echtzeit-K-Line-Stufe, und diese Zeit ist die neueste Echtzeit-Daten. Dann von der 1. BAR bis zur 100. BAR sind dies die vergangenen historischen Marktpreise, aber die Strategie wird auch an diesen historischen Marktpreisen laufen, also ist diese Stufe die historische K-Line-Stufe.
barstate.ishistory
Dies ist eine eingebaute Variable in der Pine-Sprache,barstate.ishistory
ist wahr, wenn die aktuelle BAR eine historische BAR ist, und falsch, wenn sie keine historische BAR ist.
Als nächstes wird eine Funktion erstellt
findTradeId(id) =>
ret = "notFound"
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == id
ret := strategy.opentrades.entry_id(i)
ret
Wenn eine Funktion findTradeId aufgerufen wird, gibt sie die ID der vorhandenen Order zurück (beachten Sie, dass diese ID nicht die Order-ID der Börse ist, sondern der Name, der der Order durch die Strategie gegeben wurde oder als Etikett verstanden wird).
Der nächste Schritt besteht darin, das Rasterblatt zu starten:
// Real-time K-line stage
if not barstate.ishistory
// Retrieve grid
for i = 1 to numbers
// Going long
direction = dir == "both" ? "long" : dir
plot(beginPrice-i*spacing, direction+str.tostring(i), color.green)
if direction == "long" and beginPrice-i*spacing > 0 and beginPrice-i*spacing < close and findTradeId(direction+str.tostring(i)) == "notFound"
strategy.order(direction+str.tostring(i), strategy.long, qty=amount, limit=beginPrice-i*spacing)
strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
// Going short
direction := dir == "both" ? "short" : dir
plot(beginPrice+i*spacing, direction+str.tostring(i), color.red)
if direction == "short" and beginPrice+i*spacing > close and findTradeId(direction+str.tostring(i)) == "notFound"
strategy.order(direction+str.tostring(i), strategy.short, qty=amount, limit=beginPrice+i*spacing)
strategy.exit("exit-"+direction+str.tostring(i), direction+str.tostring(i), qty_percent=100, profit=profit)
Die For-Schleife wird verwendet, und die Anzahl der Schleifen wird nach dem Wert des Zahlenparameters bestimmt, d.h. die entsprechende Anzahl von Aufträgen wird angeordnet. Setzen Sie die Richtung nach dem Dir-Parameter. Verwenden Sie die Funktion findTradeId, um herauszufinden, ob die Bestellung des Labels an der aktuellen Gitterposition geöffnet wurde, und platzieren Sie die geplante Bestellung nur, wenn keine offene Position besteht (wenn die Position geöffnet ist, kann sie nicht wiederholt werden). Um eine Bestellung zu platzieren, verwenden Sie die Strategie.order-Funktion, um den Limitparameter als geplante Bestellung anzugeben. Platzieren Sie die entsprechende Schließbestellung, während Sie die geplante Bestellung platzieren. Die Schließbestellung verwendet diestrategy.exitFunktion, gibt den Gewinnparameter an und gibt die Gewinnpunkte an.
Wenn wir uns die Gewinnkurve anschauen, können wir sehen, dass das Netz auch riskant ist. Es ist kein garantierter Gewinn. Es ist nur, dass das Risiko, das Netz in großem Maßstab zu erweitern, etwas geringer ist.
Nun, wenn du nicht weißt, wie man eine Strategie in einer so leicht zu lernenden und benutzerfreundlichen Pine-Sprache schreibt, dann...