Si vous ne savez pas écrire une stratégie dans un langage aussi facile à apprendre et à utiliser...

Auteur:Je ne sais pas., Créé: 2023-02-16 14:55:00, Mis à jour: 2023-09-18 20:18:52

img

Si vous ne savez pas écrire une stratégie dans un langage aussi facile à apprendre et à utiliser...

Le nombre de stratégies open source sur TradingView est grand. Il est dommage que tant d'excellentes stratégies, idées et indicateurs ne puissent pas être utilisés dans un vrai bot. Voyant cela, FMZ, qui s'engage à populariser la technologie de trading quantitative auprès de nombreux traders, ne peut naturellement pas supprimer cette envie de résoudre le problème!

Ce partage d'expérience est absolument à offrir!

Ainsi, après avoir parcouru le monde de la programmation et du développement de code, traversé 9*9=81 fosses, survécu à d'innombrables nuits blanches, et empilé une montagne de canettes vides de Red Bull dans un coin.

En ce qui concerne le langage Pine, je ne me suis appris que récemment. Mais pour être honnête, le langage Pine pour le trading quantitatif est vraiment facile à utiliser et facile à apprendre. Laissez-moi vous écrire une stratégie de grille:

/*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 est un vrai bot, des outils de backtesting et de nombreuses fonctions combinées à la simplicité du langage Pine sont un excellent ajout!

Bien sûr, cette stratégie est une stratégie de grille, qui a aussi des défauts, et ce n'est pas une machine d'impression d'argent qui gagne toujours. La clé dépend de l'utilisation et des paramètres. Nous allons nous concentrer davantage sur la façon d'écrire des stratégies facilement pour mettre en œuvre notre propre logique de trading, et gagner de l'argent en écrivant des stratégies et en négociant nous-mêmes. C'est tellement cool de ne pas demander de l'aide!

Explication du code

Je vais vous expliquer à tous, le code est simple et facile à comprendre, avec un tel langage facile à apprendre et à utiliser Pine, si vous ne pouvez toujours pas écrire une stratégie, alors je vais... vous dire en détail!

Le contenu de/*backtestet*/au début est le code de configuration de backtest de FMZ. C'est la fonction de FMZ, pas le contenu du langage Pine. Bien sûr, vous pouvez laisser cette partie de côté, et vous cliquerez sur le contrôle de paramètre manuellement pour définir la configuration de backtest et les paramètres pendant le backtesting.

/*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]]
*/

Le code suivant:

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): Il est utilisé pour définir certaines options du script, overlay=true, qui est d'attribuer une valeur vraie au paramètreoverlay, de sorte que lors du dessin du graphique, il est dessiné sur le graphique principal (K-ligne graphique est le graphique principal, il peut être compris si simplement).
  • varip beginPrice = 0: Une variable beginPrice est déclarée avec le mot clé varip avec une valeur initiale de 0, qui est utilisée comme prix initial pour la grille.
  • var spacing = input.float(-1, title="Spacing prices"): Définir un paramètre de stratégie, le nom du paramètre est prix d'espacement, qui est l'espacement de chaque point de la grille, définir 100 signifie que le prix sera négocié une fois tous les 100.
  • var dir = input.string("long", title="Directions", options = ["long", "short", "both"]): Configurez un paramètre de stratégie nommé direction, ce paramètre est une fenêtre déroulante avec des options longues, courtes et les deux, ce qui signifie que la grille est respectivement longue seulement, courte seulement et les deux.
  • var amount = input.float(-1, title="Order quantity"): définir un paramètre pour contrôler le volume des transactions à chaque transaction de point de réseau.
  • var numbers = input.int(-1, title="Number of grids"): le nombre de points de grille, en réglant 20 est de 20 points de grille dans un sens.
  • var profit = input.int(-1, title="Profit spreads") / syminfo.mintick: Définir un paramètre permettant de contrôler la marge bénéficiaire de chaque position de point de grille avant de fermer la position.

Ensuite, regardez le code:

if spacing == -1 and amount == -1 and numbers == -1 and profit == -1
    runtime.error("Parameter errors")

Cela signifie que si des paramètres tels que l'espacement, le montant, les chiffres et le profit ne sont pas définis, le défaut est -1, et la stratégie s'arrêtera (vous ne pouvez pas opérer à l'aveugle sans définir des paramètres)

Allez, allez!

if not barstate.ishistory and beginPrice == 0 
    beginPrice := close 

Ce que cela signifie ici, c'est que lorsque la stratégie est à l'étape de la ligne K en temps réel et commencePrice == 0, changez la valeur de commencePrice au dernier prix actuel. On peut comprendre que lorsque la stratégie est officiellement en cours d'exécution, le prix actuel initial est le prix initial de la grille. Parce que le script a une étape BAR historique de la ligne K, la stratégie exécutera la logique une fois à l'étape BAR historique, et il est définitivement inutile d'organiser la grille sur la BAR historique.

Quelle est l'étape historique du BAR?

Pour donner un exemple simple, au moment actuel A, la stratégie commence à s'exécuter, et la stratégie obtient des données avec 100 K-line BARs. Au fil du temps, 100 BARs deviendront 101, 102...N. Quand elle commence à fonctionner à partir du moment A, la 101e BAR est l'étape de la ligne K en temps réel, et cette fois, ce sont les dernières données en temps réel. Ensuite, de la 1ère BAR à la 100e BAR, ce sont les prix historiques du marché qui sont passés, mais la stratégie fonctionnera également sur ces prix historiques du marché, donc cette étape est l'étape historique de la ligne K.

barstate.ishistoryc'est une variable intégrée dans le langage Pine,barstate.ishistoryest vrai si le BAR actuel est un BAR historique, et faux si ce n'est pas un BAR historique.

Ensuite, une fonction est créée

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 

Le rôle de cette fonction est de savoir si un certain id existe dans tous les ordres qui ont actuellement ouvert une position. S'il y a un appel à la fonction findTradeId, il renverra l'ID de l'ordre existant (notez que cet ID n'est pas l'ID d'ordre de l'échange, c'est le nom donné à l'ordre par la stratégie ou compris comme une étiquette), s'il n'existe pas, la chaîne notFound est renvoyée.

L'étape suivante consiste à démarrer la feuille de grille:

// 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)

La boucle for est utilisée, et le nombre de boucles est déterminé en fonction de la valeur du paramètre des nombres, c'est-à-dire le nombre correspondant d'ordres sont disposés. Définir la direction en fonction du paramètre dir. Utilisez la fonction findTradeId pour savoir si l'ordre de l'étiquette à la position de la grille actuelle a été ouvert, et ne placez l'ordre prévu si il n'y a pas de position ouverte (si la position est ouverte, il ne peut pas être répété). Pour placer un ordre, utiliser la fonction strategy.order pour spécifier le paramètre limite comme un ordre prévu. Placer l'ordre de fermeture correspondant tout en plaçant l'ordre prévu. L'ordre de fermeture utilise lestrategy.exitfonction, spécifie le paramètre de profit, et spécifie les points de profit.

img

img

En regardant la courbe de profit, on voit que le réseau est aussi risqué. Ce n'est pas une victoire garantie. C'est juste que le risque d'expansion du réseau à grande échelle est un peu plus faible.

Si vous ne savez pas écrire une stratégie dans un langage aussi facile à apprendre et à utiliser, alors...


Relationnée

Plus de