tradingview / charting-library-tutorial

This tutorial explains step by step how to connect your data to the Charting Library
MIT License
434 stars 317 forks source link

Issue about positionLine #102

Open samartsevigor opened 1 year ago

samartsevigor commented 1 year ago
import './index.scss';

import { filterData } from '@utils';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import binanceAPI from '../../services/binance-api/api';
import { options } from './options';

const TradingViewChart = () => {
  const dispatch = useDispatch();
  const { positions } = useSelector(state => state.orders);
  const { isLoadingUser } = useSelector(state => state.auth);

  const [lastTestRun, setLastTestRun] = useState(0);
  const tradingViewRef = useRef(null);

  const lines = useRef();
  lines.current = new Map();

  const twOptions = useMemo(
    () => ({
      datafeed: new binanceAPI({
        debug: false,
        ecpId: 'binance',
        ecpName: 'Binance',
        market: 'spot',
      }),
      symbol: 'BTC',
      custom_css_url: '/css/tw-style.css',
      interval: '15',
      ...options,
    }),
    [],
  );

  useEffect(() => {
    if (!isLoadingUser && !tradingViewRef.current) {
      tradingViewRef.current = window.tvWidget = new window.TradingView.widget(
        twOptions,
      );
    }
  }, [dispatch, isLoadingUser, twOptions]);

  const test = () => {
    const now = Date.now();
    if (now - lastTestRun >= 5000) {
      setLastTestRun(now);

      tradingViewRef?.current?.onChartReady(() => {
        lines.current.forEach((_value, key) => {
          lines.current.get(key).remove();
          lines.current.delete(key);
        });

        positions?.forEach((position, idx) => {
          const line = tradingViewRef.current
            ?.chart()
            .createPositionLine()
            .setText(`PROFIT: ${position.pnl || '-'}`)
            .setTooltip('Additional position information')
            .setProtectTooltip('Protect position')
            .setCloseTooltip('Close position')
            .setReverseTooltip('Reverse position!')
            .setQuantity(position.ep)
            .setPrice(position.ep)
            .setLineColor('#28B550')
            .setBodyBackgroundColor('#28B550')
            .setBodyBorderColor('#28B550')
            .setQuantityBackgroundColor('#28B550')
            .setQuantityBorderColor('#28B550')
            .setBodyTextColor('#fff')
            .setLineStyle(3);
          lines.current.set(idx, line);
        });
      });
    }
  };

  useEffect(() => {
    const intervalId = setInterval(test, 5000);
    return () => {
      clearInterval(intervalId);
    };
  }, []);

  return (
    <div className="tw-wrapper">
      <div id="chart_container" />
    </div>
  );
};

export default TradingViewChart;

There is almost no information on the internet how to update lines with positions, maybe we should add an example to the documentation? This is a very capricious point.

I seem to be doing everything right, but why my lines are not deleted? The reference to the object does not change. But my behavior is that new lines are created but previous lines are not deleted. How to fix it and what is the reason? Maybe someone has an example of implementation?

My test function is called every 5 seconds and should clear the lines and draw again, but it doesn't ((

If I do it like this, the line removal works. I don't see anything on the screen. But why doesn't it work through Map? The reference to the object remains the same


positions?.forEach((position, idx) => {
          const line = tradingViewRef.current
            ?.chart()
            .createPositionLine()
            .setText(`PROFIT: ${position.pnl || '-'}`)
            .setTooltip('Additional position information')
            .setProtectTooltip('Protect position')
            .setCloseTooltip('Close position')
            .setReverseTooltip('Reverse position!')
            .setQuantity(position.ep)
            .setPrice(position.ep)
            .setLineColor('#28B550')
            .setBodyBackgroundColor('#28B550')
            .setBodyBorderColor('#28B550')
            .setQuantityBackgroundColor('#28B550')
            .setQuantityBorderColor('#28B550')
            .setBodyTextColor('#fff')
            .setLineStyle(3);

          // HERE
          line.remove()

        });
romfrancois commented 1 year ago

Is there a way you could provide a min reproducible example online (you can follow this doc) ?

samartsevigor commented 1 year ago

@romfrancois

https://glitch.com/edit/#!/delightful-orange-domain https://delightful-orange-domain.glitch.me

I prepared a demo version and reproduced the error. I would like to see best practices for React, Angular, Vue, for updating orders and positions on the chart in the documentation. Would appreciate help with my problem. As you can see, the positions are duplicated instead of removing the previous lines and showing the new ones. As far as I understand, we can't just update, we need to delete the old ones and draw new ones.

samartsevigor commented 1 year ago

Probably my implementation is too complex and everything can be done much simpler

samartsevigor commented 12 months ago

The community is not active at all (