highfestiva/finplot

Plotting Multiple Candlestick charts on different pane

guanm326 opened this issue · 7 comments

Not sure where to ask questions. I have 2 dataframes with separate indices (intraday OHLC and daily OHLC), how do I get the second pane to plot the daily OHLC aligned correct to the first panes intraday OHLC?

thanks

Good one, I did think about it but never got around to fixing that. I'll have something in a couple of weeks. In the mean while you can disconnect the two axes by severing the x-link: ax2.setXLink(None).

c0f7c1e fixes that. Perfect alignment might sometimes be difficult to achieve, as different months, days and time zones play a role in stock markets (that close).

Note that you should remove all margins in order to get perfect alignment.

import finplot as fplt
import yfinance as yf

df = yf.download('ETH-USD', '2020-07-10', '2020-09-02', interval='90m') # market that doesn't close

# no margins
fplt.right_margin_candles = 0
fplt.side_margin = 0
ax1,ax2 = fplt.create_plot(rows=2)

# first plot shows 90m candles
fplt.candlestick_ochl(df[['Open','Close','High','Low']], ax=ax1)

# second plot shows daily
dfd = df.Open.resample('D').first().to_frame()
dfd['Close'] = df.Close.resample('D').last()
dfd['High'] = df.High.resample('D').max()
dfd['Low'] = df.Low.resample('D').min()
fplt.candlestick_ochl(dfd.dropna(), ax=ax2)

fplt.show()

One other options I should mention, which I kinda like myself is plotting them both on the same axis, like so:

image

It's easy to do: just download, resample and plot the background first, in this case five 90-minute per business day. We offset the base candle, since resample puts it at start of day by default. Plot the high-res version on top. Done.

#!/usr/bin/env python3

import finplot as fplt
import yfinance as yf

df = yf.download('GOOG', '2020-07-10', '2020-09-03', interval='90m')

dfd = df.Open.resample('D').first().to_frame()
dfd['Close'] = df.Close.resample('D').last()
dfd['High'] = df.High.resample('D').max()
dfd['Low'] = df.Low.resample('D').min()

daily_plot = fplt.candlestick_ochl(dfd.dropna(), candle_width=5)
daily_plot.colors.update(dict(bull_body='#bfb', bull_shadow='#ada', bear_body='#fbc', bear_shadow='#dab'))
daily_plot.x_offset = 3.1 # resample() gets us start of day

fplt.candlestick_ochl(df[['Open','Close','High','Low']])

fplt.show()

Hello somehow I didn't get any notification of you reply, apologies. I tried your first solution but I am getting back green candles without any wicks at all on my dataset....


                        Open     High      Low    Close    Volume   OpenUS   HighUS    LowUS  CloseUS   VolumeUS
Datetime                                                                                                        
2020-09-18 13:45:00  3301.50  3304.75  3297.00  3298.75   28211.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 14:00:00  3298.75  3306.50  3298.00  3306.25   35531.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 14:15:00  3306.25  3311.75  3305.00  3307.50   38635.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 14:30:00  3307.75  3313.75  3304.25  3313.50   36680.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 14:45:00  3313.25  3316.75  3309.25  3312.75   51666.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 15:00:00  3313.00  3316.25  3306.25  3307.50  147701.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 15:15:00  3307.75  3317.50  3305.25  3317.25   78692.0  3354.75  3357.25  3280.75  3317.25  1976121.0
2020-09-18 15:30:00  3317.25  3317.25  3317.25  3317.25       6.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 15:45:00  3317.00  3317.25  3314.25  3316.50    5766.0      NaN      NaN      NaN      NaN        NaN
2020-09-18 16:00:00  3316.50  3318.00  3314.50  3317.25    3714.0      NaN      NaN      NaN      NaN        NaN

I use the following code with added 0 margins to test out:

    # Visualization
    import finplot as fplt

    # no margins
    fplt.right_margin_candles = 0
    fplt.side_margin = 0

    mat = feat.data_frame.tail(1000)
    ax, ax2 = fplt.create_plot("Custom", rows=2)
    fplt.candlestick_ochl(mat[['Open', 'High', 'Low', 'Close']].dropna())
    fplt.candlestick_ochl(mat[['OpenUS', 'HighUS', 'LowUS', 'CloseUS']], ax=ax2)
    fplt.show()

But once I plot it, I get
image

I am totally confused to what happened to the wicks...but when I run your example, it works...

Ah, you've flipped order of the columns! It's called candlestick_ochl, as in Open, Close, High, Low. But you've provided them in the order Open, High, Low, Close. Right order:

fplt.candlestick_ochl(mat[['OpenUS', 'CloseUS', 'HighUS', 'LowUS']].dropna(), candle_width=10)
fplt.candlestick_ochl(mat[['Open', 'Close', 'High', 'Low']])
fplt.show()

gets me closer to what you're expecting:

image

Set some colors and you're good to go! Notice that you should plot your low-res version first to get it underneath, then the higher-resolution one on top. (Also .dropna() was meant on the low-res data, but you can probably leave that out.)

LOL nice! totally didn't see that! thanks so much for quick response, finplot is by far the best interactive plot out there....no joke