Use a função KLineChart para facilitar o desenho de estratégias

Autora:Sonhos pequenos, Criado: 2022-07-05 15:13:55, Atualizado: 2023-09-25 19:49:32

img

Use a função KLineChart para facilitar o desenho de estratégias

Ao projetar uma estratégia, muitas vezes é necessário projetar um gráfico de estratégia para exibir, ao escrever estratégias na linguagem JavaScript, linguagem Python, usuários que não estão familiarizados com programação ou a biblioteca de gráficos usada na plataforma FMZ muitas vezes lutam com o design de código para desenhar em gráficos personalizados.

Esta maneira simples e poderosa de desenhar pode ser vista na linguagem Pine, que é conhecida por suas ricas funções de desenho. Se a interface de desenho da linguagem Pine puder ser conectada às estratégias das linguagens JavaScript e Python, isso facilitará muito a função de desenho da estratégia de design do desenvolvedor.KLineChartPode consultar a documentação da API em:https://www.fmz.com/api#klinechart

Vamos começar por escrever um exemplo simples usando a linguagem JavaScript para transição.

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, "Close")
            c.close()
        }
        Sleep(1000)
    }
}

Este exemplo é muito simples, basta desenhar um gráfico de linha K na área de desenho personalizada da estratégia e desenhar uma curva de volume correspondente a cada BAR de linha K na posição de sub-gráfico do gráfico.

img

No código, usamosvar c = KLineChart()Para criar um objeto de gráfico primeiro, e depois usar seu método para desenhar um gráfico. Em seguida, no loop, obtemos os dados de linha K (estrutura de matriz), e atravessamos a matriz de linha K. Pode ser atravessado usando um loop simples como no exemplo, ou pode ser atravessado de outras maneiras.

A operação de desenho começa com oc.begin(bar)função e termina com oc.close()Abegineclosefunções são todos os métodos do objeto gráfico c. Em seguida, use a função de desenho mais comumente usadaplotdesenhar a curva de volume em cada BAR.

Um exemplo mais complexo

Suponhamos que queremos projetar um gráfico com o indicador de Bollinger ligado e também vem com um gráfico de volume de cada BAR, que pode ser projetado 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()

    // main strategy loop
    while(true) {
        // polling interval
        Sleep(500)
        
        // get K-line data
        let bars = exchange.GetRecords()
        if (!bars || bars.length <= 20) {
            continue
        }
        
        // calculate the Bollinger indicator
        var boll = TA.BOLL(bars)
        
        bars.forEach(function(bar, index) {
            c.begin(bar)
            // drawing operation
            c.plot(boll[0][index], "Boll_Up", {overlay: true})     // Draw on the main chart
            c.plot(boll[1][index], "Boll_Mid", {overlay: true})    // Draw on the main chart
            c.plot(boll[2][index], "Boll_Down", {overlay: true})   // Draw on the main chart
            c.plot(bar.Volume, "volume")                           // Draw on the sub-chart
            c.close()
        })
    
        // Strategy trading logic
        // ...
        // ..
    }
}

Como podemos ver no código, nossa informação de configuração backtest 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"}]
*/

Tal configuração é usar o teste de backtesting do objeto de câmbio Binance.

img

Pode-se ver que usamos o método de desenho Pines, que simplifica muito o código de desenho na linguagem JavaScript.

Escrever indicadores e outros dados para desenhar gráficos

As operações de obtenção de dados de linha K e de cálculo de indicadores são comuns e simples nos exemplos de estratégia do Quadrado de Estratégia da Plataforma e na documentação da API.

        // obtain K-line data
        let bars = exchange.GetRecords()
        if (!bars || bars.length <= 20) {   
            // If the acquisition of the K line fails, that is, if !bar is true, execute continue, ignore the following code, and re-execute the loop
            // If bars.length is less than or equal to 20, that is, the number of K-line BAR (bar) is less than 20, the indicator cannot be calculated, and continue is also executed
            continue
        }
        
        // Calculate the Bollinger indicator
        var boll = TA.BOLL(bars)

A função de cálculo do indicador de Bollinger TA.BOLL, se os parâmetros do indicador de Bollinger não forem especificados, os parâmetros por defeitoBOLL(20, 2)O indicador de Bollinger tem três linhas, então os dados retornados pela função TA.BOLL são uma matriz bidimensional. boll[0], boll[1], e boll[2] são os três elementos da matriz boll, cada um dos quais representa uma linha e é uma matriz.

  • Bollinger Bands em linha ascendente
  • boll[1]: Bollinger Bands linha média
  • boll[2]: Bollinger Bands linha descendente

Então vamos ver como desenhar o volume dos dados da linha K, ou seja, o volume, e os dados calculados do indicador de Bollinger no gráfico.

Nós desenhamos os dados K-line Bar por Bar, então precisamos atravessar toda a matriz K-line, ou seja, atravessar a matriz de barras no código.forEachmétodo é usado aqui para atravessar, ou o loop for pode ser usado para atravessar.

        bars.forEach(function(bar, index) {
            c.begin(bar)
            // Drawing operations
            c.plot(boll[0][index], "Boll_Up", {overlay: true})     // {overlay: true} Parameter control, drawn on the main chart
            c.plot(boll[1][index], "Boll_Mid", {overlay: true})    // Draw on the main chart
            c.plot(boll[2][index], "Boll_Down", {overlay: true})   // Draw on the main chart
            c.plot(bar.Volume, "volume")                           // Draw on the sub-chart
            c.close()
        })

Deve notar-se que sempre que iniciar uma operação de desenho de gráficos em uma barra, deve fazer umac.begin(bar)A função chamada primeiro.beginFunção é um de nosso objeto gráfico c método.c.close()Entre obeginFunção eclosefunção é a função de desenho que chamamos semelhante ao método de desenho da linguagem Pine.barcolor bgcolor plot fill hline plotarrow plotshape plotchar plotcandle signal, você pode desenhar linhas, setas, informações de marcação, etc. Os parâmetros dessas funções são os mesmos que os parâmetros de função correspondentes à linguagem Pine, e as funções de desenho também são as mesmas.

Adicionar o desenho de setas de sinal de negociação, marcadores, linhas horizontais, etc.

Adicione algumas setas de sinal de negociação, marcadores, linhas horizontais para o exemplo de gráfico Bollinger Bands acima.

/*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({overlay : true})

    // Strategy main loop
    while(true) {
        // Polling interval
        Sleep(500)
        
        // Obtain K-line data
        let bars = exchange.GetRecords()
        if (!bars || bars.length <= 20) {
            continue
        }
        
        // Calculate Bollinger indicator
        var boll = TA.BOLL(bars)
        
        bars.forEach(function(bar, index) {
            c.begin(bar)
            // Drawing operations
            c.plot(boll[0][index], "Boll_Up", {overlay: true})     // Draw on the main chart
            c.plot(boll[1][index], "Boll_Mid", {overlay: true})    // Draw on the main chart
            c.plot(boll[2][index], "Boll_Down", {overlay: true})   // Draw on the main chart
            c.plot(bar.Volume, "volume", {overlay: false})         // Draw on the sub-chart
            
            c.hline(bar.Open, {overlay: true})                          // Horizontal line
            c.plotarrow(bar.Close - bar.Open, {overlay: true})          // Arrow
            c.plotshape(bar.Close - bar.Open > 0, {style: 'square'})    // Draw square markers
            c.plotchar(bar.Close - bar.Open < 0, {char: 'X'})           // Draw the character X
            
            c.close()
        })
    
        // Strategy trading logic
        // ...
        // ..
    }
}

img

Objeto de configuração do gráfico

Uma estrutura pode ser declarada para configurar o estilo do gráfico. Por exemplo, a seguinte variável chartCfg representa as informações de configuração de uma linha de grade.

    var chartCfg = {
        grid: {
            show: true,
            // Grid horizontal line
            horizontal: {
                show: true,
                size: 2,
                color: '#FF0000',    // Color of horizontal grid line
                // 'solid'|'dash'
                style: 'dash',       // Type of line
                dashValue: [2, 2]
            },
   	        // Grid vertical line
            vertical: {
                show: true,
                size: 2,
                color: '#32CD32',
                // 'solid'|'dash'
                style: 'solid',
                dashValue: [2, 2]
            }
        },
    }

O objeto de configuração do gráfico é a estrutura de dados que define algumas propriedades e aparência do gráfico. Por exemplo, uma configuração de estilo de linha de grade é usada no exemplo. Há também muitas opções que podem ser configuradas e modificadas, como configurações de eixo X, configurações relacionadas ao eixo Y, configurações de linha do cursor, configurações de mensagem de alerta, configurações de estilo de indicador técnico, configurações de estilo BAR de linha K, etc.

Claro, se você não está familiarizado com estes, você não pode passar no objeto de configuração gráfico ao chamar oKLineChartA função para criar um objeto gráfico. Então o gráfico criado é o estilo padrão. Use a função APIKLineChartFunção da plataforma FMZ para criar um objeto de gráfico:

var c = KLineChart(chartCfg)

Código de ensaio para desenho de linhas de grelha:

/*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,
            // Grid horizontal line
            horizontal: {
                show: true,
                size: 2,
                color: '#FF0000',
                // 'solid'|'dash'
                style: 'dash',
                dashValue: [2, 2]
            },
   	        // Grid vertical line
            vertical: {
                show: true,
                size: 2,
                color: '#32CD32',
                // 'solid'|'dash'
                style: 'solid',
                dashValue: [2, 2]
            }
        },
    }

    var c = KLineChart(chartCfg)

    // Strategy main loop
    while(true) {
        // Polling interval
        Sleep(500)
        
        // Obtain K-line data
        var bars = _C(exchange.GetRecords)
        bars.forEach(function(bar, index) {
            c.begin(bar)
            c.close()
        })
    
        // Strategy trading logic
        // ...
        // ..
    }
}

img

Exemplo de estilo de configuração do gráfico

Pode ser usado para se referir às configurações de estilo do gráfico.

{
    // Gridlines
    grid: {
        show: true,
        // Grid horizontal line
        horizontal: {
            show: true,
            size: 1,
            color: '#393939',
            // 'solid'|'dash'
            style: 'dash',
            dashValue: [2, 2]
        },
        // Grid vertical line
        vertical: {
            show: false,
            size: 1,
            color: '#393939',
            // 'solid'|'dash'
            style: 'dash',
            dashValue: [2, 2]
        }
    },
    // Candlestick chart
    candle: {
        // The distance between the top and bottom of the candlestick chart, greater than 1 is the absolute value, greater than 0, and 1 is the proportion
        margin: {
            top: 0.2,
            bottom: 0.1
        },
        // Type of Candlestick Charts 'candle_solid'|'candle_stroke'|'candle_up_stroke'|'candle_down_stroke'|'ohlc'|'area'
        type: 'candle_solid',
        // Candle pillar
        bar: {
            upColor: '#26A69A',
            downColor: '#EF5350',
            noChangeColor: '#888888'
        },
        // Area map
        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,
            // Highest price marker
            high: {
                show: true,
                color: '#D9D9D9',
                textMargin: 5,
                textSize: 10,
                textFamily: 'Helvetica Neue',
                textWeight: 'normal'
            },
            // Lowest price marker
            low: {
                show: true,
                color: '#D9D9D9',
                textMargin: 5,
                textSize: 10,
                textFamily: 'Helvetica Neue',
                textWeight: 'normal',
            },
            // Latest price marker
            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
                }
            }
        },
        // Tips
        tooltip: {
            // 'always' | 'follow_cross' | 'none'
            showRule: 'always',
            // 'standard' | 'rect'
            showType: 'standard',
            labels: ['time', 'open', 'close', 'high', 'low', 'volume'],
            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
            }
        }
    },
    // Technical indicators
    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'
        },
        // Latest value marker
        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
            }
        },
        // Tips
        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-axis
    xAxis: {
        show: true,
        height: null,
        // x-axis line
        axisLine: {
            show: true,
            color: '#888888',
            size: 1
        },
        // x-axis split text
        tickText: {
            show: true,
            color: '#D9D9D9',
            family: 'Helvetica Neue',
            weight: 'normal',
            size: 12,
            paddingTop: 3,
            paddingBottom: 6
        },
        // x-axis split line
        tickLine: {
            show: true,
            size: 1,
            length: 3,
            color: '#888888'
        }
    },
    // y-axis
    yAxis: {
        show: true,
        width: null,
        // 'left' | 'right'
        position: 'right',
        // 'normal' | 'percentage' | 'log'
        type: 'normal',
        inside: false,
        reverse: false,
        // y-axis line
        axisLine: {
            show: true,
            color: '#888888',
            size: 1
        },
        // y-axis split text
        tickText: {
            show: true,
            color: '#D9D9D9',
            family: 'Helvetica Neue',
            weight: 'normal',
            size: 12,
            paddingLeft: 3,
            paddingRight: 6
        },
        // y-axis split line
        tickLine: {
            show: true,
            size: 1,
            length: 3,
            color: '#888888'
        }
    },
    // Split line between charts
    separator: {
        size: 1,
        color: '#888888',
        fill: true,
        activeBackgroundColor: 'rgba(230, 230, 230, .15)'
    },
    // Crosshair
    crosshair: {
        show: true,
        // Horizontal line and text of crosshair
        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 line and text of crosshair
        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'
            }
        }
    },
    // Graph
    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'
        }
    }
}

Isto não facilita o desenho de estratégias?


Relacionados

Mais.