Usar a função KlineChart para simplificar o desenho de gráficos de estratégias

Autora:Sonhos pequenos, Criado: 2022-07-01 15:54:06, Atualizado: 2023-09-18 20:11:05

img

Usar a função KlineChart para simplificar o desenho de gráficos de estratégias

Quando se usa a linguagem JavaScript, Python, etc. Os usuários que não estão familiarizados com programação ou com a biblioteca de gráficos usada pela plataforma FMZ geralmente têm dificuldade em desenhar um gráfico de código em um gráfico personalizado. Então, como você pode desenhar um gráfico de estratégia rico com apenas um pouco de código?

A linguagem Pine é conhecida por ter uma grande variedade de gráficos. A linguagem Pine é conhecida por ter uma linguagem de gráficos muito simples e poderosa. Se a interface de gráficos da linguagem Pine puder ser usada para acessar as estratégias de JavaScript e Python, isso facilitará muito as estratégias de design de gráficos dos desenvolvedores.KLineChartComo a função faz gráficos personalizados. Veja a documentação da API:https://www.fmz.com/api#klinechart

Vamos começar por escrever um exemplo simples de transição usando o JavaScript.

Exemplo simples

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

O exemplo é muito simples, basta desenhar um gráfico de linha K na região do gráfico personalizado da estratégia e desenhar uma curva de transação correspondente a cada linha K BAR na posição do gráfico.

img

O primeiro que usamos no código.var c = KLineChart()Criar um objeto de gráfico que pode ser usado para chamar seu método para fazer um gráfico. Em seguida, no ciclo, obtemos dados de linha K (estrutura de arquivos) e percorrem a matriz de linha K. Pode ser feito, como no exemplo, com o simples ciclo for, ou pode ser feito de outras maneiras.

A função de desenho deve serc.begin(bar)A função começa.c.close()A função terminou.begincloseFunções são métodos para objetos de gráfico c. A seguir, usamos as funções gráficas mais comuns.plotDesenhe uma curva de tráfego em cada BAR.

Exemplo um pouco mais complicado

Se quisermos desenhar um gráfico com indicadores de Brin. Sim! e desenhar um gráfico de transações para cada barra, podemos desenhar assim:

/*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 você pode ver no código, a configuração de informações que nós usamos na plataforma FMZ é:

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

A configuração é a de um teste de retrospecção de objetos do Binance Exchange, que tem o seguinte efeito:

img

Como você pode ver, nós usamos o modo de desenho do Pine para simplificar muito o código de desenho no JavaScript.

Escrever gráficos de dados como indicadores

Obter dados da linha K, calcular indicadores, estas operações são comuns e muito simples nos padrões de estratégia da plataforma Strategy Square e na documentação da 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)O indicador de Boll tem três linhas, então o dado que a função TA.BOLL retorna é um conjunto bidimensional. boll[0],boll[1] eboll[2] são os três elementos do conjunto de Boll, que representam uma linha, um conjunto.

  • boll[0]: Brin Band está online
  • boll[1]: linha do meio da faixa de Boll
  • boll[2]: Linha de baixo da faixa Brin

Então vamos ver como transformar o volume dos dados da linha K em quantidade de transações e os dados do indicador de Brin calculados em gráficos.

Nós estamos desenhando dados de K-linhas Bar por Bar, então vamos percorrer toda a matriz de K-linhas, ou seja, percorrer a matriz de bars no código.forEachO método pode ser recorrido ou recorrido usando o loop for.

        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()
        })

É importante notar que, quando você começa a traçar um gráfico em uma barra, você deve fazer o seguinte:c.begin(bar)A função é chamadabeginA função é um método para nossos objetos de gráfico c. Quando a operação de desenho termina, é necessário chamarc.close()Não.beginFunções ecloseEntre as funções estão as funções de gráficos que chamamos de forma semelhante ao modo de desenho do linguagem Pine.barcolor bgcolor plot fill hline plotarrow plotshape plotchar plotcandle signal, pode desenhar linhas, desenhar setas, marcar informações, etc. Os parâmetros dessas funções são consistentes com os parâmetros das funções correspondentes à linguagem Pine, e as funções de gráficos também são consistentes.

Adicionar gráficos, como setas, marcadores, linhas horizontais e sinais de negociação

No exemplo gráfico do indicador de Brin acima, adicionamos algumas setas, marcas e linhas horizontais de sinais de negociação.

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

Uma vez que a linguagem Pine tem uma estratégia para marcar sinais automaticamente em gráficos, é possível que o código seja usado para fazer uma lista de sinais.KLineChartOs objetos gráficos criados pela função também estendem uma função usada para desenhar sinais de compra e venda:c.signal

Objetos de configuração de gráficos

Pode-se declarar uma estrutura para configurar o estilo do gráfico, como a variável chartCfg abaixo, que representa a informação de configuração de uma linha de grelha.

    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]
            }
        },
    }

Os objetos de configuração de gráficos são os que definem algumas propriedades, aparências e outras estruturas de dados do gráfico, como a configuração de um estilo de grelha usada no exemplo. Há muitas opções que podem ser configuradas e modificadas, como configurações do eixo X, eixo Y, configurações de linhas de luz, configurações de sugestões, configurações de estilo de indicadores técnicos, configurações de estilo de K-line BAR, etc.

Claro que se você não está familiarizado com isso, você está chamandoKLineChartQuando uma função cria objetos de gráfico, não pode passar para objetos de configuração de gráfico. Então, o gráfico criado é o padrão padrão. Utiliza funções API da plataforma FMZ.KLineChartA função cria objetos gráficos:

var c = KLineChart(chartCfg)

Desenhe o código de teste para a rede:

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

Exemplos de estilos de configuração de gráficos

Pode ser usado para referenciar configurações de estilo de 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'
        }
    }
}

O que é que isso quer dizer para o gráfico estratégico ser mais simples?


Relacionados

Mais.