Usar la función KlineChart para hacer más sencillo el diseño de gráficos de estrategias

El autor:Un sueño pequeño., Creado: 2022-07-01 15:54:06, Actualizado: 2023-09-18 20:11:05

img

Usar la función KlineChart para hacer más sencillo el diseño de gráficos de estrategias

La política de diseño a menudo requiere el diseño de gráficos de políticas que muestran que cuando se usa el lenguaje JavaScript, Python para escribir estrategias. Los usuarios que no están familiarizados con la programación o con la biblioteca de gráficos que se utiliza en la plataforma FMZ a menudo tienen dificultades para diseñar el código para dibujar gráficos en gráficos personalizados.

Este modo de dibujar, a la vez simple y potente, se puede ver en el lenguaje Pine, conocido por sus ricas funciones gráficas. Si la interfaz gráfica del lenguaje Pine se puede usar para acceder a las estrategias de JavaScript y Python, es muy conveniente para los desarrolladores diseñar estrategias gráficas.KLineChartCómo hacer gráficos personalizados de las funciones.https://www.fmz.com/api#klinechart

Para empezar, vamos a escribir un ejemplo sencillo de transición en JavaScript.

Un ejemplo simple

/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 30m
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

function main() {
    var c = KLineChart()
    while (true) {
        var bars = _C(exchange.GetRecords)
        for (var i = 0 ; i < bars.length ; i++) {
            var bar = bars[i]
            c.begin(bar)
            c.plot(bar.Volume, "volume")
            c.close()
        }
        Sleep(1000)
    }
}

Este ejemplo es muy simple: simplemente se dibuja un gráfico de K líneas en el área de gráfico de costumbre de la estrategia, y se dibuja una curva de transacción en la posición del subgrupo del gráfico correspondiente a cada K línea BAR.

img

En el código, lo primero que usamos esvar c = KLineChart()Se crea un objeto gráfico que se puede usar para llamar a su método para hacer un gráfico. Luego, en el bucle, obtenemos datos de K líneas (estructura de la matriz), y se puede explorar la matriz de K líneas. Se puede explorar con un simple bucle for en el ejemplo, pero también se puede explorar con otros métodos.

La operación de dibujo se hace desdec.begin(bar)La función comienza.c.close()La función termina.begincloseLas funciones son métodos de objetos de gráfico c. A continuación, se utilizan las funciones de gráfico más comunes.plotDibujar una curva de tráfico en cada BAR.

Un ejemplo un poco más complicado

Si queremos diseñar un gráfico con indicadores de Brin adjuntos. ¡Sí! y también con gráficos de transacciones de cada barra, podemos diseñar así:

/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

function main() {
    var c = KLineChart()

    // 策略主循环
    while(true) {
        // 轮询间隔
        Sleep(500)
        
        // 获取K线数据
        let bars = exchange.GetRecords()
        if (!bars || bars.length <= 20) {
            continue
        }
        
        // 计算布林指标
        var boll = TA.BOLL(bars)
        
        bars.forEach(function(bar, index) {
            c.begin(bar)
            // 画图操作
            c.plot(boll[0][index], "Boll_Up", {overlay: true})     // 画在图表主图
            c.plot(boll[1][index], "Boll_Mid", {overlay: true})    // 画在图表主图
            c.plot(boll[2][index], "Boll_Down", {overlay: true})   // 画在图表主图
            c.plot(bar.Volume, "volume")                           // 画在图表副图
            c.close()
        })
    
        // 策略交易逻辑
        // ...
        // ..
    }
}

Como se puede ver en el código, la información de configuración de retraso que tenemos en la plataforma FMZ es:

/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

Este tipo de configuración es el resultado de una prueba de retrospección de objetos en Binance Exchange, que se muestra a continuación:

img

Como puede ver, utilizamos el modo de dibujo de Pine, que simplifica mucho el código de dibujo en JavaScript.

Escribir gráficos de datos como indicadores

Obtener datos de línea K, calcular indicadores: estas operaciones son comunes y muy sencillas en el paradigma de estrategias de la plataforma Strategy Square y en la documentación de la API.

        // 获取K线数据
        let bars = exchange.GetRecords()
        if (!bars || bars.length <= 20) {   
            // 如果获取K线失败,即!bar为真则执行continue,忽略之后的代码,重新执行循环
            // 如果bars.length小于等于20,即K线BAR(柱)数量小于20,无法计算指标,也执行continue
            continue
        }
        
        // 计算布林指标
        var boll = TA.BOLL(bars)

布林指标计算函数TA.BOLL,如果不指定布林指标参数,就使用默认参数BOLL(20, 2)Los indicadores de Boll tienen tres líneas, por lo que los datos que devuelve la función TA.BOLL son un conjunto bidimensional.

  • boll[0]: Brin está en línea
  • Boll[1]: línea media del cinturón de Boll
  • boll[2]: línea baja de la cinta de Brin

A continuación, vamos a ver cómo dibujar en el gráfico el volumen de datos de la línea K, es decir, la cantidad de transacciones, y los datos del indicador de Brin calculados.

Hemos dibujado los datos de K-línea Bar por Bar, por lo que queremos recorrer toda la matriz de K-línea, es decir, recorrer la matriz de bares en el código.forEachLos métodos pueden ser recorridos, pero también se puede recorrer con el for loop.

        bars.forEach(function(bar, index) {
            c.begin(bar)
            // 画图操作
            c.plot(boll[0][index], "Boll_Up", {overlay: true})     // {overlay: true}参数控制,画在图表主图
            c.plot(boll[1][index], "Boll_Mid", {overlay: true})    // 画在图表主图
            c.plot(boll[2][index], "Boll_Down", {overlay: true})   // 画在图表主图
            c.plot(bar.Volume, "volume")                           // 画在图表副图
            c.close()
        })

Hay que tener en cuenta que cuando se inicia una operación de dibujo de gráficos en una barra, primero se realizac.begin(bar)Las llamadas a funcionesbeginLa función es un método de nuestro objeto gráfico c. Cuando termina la operación de dibujo, se necesita llamarc.close()¿Qué es esto?beginFunción ycloseEntre las funciones está la función de dibujo que llamamos de manera similar al dibujo gráfico del lenguaje Pine.barcolor bgcolor plot fill hline plotarrow plotshape plotchar plotcandle signalLos parámetros de estas funciones coinciden con los parámetros de las funciones correspondientes al lenguaje Pine, y las funciones de gráficos también coinciden.

Añadir gráficos como flechas, marcas, líneas horizontales y señales de transacción

En el ejemplo gráfico de los indicadores de Brin, añadimos algunas flechas, marcas y líneas horizontales de señales de transacción.

/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

function main() {
    var c = KLineChart()

    // 策略主循环
    while(true) {
        // 轮询间隔
        Sleep(500)
        
        // 获取K线数据
        let bars = exchange.GetRecords()
        if (!bars || bars.length <= 20) {
            continue
        }
        
        // 计算布林指标
        var boll = TA.BOLL(bars)
        
        bars.forEach(function(bar, index) {
            c.begin(bar)
            // 画图操作
            c.plot(boll[0][index], "Boll_Up", {overlay: true})     // 画在图表主图
            c.plot(boll[1][index], "Boll_Mid", {overlay: true})    // 画在图表主图
            c.plot(boll[2][index], "Boll_Down", {overlay: true})   // 画在图表主图
            c.plot(bar.Volume, "volume")                           // 画在图表副图
            
            c.hline(bar.Open, {overlay: true})                                         // 水平线
            c.plotarrow(bar.Close - bar.Open, {overlay: true})                         // 箭头
            c.plotshape(bar.Close - bar.Open > 0, {style: 'square', overlay: true})    // 画方块标记
            c.plotchar(bar.Close - bar.Open < 0, {char: '❄', size: "20px", overlay: true})           // 画出字符❄
            if (boll[0][index] && bar.Close > boll[0][index]) {
                c.signal("long", bar.Close, 1.5)
            } else if (boll[2][index] && bar.Close < boll[2][index]) {
                c.signal("closelong", bar.Close, 1.5)
            }
            
            c.close()
        })
    
        // 策略交易逻辑
        // ...
        // ..
    }
}

img

Como las operaciones de comandos estratégicos en el lenguaje Pine marcan automáticamente las señales en el gráfico,KLineChartLos objetos gráficos creados por la función también se extienden a una función para dibujar señales de compra y venta:c.signal

Objetos de configuración de gráficos

Se puede declarar una estructura para configurar el estilo del gráfico, por ejemplo, la variable Cfg de la siguiente gráfica representa la información de configuración de una línea de red.

    var chartCfg = {
        grid: {
            show: true,
            // 网格水平线
            horizontal: {
                show: true,
                size: 2,
                color: '#FF0000',    // 水平网格线的颜色
                // 'solid'|'dash'
                style: 'dash',       // 线的类型
                dashValue: [2, 2]
            },
   	        // 网格垂直线
            vertical: {
                show: true,
                size: 2,
                color: '#32CD32',
                // 'solid'|'dash'
                style: 'solid',
                dashValue: [2, 2]
            }
        },
    }

Los objetos de configuración del gráfico son los que establecen algunas propiedades, diseños, etc. de la estructura de datos del gráfico, como la configuración de un estilo de rejilla utilizada en el ejemplo. También hay muchas opciones que se pueden configurar y modificar, como la configuración del eje X, el eje Y, la configuración de la línea de luz, la configuración de la sugerencia, la configuración del estilo del indicador técnico, la configuración del estilo de la línea K BAR, etc.

Por supuesto, si usted no está familiarizado con esto, usted está haciendo un llamado.KLineChartCuando una función crea un objeto de gráfico, no se puede transmitir el objeto de configuración del gráfico. Entonces, el gráfico creado es el estilo predeterminado.KLineChartLa función crea objetos de gráficos:

var c = KLineChart(chartCfg)

El código de prueba para dibujar una línea de red:

/*backtest
start: 2022-03-21 09:00:00
end: 2022-06-21 15:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/

function main() {
    var chartCfg = {
        grid: {
            show: true,
            // 网格水平线
            horizontal: {
                show: true,
                size: 2,
                color: '#FF0000',
                // 'solid'|'dash'
                style: 'dash',
                dashValue: [2, 2]
            },
   	        // 网格垂直线
            vertical: {
                show: true,
                size: 2,
                color: '#32CD32',
                // 'solid'|'dash'
                style: 'solid',
                dashValue: [2, 2]
            }
        },
    }

    var c = KLineChart(chartCfg)

    // 策略主循环
    while(true) {
        // 轮询间隔
        Sleep(500)
        
        // 获取K线数据
        var bars = _C(exchange.GetRecords)
        bars.forEach(function(bar, index) {
            c.begin(bar)
            c.close()
        })
    
        // 策略交易逻辑
        // ...
        // ..
    }
}

img

Ejemplos de estilos de configuración de gráficos

Se puede utilizar para referirse a la configuración de estilo del gráfico.

{
    // 网格线
    grid: {
        show: true,
        // 网格水平线
        horizontal: {
            show: true,
            size: 1,
            color: '#393939',
            // 'solid'|'dash'
            style: 'dash',
            dashValue: [2, 2]
        },
        // 网格垂直线
        vertical: {
            show: false,
            size: 1,
            color: '#393939',
            // 'solid'|'dash'
            style: 'dash',
            dashValue: [2, 2]
        }
    },
    // 蜡烛图
    candle: {
        // 蜡烛图上下间距,大于1为绝对值,大于0小余1则为比例
        margin: {
            top: 0.2,
            bottom: 0.1
        },
        // 蜡烛图类型 'candle_solid'|'candle_stroke'|'candle_up_stroke'|'candle_down_stroke'|'ohlc'|'area'
        type: 'candle_solid',
        // 蜡烛柱
        bar: {
            upColor: '#26A69A',
            downColor: '#EF5350',
            noChangeColor: '#888888'
        },
        // 面积图
        area: {
            lineSize: 2,
            lineColor: '#2196F3',
            value: 'close',
            backgroundColor: [{
                offset: 0,
                color: 'rgba(33, 150, 243, 0.01)'
            }, {
                offset: 1,
                color: 'rgba(33, 150, 243, 0.2)'
            }]
        },
        priceMark: {
            show: true,
            // 最高价标记
            high: {
                show: true,
                color: '#D9D9D9',
                textMargin: 5,
                textSize: 10,
                textFamily: 'Helvetica Neue',
                textWeight: 'normal'
            },
            // 最低价标记
            low: {
                show: true,
                color: '#D9D9D9',
                textMargin: 5,
                textSize: 10,
                textFamily: 'Helvetica Neue',
                textWeight: 'normal',
            },
            // 最新价标记
            last: {
                show: true,
                upColor: '#26A69A',
                downColor: '#EF5350',
                noChangeColor: '#888888',
                line: {
                    show: true,
                    // 'solid'|'dash'
                    style: 'dash',
                    dashValue: [4, 4],
                    size: 1
                },
                text: {
                    show: true,
                    size: 12,
                    paddingLeft: 2,
                    paddingTop: 2,
                    paddingRight: 2,
                    paddingBottom: 2,
                    color: '#FFFFFF',
                    family: 'Helvetica Neue',
                    weight: 'normal',
                    borderRadius: 2
                }
            }
        },
        // 提示
        tooltip: {
            // 'always' | 'follow_cross' | 'none'
            showRule: 'always',
            // 'standard' | 'rect'
            showType: 'standard',
            labels: ['时间', '开', '收', '高', '低', '成交量'],
            values: null,
            defaultValue: 'n/a',
            rect: {
                paddingLeft: 0,
                paddingRight: 0,
                paddingTop: 0,
                paddingBottom: 6,
                offsetLeft: 8,
                offsetTop: 8,
                offsetRight: 8,
                borderRadius: 4,
                borderSize: 1,
                borderColor: '#3f4254',
                backgroundColor: 'rgba(17, 17, 17, .3)'
            },
            text: {
                size: 12,
                family: 'Helvetica Neue',
                weight: 'normal',
                color: '#D9D9D9',
                marginLeft: 8,
                marginTop: 6,
                marginRight: 8,
                marginBottom: 0
            }
        }
    },
    // 技术指标
    technicalIndicator: {
        margin: {
            top: 0.2,
            bottom: 0.1
        },
        bar: {
            upColor: '#26A69A',
            downColor: '#EF5350',
            noChangeColor: '#888888'
        },
        line: {
            size: 1,
            colors: ['#FF9600', '#9D65C9', '#2196F3', '#E11D74', '#01C5C4']
        },
        circle: {
            upColor: '#26A69A',
            downColor: '#EF5350',
            noChangeColor: '#888888'
        },
        // 最新值标记
        lastValueMark: {
            show: false,
            text: {
                show: false,
                color: '#ffffff',
                size: 12,
                family: 'Helvetica Neue',
                weight: 'normal',
                paddingLeft: 3,
                paddingTop: 2,
                paddingRight: 3,
                paddingBottom: 2,
                borderRadius: 2
            }
        },
        // 提示
        tooltip: {
            // 'always' | 'follow_cross' | 'none'
            showRule: 'always',
            // 'standard' | 'rect'
            showType: 'standard',
            showName: true,
            showParams: true,
            defaultValue: 'n/a',
            text: {
                size: 12,
                family: 'Helvetica Neue',
                weight: 'normal',
                color: '#D9D9D9',
                marginTop: 6,
                marginRight: 8,
                marginBottom: 0,
                marginLeft: 8
            }
        }
    },
    // x轴
    xAxis: {
        show: true,
        height: null,
        // x轴线
        axisLine: {
            show: true,
            color: '#888888',
            size: 1
        },
        // x轴分割文字
        tickText: {
            show: true,
            color: '#D9D9D9',
            family: 'Helvetica Neue',
            weight: 'normal',
            size: 12,
            paddingTop: 3,
            paddingBottom: 6
        },
        // x轴分割线
        tickLine: {
            show: true,
            size: 1,
            length: 3,
            color: '#888888'
        }
    },
    // y轴
    yAxis: {
        show: true,
        width: null,
        // 'left' | 'right'
        position: 'right',
        // 'normal' | 'percentage' | 'log'
        type: 'normal',
        inside: false,
        reverse: false,
        // y轴线
        axisLine: {
            show: true,
            color: '#888888',
            size: 1
        },
        // y轴分割文字
        tickText: {
            show: true,
            color: '#D9D9D9',
            family: 'Helvetica Neue',
            weight: 'normal',
            size: 12,
            paddingLeft: 3,
            paddingRight: 6
        },
        // y轴分割线
        tickLine: {
            show: true,
            size: 1,
            length: 3,
            color: '#888888'
        }
    },
    // 图表之间的分割线
    separator: {
        size: 1,
        color: '#888888',
        fill: true,
        activeBackgroundColor: 'rgba(230, 230, 230, .15)'
    },
    // 十字光标
    crosshair: {
        show: true,
        // 十字光标水平线及文字
        horizontal: {
            show: true,
            line: {
                show: true,
                // 'solid'|'dash'
                style: 'dash',
                dashValue: [4, 2],
                size: 1,
                color: '#888888'
            },
            text: {
                show: true,
                color: '#D9D9D9',
                size: 12,
                family: 'Helvetica Neue',
                weight: 'normal',
                paddingLeft: 2,
                paddingRight: 2,
                paddingTop: 2,
                paddingBottom: 2,
                borderSize: 1,
                borderColor: '#505050',
                borderRadius: 2,
                backgroundColor: '#505050'
            }
        },
        // 十字光标垂直线及文字
        vertical: {
            show: true,
            line: {
                show: true,
                // 'solid'|'dash'
                style: 'dash',
                dashValue: [4, 2],
                size: 1,
                color: '#888888'
            },
            text: {
                show: true,
                color: '#D9D9D9',
                size: 12,
                family: 'Helvetica Neue',
                weight: 'normal',
                paddingLeft: 2,
                paddingRight: 2,
                paddingTop: 2,
                paddingBottom: 2,
                borderSize: 1,
                borderColor: '#505050',
                borderRadius: 2,
                backgroundColor: '#505050'
            }
        }
    },
    // 图形
    shape: {
        point: {
            backgroundColor: '#2196F3',
            borderColor: '#2196F3',
            borderSize: 1,
            radius: 4,
            activeBackgroundColor: '#2196F3',
            activeBorderColor: '#2196F3',
            activeBorderSize: 1,
            activeRadius: 6
        },
        line: {
            // 'solid'|'dash'
            style: 'solid'
            color: '#2196F3',
            size: 1,
            dashValue: [2, 2]
        },
        polygon: {
            // 'stroke'|'fill'
            style: 'stroke',
            stroke: {
                // 'solid'|'dash'
                style: 'solid',
                size: 1,
                color: '#2196F3',
                dashValue: [2, 2]
            },
            fill: {
                color: 'rgba(33, 150, 243, 0.1)'
            }
        },
        arc: {
            // 'stroke'|'fill'
            style: 'stroke',
            stroke: {
                // 'solid'|'dash'
                style: 'solid',
                size: 1,
                color: '#2196F3',
                dashValue: [2, 2]
            },
            fill: {
                color: '#2196F3'
            }
        },
        text: {
            style: 'fill',
            color: '#2196F3',
            size: 12,
            family: 'Helvetica Neue',
            weight: 'normal',
            offset: [0, 0]
        }
    },
    annotation: {
        // 'top' | 'bottom' | 'point'
        position: 'top',
        offset: [20, 0]
        symbol: {
            // 'diamond' | 'circle' | 'rect' | 'triangle' | 'custom' | 'none'
            type: 'diamond',
            size: 8,
            color: '#2196F3',
            activeSize: 10,
            activeColor: '#FF9600'
        }
    },
    tag: {
        // 'top' | 'bottom' | 'point'
        position: 'point',
        offset: 0,
        line: {
            show: true,
            style: LineStyle.DASH,
            dashValue: [4, 2],
            size: 1,
            color: '#2196F3'
        },
        text: {
            color: '#FFFFFF',
            backgroundColor: '#2196F3',
            size: 12,
            family: 'Helvetica Neue',
            weight: 'normal',
            paddingLeft: 2,
            paddingRight: 2,
            paddingTop: 2,
            paddingBottom: 2,
            borderRadius: 2,
            borderSize: 1,
            borderColor: '#2196F3'
        },
        mark: {
            offset: 0,
            color: '#FFFFFF',
            backgroundColor: '#2196F3',
            size: 12,
            family: 'Helvetica Neue',
            weight: 'normal',
            paddingLeft: 2,
            paddingRight: 2,
            paddingTop: 2,
            paddingBottom: 2,
            borderRadius: 2,
            borderSize: 1,
            borderColor: '#2196F3'
        }
    }
}

¿No es eso lo que hace más sencillo el diseño de gráficos estratégicos?


Relacionados

Más.