Si no sabes cómo escribir una estrategia en un lenguaje Pine tan fácil de aprender y usar...

El autor:- ¿ Por qué?, Creado: 2023-02-16 14:55:00, Actualizado: 2023-09-18 20:18:52

img

Si no sabes cómo escribir una estrategia en un lenguaje Pine tan fácil de aprender y usar...

El número de estrategias de código abierto en TradingView es grande. Es una lástima que tantas estrategias, ideas e indicadores excelentes no puedan usarse en un bot real. Viendo esto, FMZ, que se compromete a popularizar la tecnología de comercio cuantitativo para muchos comerciantes, naturalmente no puede suprimir este impulso para resolver el problema!

¡Este intercambio de experiencias es absolutamente recomendable!

Así que, después de caminar por el mundo de la programación y el desarrollo de código, pasando por 9*9=81 hoyos, sobreviviendo a innumerables noches de insomnio, y acumulando una montaña de latas vacías de Red Bull en la esquina.

Cuando se trata del lenguaje Pine, sólo recientemente me he enseñado a mí mismo. Pero para ser honesto, el lenguaje Pine para el comercio cuantitativo es realmente fácil de usar y fácil de aprender. ¿Qué? ¿No crees? Déjame escribir una estrategia de la red para ti:

/*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 es un bot real, herramientas de backtesting y numerosas funciones combinadas con la simplicidad del lenguaje Pine son una gran adición! Incluyendo el ajuste de parámetros y el código de configuración de backtesting, el código total es de menos de 50 líneas.

Por supuesto, esta estrategia es una estrategia de cuadrícula, que también tiene defectos, y no es una máquina de impresión de dinero que siempre gana. La clave depende del uso y los parámetros. Nos centraremos más en cómo escribir estrategias fácilmente para implementar nuestra propia lógica de negociación, y ganar dinero escribiendo estrategias y negociando nosotros mismos. ¡Es tan genial no pedir ayuda!

Explicación del código

Les explicaré a todos, el código es simple y fácil de entender, con un lenguaje de Pine tan fácil de aprender y usar, si aún no pueden escribir una estrategia, entonces yo... les diré en detalle!

El contenido incluido en/*backtesty*/al principio está el código de configuración de backtest de FMZ. Esta es la función de FMZ, no el contenido del lenguaje Pine. Por supuesto, puede omitir esta parte, y usted va a hacer clic en el control de parámetros manualmente para establecer la configuración de backtest y parámetros durante 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]]
*/

El siguiente código:

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): Se utiliza para establecer algunas opciones del script, superposición=verdadero, que es asignar un valor verdadero al parámetrooverlay, de modo que al dibujar el gráfico, se dibuja en el gráfico principal (K-línea gráfico es el gráfico principal, se puede entender tan simplemente).
  • varip beginPrice = 0: Una variable beginPrice se declara con la palabra clave varip con un valor inicial de 0, que se utiliza como precio inicial para la cuadrícula.
  • var spacing = input.float(-1, title="Spacing prices"): Establecer un parámetro de estrategia, el nombre del parámetro es precio de espaciamiento, que es el espaciamiento de cada punto de la cuadrícula, la configuración de 100 significa que el precio se comercializa una vez cada 100.
  • var dir = input.string("long", title="Directions", options = ["long", "short", "both"]): Configure un parámetro de estrategia llamado direction, este parámetro es un cuadro desplegable con opciones largo, corto y ambos, lo que significa que la cuadrícula es larga solo, corta solo y ambos, respectivamente.
  • var amount = input.float(-1, title="Order quantity"): Establecer un parámetro para controlar el volumen de operaciones en cada operación de punto de red.
  • var numbers = input.int(-1, title="Number of grids"): el número de puntos de la red, fijando 20 es 20 puntos de la red en una dirección.
  • var profit = input.int(-1, title="Profit spreads") / syminfo.mintick: Establecer un parámetro para controlar el margen de ganancia de cada posición de punto de la red antes de cerrar la posición.

A continuación, mira el código:

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

Significa que si no se establecen parámetros como espaciado, cantidad, números y ganancias, el valor predeterminado es -1, y la estrategia se detendrá (no se puede operar ciegamente sin establecer parámetros)

¡ Vamos, ahora!

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

Lo que esto significa aquí es que cuando la estrategia está en la etapa de la línea K en tiempo real y startPrice == 0, cambiar el valor de startPrice al último precio actual. Se puede entender que cuando la estrategia está funcionando oficialmente, el precio actual inicial es el precio inicial de la cuadrícula. Debido a que el guión tiene una etapa histórica BAR de la línea K, la estrategia ejecutará la lógica una vez en la etapa BAR histórica, y definitivamente no tiene sentido organizar la cuadrícula en la BAR histórica.

¿Cuál es la etapa histórica de BAR?

Para dar un ejemplo simple, en el momento actual A, la estrategia comienza a ejecutarse, y la estrategia obtiene datos con 100 K-line BARs. Con el tiempo, 100 BARs se convertirán en 101, 102...N. Cuando comienza a ejecutarse desde el momento A, la 101a BAR es la etapa de la línea K en tiempo real, y este tiempo es el último dato en tiempo real. Luego desde la 1a BAR hasta la 100a BAR, estos son los precios históricos del mercado que han pasado, pero la estrategia también se ejecutará en estos precios históricos del mercado, por lo que esta etapa es la etapa histórica de la línea K.

barstate.ishistoryesta es una variable incorporada en el lenguaje Pine,barstate.ishistoryes verdadero si el BAR actual es un BAR histórico, y falso si no es un BAR histórico.

A continuación, se crea una función

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 

Si hay una llamada a la función findTradeId, devolverá el ID del pedido existente (tenga en cuenta que este ID no es el ID del pedido del intercambio, es el nombre dado al pedido por la estrategia o entendido como una etiqueta), si no existe, se devuelve la cadena notFound.

El siguiente paso es iniciar la hoja de la red:

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

Se utiliza el bucle for, y el número de bucles se determina de acuerdo con el valor del parámetro de números, es decir, el número correspondiente de órdenes se organizan. Establezca la dirección de acuerdo con el parámetro dir. Utilice la función findTradeId para averiguar si el orden de la etiqueta en la posición de la cuadrícula actual se ha abierto, y solo coloque el orden planificado si no hay posición abierta (si la posición está abierta, no se puede repetir). Para colocar una orden, use la función strategy.order para especificar el parámetro límite como una orden planificada. Coloque la orden de cierre correspondiente mientras coloca la orden planificada. La orden de cierre utiliza elstrategy.exitFunción, especifica el parámetro de ganancia y especifica los puntos de ganancia.

img

img

Mirando la curva de ganancias, podemos ver que la red también es arriesgada. No es una ganancia garantizada. Es sólo que el riesgo de expandir la red a gran escala es un poco menor.

Bueno, si no sabes cómo escribir una estrategia en un lenguaje Pine tan fácil de aprender y usar, entonces yo...


Relacionados

Más.