Search code examples
pythonpandasplotlyyfinance

how do i make 1 plotly chart consisting of different dataframes, I need help to add the right buttons as well?


Below is the starting code, dataframes and TA indicator. Using plotly to make all my graphs. The dataframes are 'df' and 'd15'. I do have others but will keep it simple for the help.

import yfinance as yf
import plotly.graph_objs as go

#Importing my data
df = yf.download(tickers='EURUSD=X', period='1d', interval='5m')

d15 = yf.download(tickers='EURUSD=X', period='3d',interval='15m')

def Supertrend(df, atr_period, multiplier):
high = df['High']
low = df['Low']
close = df['Close']


# calculate ATR
price_diffs = [high - low, 
               high - close.shift(), 
               close.shift() - low]
true_range = pd.concat(price_diffs, axis=1)
true_range = true_range.abs().max(axis=1)
# default ATR calculation in supertrend indicator
atr = true_range.ewm(alpha=1/atr_period,min_periods=atr_period).mean() 
# df['atr'] = df['tr'].rolling(atr_period).mean()

# HL2 is simply the average of high and low prices
hl2 = (high + low) / 2
# upperband and lowerband calculation
# notice that final bands are set to be equal to the respective bands
final_upperband = upperband = hl2 + (multiplier * atr)
final_lowerband = lowerband = hl2 - (multiplier * atr)

# initialize Supertrend column to True
supertrend = [True] * len(df)

for i in range(1, len(df.index)):
    curr, prev = i, i-1
    
    # if current close price crosses above upperband
    if close[curr] > final_upperband[prev]:
        supertrend[curr] = True
    # if current close price crosses below lowerband
    elif close[curr] < final_lowerband[prev]:
        supertrend[curr] = False
    # else, the trend continues
    else:
        supertrend[curr] = supertrend[prev]
        
        # adjustment to the final bands
        if supertrend[curr] == True and final_lowerband[curr] < final_lowerband[prev]:
            final_lowerband[curr] = final_lowerband[prev]
        if supertrend[curr] == False and final_upperband[curr] > final_upperband[prev]:
            final_upperband[curr] = final_upperband[prev]

    # to remove bands according to the trend direction
    if supertrend[curr] == True:
        final_upperband[curr] = np.nan
    else:
        final_lowerband[curr] = np.nan

return pd.DataFrame({
    'Supertrend': supertrend,
    'Final Lowerband': final_lowerband,
    'Final Upperband': final_upperband
}, index=df.index)


atr_period = 10
atr_multiplier = 6.0

df = yf.download(tickers='EURUSD=X', period='1d', interval='5m')
supertrend = Supertrend(df, atr_period, atr_multiplier)
df = df.join(supertrend)

#15 Minute Indicator 
def Supertrend(df, atr_period, multiplier):
high = df['High']
low = df['Low']
close = df['Close']


# calculate ATR
price_diffs = [high - low, 
               high - close.shift(), 
               close.shift() - low]
true_range = pd.concat(price_diffs, axis=1)
true_range = true_range.abs().max(axis=1)
# default ATR calculation in supertrend indicator
atr = true_range.ewm(alpha=1/atr_period,min_periods=atr_period).mean() 
# df['atr'] = df['tr'].rolling(atr_period).mean()

# HL2 is simply the average of high and low prices
hl2 = (high + low) / 2
# upperband and lowerband calculation
# notice that final bands are set to be equal to the respective bands
final_upperband = upperband = hl2 + (multiplier * atr)
final_lowerband = lowerband = hl2 - (multiplier * atr)

# initialize Supertrend column to True
supertrend = [True] * len(df)

for i in range(1, len(df.index)):
    curr, prev = i, i-1
    
    # if current close price crosses above upperband
    if close[curr] > final_upperband[prev]:
        supertrend[curr] = True
    # if current close price crosses below lowerband
    elif close[curr] < final_lowerband[prev]:
        supertrend[curr] = False
    # else, the trend continues
    else:
        supertrend[curr] = supertrend[prev]
        
        # adjustment to the final bands
        if supertrend[curr] == True and final_lowerband[curr] < final_lowerband[prev]:
            final_lowerband[curr] = final_lowerband[prev]
        if supertrend[curr] == False and final_upperband[curr] > final_upperband[prev]:
            final_upperband[curr] = final_upperband[prev]

    # to remove bands according to the trend direction
    if supertrend[curr] == True:
        final_upperband[curr] = np.nan
    else:
        final_lowerband[curr] = np.nan

return pd.DataFrame({
    'Supertrend': supertrend,
    'Final Lowerband': final_lowerband,
    'Final Upperband': final_upperband
}, index=df.index)


atr_period = 10
atr_multiplier = 6.0

df = yf.download(tickers='EURUSD=X', period='1d', interval='5m')
supertrend = Supertrend(df, atr_period, atr_multiplier)
df = df.join(supertrend)

This next part is the plot which I think is where I need the help. I need to add 2 buttons and add these 2 charts to each other?
Button 1: 5m (Shows 05m TF Plot) Button 2: 15m (Shows 15m TF Plot)

#5 Minute TF plot
fig = go.Figure()
fig.add_trace(go.Candlestick(x=df.index,
                         open=df['Open'],
                         high=df['High'],
                         low=df['Low'],
                         close=df['Close'],
                         increasing_line_color= '#04b29b', 
                         decreasing_line_color= '#ff2d5d',
                         increasing_fillcolor = '#04b29b',
                         decreasing_fillcolor = '#ff2d5d',
                         name='EURUSD'
                         ))

  fig.add_trace(go.Scatter(x=df.index,
                     y=df['Final Lowerband'],
                     mode='lines',
                     line=dict(color='#04b29b'),
                     name='Bullish'
                     ))

fig.add_trace(go.Scatter(x=df.index,
                     y=df['Final Upperband'],
                     mode='lines',
                     line=dict(color='#ff2d5d'),
                     name='Bearish'
                     ))

fig.update_layout(xaxis_rangeslider_visible=False,
              plot_bgcolor = 'black', showlegend = False,
              margin = dict(l=10, r=10,t=10,b=10),
              paper_bgcolor='black',
              xaxis=dict(showgrid=False, zerolinecolor = 'white', 
color='white'),
              yaxis=dict(showticklabels=False, showgrid=False))

fig.update_xaxes(
rangebreaks=[
    dict(bounds=["sat", "mon"]), #hide weekends
    dict(values=["2015-12-25", "2016-01-01"])  # hide Christmas 
and New Year's
    ]
 )

fig.show()

This is the 15 minute tf

15 Minute TF Plot
fig15 = go.Figure()
fig15.add_trace(go.Candlestick(x=d15.index,
                         open=d15['Open'],
                         high=d15['High'],
                         low=d15['Low'],
                         close=d15['Close'],
                         increasing_line_color= '#04b29b', 
                         decreasing_line_color= '#ff2d5d',
                         increasing_fillcolor = '#04b29b',
                         decreasing_fillcolor = '#ff2d5d',
                         name='EURUSD'
                         ))

fig15.add_trace(go.Scatter(x=d15.index,
                     y=d15['Final Lowerband'],
                     mode='lines',
                     line=dict(color='#04b29b'),
                     name='Bullish'
                     ))

fig15.add_trace(go.Scatter(x=d15.index,
                     y=d15['Final Upperband'],
                     mode='lines',
                     line=dict(color='#ff2d5d'),
                     name='Bearish'
                     ))

fig15.update_layout(xaxis_rangeslider_visible=False,
              plot_bgcolor = 'black', showlegend = False,
              margin = dict(l=10, r=10,t=10,b=10),
              paper_bgcolor='black',
              xaxis=dict(showgrid=False, zerolinecolor = 'white', 
color='white'),
              yaxis=dict(showticklabels=False, showgrid=False))

fig15.update_xaxes(
 rangebreaks=[
    dict(bounds=["sat", "mon"]), #hide weekends
    dict(values=["2015-12-25", "2016-01-01"])  # hide Christmas 
and New Year's
]
)

 fig15.show()

Solution

  • If you want to get an answer quickly, you will get a quicker answer if you put a more simplified code on it. Or, if you create a reproducible situation with sample data and code for graphs, you will have a better chance of getting an answer. To answer the main question of how to make each graph a button, you can use the stock price data from the official reference, draw three different stocks, and set the show/hide control for each to show For example, if you only have AAPL, set the others to False to hide them. That is simply the only setting.

    import plotly.graph_objects as go
    import plotly.express as px
    
    df = px.data.stocks()
    
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=df['date'], y=df['AAPL'], name='AAPL'))
    fig.add_trace(go.Scatter(x=df['date'], y=df['GOOG'], name='GOOG'))
    fig.add_trace(go.Scatter(x=df['date'], y=df['AMZN'], name='AMZN'))
    
    fig.update_layout(
        updatemenus=[
            dict(
                type="buttons",
                direction="right",
                active=0,
                x=0.25,
                y=1.2,
                buttons=list([
                    dict(label="All",
                         method="update",
                         args=[{"visible": [True, True, True]},
                               {"title": "All"}
                              ]),
                    dict(label="AAPL",
                         method="update",
                         args=[{"visible": [True, False, False]},
                               {"title": "AAPL"}
                              ]),
                    dict(label="GOOG",
                         method="update",
                         args=[{"visible": [False, True, False]},
                               {"title": "GOOG"}
                              ]),
                    dict(label="AMZN",
                         method="update",
                         args=[{"visible": [False, False, True]},
                               {"title": "AMZN"}
                              ]),
                ]),
            )
        ])
    
    fig.show()
    

    enter image description here