louisnw01 / lightweight-charts-python

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

Day Seperators / Session Breaks feature #84

Closed kasoob closed 1 year ago

kasoob commented 1 year ago

Hello,

A new feature that I think would be wonderful is an optional parameter for all chart classes, where we can toggle and customize session breaks. This would be used to draw dashed lines on charts at the end and beginning of each trading day. Perhaps we should also implement an option to set a different color for session break lines at the end of each week. See the example below:

image

This feature is available by default in TradingView's chart settings as session breaks:

image

louisnw01 commented 1 year ago

Hey @kasoob,

Cool idea!

I think a more general method would be more flexible, something like:

chart.vertical_span(start_date, end_date, color)

Where you can omit the end_date to just get a single line going up.

There is a way to do this in Lightweight Charts; i'll look into it.

Louis

kasoob commented 1 year ago

That would be used to draw a single vertical line at the end_date right?

Perhaps we could develop it further to implement an interval, or maybe it would be even more accurate to set a time parameter that would draw the line at every occurrence of that time on the chart.

Additionally, a day parameter would also be useful, where we could for example set a different color vertical line to appear at that time and particular day (such as Monday) at its every occurrence on the chart. That would overwrite any existing lines at that time if it was previously created.

This would allow for further styling of day separators when it comes to new week and new day lines. The default value of the day parameter would be None and the time parameter is required. Both time and day parameters can handle a string value or a list of strings.

If I was to construct session break lines suited for NYSE or NASDAQ stock market exchanges, I would call:

chart.session_breaks(time='9:30') # blue dashed line at the start of a new day

Followed by:

chart.session_breaks(time='9:30', day='Monday', color='#FFA500') # orange dashed line at the start of a new week

Below is my simplified implementation, which by default has no day parameter and has a blue color line and a dashed line style:

from datetime import datetime
from typing import Union, List
import calendar

print(list(calendar.day_name) + list(calendar.day_abbr))
chart_datetime_objs = []

def session_breaks(time: Union[str, List[str]], day: Union[str, List[str]] =None, color: str ='#0000FF', style: str ='dashed'):
    # can raise ValueError if time is not in %H:%M format or is invalid.
    # can raise ValueError if day is not in %A or %a format or is invalid. i.e. weekday or abbreviation of weekday
    if day:
        if day not in list(calendar.day_name) + list(calendar.day_abbr):
            raise ValueError(f'{day} is not a valid day name or abbreviation.') 
    time_format = '%H:%M'
    time_str = datetime.strptime(time, time_format).time().strftime(time_format)

    for datetime_obj in [datetime.now()]:
        if not day:
            if datetime_obj.strftime(time_format) == time_str:
                    print(f'plotting line at {time_str}')
                    #plot line
                    continue

        else:
            if datetime_obj.strftime('%A') == day or datetime_obj.strftime('%a') == day:
                if datetime_obj.strftime(time_format) == time_str:
                    print(f'plotting line at {time_str}, {day}')
                    #plot line
                    continue
kasoob commented 1 year ago

Also I think it may be worth noting that these lines would be to the left of the relevant candlestick, not running down the middle of it - that's the way it is in TradingView, but I'm not exactly sure how it's plotted on lightweight charts.

image
louisnw01 commented 1 year ago

Hey @kasoob,

So I think i'll leave the 'session break' side of things to the user for now, with the library only providing the method to create the vertical lines.

Due to limitations within Lightweight Charts, it won't be possible to have the line directly to the left of the candle, as the library doesn't actually provide any way to draw vertical lines; they will essentially be a volume series layered on top of the chart, which spans the entire height of the chart. Probably best to use a rgba color for visibility.

louisnw01 commented 1 year ago

Session break lines would also need to account for different timezones; if UTC timestamps are given, then the opening time would depend on DST.

louisnw01 commented 1 year ago

Implemented the vertical_span method in the latest version.

Louis

kasoob commented 1 year ago

Hello Louis, thank you for implementing this.

How about supporting a list of time objects as well?

That would be much more flexible as it would allow for efficiently drawing all necessary lines instead of limiting it to a start and end time.

louisnw01 commented 1 year ago

Hey @kasoob,

This would be much more efficient; I'll change start_date to allow a list/tuple of dates.

Louis

algotrader-au commented 1 year ago

Hi Louis, I'm seeing the vertical span lines persist between charts, despite calling a verticalSpan.delete(). Are they removable?

louisnw01 commented 1 year ago

Hi Louis, I'm seeing the vertical span lines persist between charts, despite calling a verticalSpan.delete(). Are they removable?

This is a bug; will fix in the latest version. Louis

louisnw01 commented 1 year ago

@algotrader-au @kasoob All fixed/implemented in the latest version.

Louis