tradingview / charting-library-tutorial

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

Issue about positionLine #102

Open samartsevigor opened 6 months ago

samartsevigor commented 6 months 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 6 months ago

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

samartsevigor commented 6 months 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 6 months ago

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

samartsevigor commented 5 months ago

The community is not active at all (