louisnw01 / lightweight-charts-python

Python framework for TradingView's Lightweight Charts JavaScript library.
MIT License
1.16k stars 214 forks source link

grouping indicator lines #452

Closed esteban2006 closed 1 month ago

esteban2006 commented 1 month ago

Description

https://github.com/user-attachments/assets/6c05fc15-eae5-4045-bb0f-d72d988aaa4c

As you can see in the video i have added super trend indicator being this a one color line a the moment, when most of the time is red and green.

I would like to request a grouping option, when an indicator with 2 or more lines legend gets added to the chart to have the ability of adding a child line

What would it do? / will avoid over flooding the left side panel What problem would it solve? / will allow users to have more control of trading strategies specially for those that are visual traders

Code example

if self.chart:
    line = self.chart.create_line(
        name=line_name,
        color=this_line["color"],
        style=this_line["style"],
        width=this_line["width"],
        price_line=this_line["price_line"],
        price_label=this_line["price_label"],
        childs=(
            (
                id='7', # id should be the line number 
                color=this_line["color"],
                style=this_line["style"],
                width=this_line["width"],
                price_line=this_line["price_line"],
                price_label=this_line["price_label"],
            ),
            (
                id='3', # id should be the line number 
                color=this_line["color"],
                style=this_line["style"],
                width=this_line["width"],
                price_line=this_line["price_line"],
                price_label=this_line["price_label"],
            ),
        )
    )
    line.set(self.new_data[["time", line_name]])

Method of implementation

when adding a legend

esteban2006 commented 1 month ago

@louisnw01, I hope this code gives you an hint on how to add it to your lib

image


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grouped Legend Example</title>
    <style>
        #container {
            position: relative;
            width: 600px;
            height: 400px;
        }
        #legend {
            position: absolute;
            left: 12px;
            top: 12px;
            z-index: 1;
            font-size: 14px;
            font-family: sans-serif;
            line-height: 18px;
            font-weight: 300;
            color: white;
        }
    </style>
</head>
<body>

<div id="container"></div>

<script src="https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js"></script>
<script>
    const chartOptions = {
        layout: {
            textColor: 'white',
            background: { type: 'solid', color: 'black' },
        },
    };
    const chart = LightweightCharts.createChart(document.getElementById('container'), chartOptions);

    chart.applyOptions({
        rightPriceScale: {
            scaleMargins: {
                top: 0.3, // leave some space for the legend
                bottom: 0.25,
            },
        },
        crosshair: {
            horzLine: {
                visible: false,
                labelVisible: false,
            },
        },
        grid: {
            vertLines: {
                visible: false,
            },
            horzLines: {
                visible: false,
            },
        },
    });

    // Add 3 series representing Bollinger Bands
    const bbUpperLine = chart.addLineSeries({
        color: 'blue',
        lineWidth: 2,
    });
    const bbMiddleLine = chart.addLineSeries({
        color: 'orange',
        lineWidth: 1,
    });
    const bbLowerLine = chart.addLineSeries({
        color: 'blue',
        lineWidth: 2,
    });

    // Dummy data for Bollinger Bands
    const data = [
        { time: '2022-01-01', upper: 100, middle: 95, lower: 90 },
        { time: '2022-01-02', upper: 102, middle: 97, lower: 92 },
        { time: '2022-01-03', upper: 104, middle: 99, lower: 94 },
        // Add more data points here
    ];

    bbUpperLine.setData(data.map(item => ({ time: item.time, value: item.upper })));
    bbMiddleLine.setData(data.map(item => ({ time: item.time, value: item.middle })));
    bbLowerLine.setData(data.map(item => ({ time: item.time, value: item.lower })));

    const symbolName = 'BBBand_21';

    const container = document.getElementById('container');

    // Create the custom legend (Single row with legend and prices combined)
    const legend = document.createElement('div');
    legend.id = 'legend';
    container.appendChild(legend);

    // Set initial legend text
    legend.innerHTML = `${symbolName}: U: - M: - L: -`;

    // Update the legend on crosshair move
    chart.subscribeCrosshairMove((param) => {
        if (!param || !param.time || !param.seriesData) {
            legend.innerHTML = `${symbolName}: U: - M: - L: -`;
            return;
        }

        const bbUpper = param.seriesData.get(bbUpperLine);
        const bbMiddle = param.seriesData.get(bbMiddleLine);
        const bbLower = param.seriesData.get(bbLowerLine);

        if (bbUpper && bbMiddle && bbLower) {
            legend.innerHTML = `${symbolName}: U: ${bbUpper.value.toFixed(2)} M: ${bbMiddle.value.toFixed(2)} L: ${bbLower.value.toFixed(2)}`;
        }
    });

    chart.timeScale().fitContent();
</script>

</body>
</html>
louisnw01 commented 1 month ago

dupe