Skip to content

how to show more area at the far right side of the Ichimoku Cloud Chart #691

Description

@soshk

Greeting!
I am a newbie in Python, and I greatly appreciate this brilliantly made built-in package for visualization of yfinance data.
I am learning and trying to plot the Ichimoku Cloud Chart, and found that the plot displayed would show with the x-axis limited at the latest data date, while the Ichimoku indicator actually would plot the cloud area 26days into future.

I tried to extend the x-axis using the xlim() function to extend 1 month into future, but the cloud still is not shown in the plot.

I have checked and make sure that in my calculations, the shift() function is applied to the calculation of the 3 lines, Leading Span A, Leading Span B, and Lagging Span. Thus I believe that there would be data to be plotted for the future date.

The first chart below is the plot generated from my broken code.
And the lower chart is a chart I got from a free online platform. I target to make my plot look more or less like this.
May I get help on how I can correctly plot the cloud for the Ichimoku chart?

Thanks in advance.

This is the chart plotted from my broken python code
Image

This is the chart I got from a free online platform. I target to make my plot look more or less like this.
Image

Activity

  1. soshk commented on Mar 5, 2025

    @soshk
    Author

    in case it is necessart, this is my broken code

    # This allows multiple outputs from a single jupyter notebook cell:
    from IPython.core.interactiveshell import InteractiveShell
    InteractiveShell.ast_node_interactivity = "all"
    
    import yfinance as yf
    import pandas as pd
    import mplfinance as mpf
    import numpy as np
    import datetime as dt
    from datetime import timedelta, date
    
    # for fixing 
    # Error: Cannot compare tz-naive and tz-aware datetime-like objects
    import pytz
    from dateutil.relativedelta import relativedelta
    
    # Print mplfinance version for debugging
    #print(f"mplfinance version: {mpf.__version__}")
    
    def get_stock_data(stock_symbol, start, end):
        # Fetch stock data
        security = yf.Ticker(stock_symbol)
        stock = security.history(interval='1d', start=start_date, end=end_date)
        #stock = yf.download(stock_symbol, start=start_date, end=end_date)
            
        if stock.empty:
            raise ValueError(f"No data retrieved for symbol '{stock_symbol}' between {start_date} and {end_date}")
        
        # Calculate Ichimoku components, default parameters = 9, 26, 52
        # Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2
        high_9 = stock['High'].rolling(window=9).max()
        low_9 = stock['Low'].rolling(window=9).min()
        stock['Tenkan_sen'] = (high_9 + low_9) / 2
        
        # Kijun-sen (Base Line): (26-period high + 26-period low)/2
        high_26 = stock['High'].rolling(window=26).max()
        low_26 = stock['Low'].rolling(window=26).min()
        stock['Kijun_sen'] = (high_26 + low_26) / 2
        
        # Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2 shifted 26 periods forward
        stock['Senkou_Span_A'] = ((stock['Tenkan_sen'] + stock['Kijun_sen']) / 2).shift(26)
        
        # Senkou Span B (Leading Span B): (52-period high + 52-period low)/2 shifted 26 periods forward
        high_52 = stock['High'].rolling(window=52).max()
        low_52 = stock['Low'].rolling(window=52).min()
        stock['Senkou_Span_B'] = ((high_52 + low_52) / 2).shift(26)
        
        # Chikou Span (Lagging Span): Close price shifted 26 periods back
        stock['Chikou_Span'] = stock['Close'].shift(-26)
        
        # Calculate MACD, default parameter = 12, 26, 9
        stock['EMA_12'] = stock['Close'].ewm(span=12, adjust=False).mean()
        stock['EMA_26'] = stock['Close'].ewm(span=26, adjust=False).mean()
        stock['MACD'] = stock['EMA_12'] - stock['EMA_26']
        stock['Signal_Line'] = stock['MACD'].ewm(span=9, adjust=False).mean()
        stock['MACD_Hist'] = stock['MACD'] - stock['Signal_Line']
        
        # Calculate RSI, default 14days RSI vs 5days SMA
        delta = stock['Close'].diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
        rs = gain / loss
        stock['RSI'] = 100 - (100 / (1 + rs))
        
        
        return stock
    
    def plot_ichimoku_with_indicators(stock_symbol, data):
        # Prepare the data for mplfinance (OHLC format)
        ohlc_data = data[['Open', 'High', 'Low', 'Close', 'Volume']].copy()
        
        # Debugging
        print("ohlc_data head:\n", ohlc_data.head())
        print("ohlc_data columns:", ohlc_data.columns.tolist())
        print("Volume NaN count in ohlc_data:", ohlc_data['Volume'].isna().sum())
        
        # Define additional plots for Ichimoku lines
        ichimoku_lines = [
            mpf.make_addplot(data['Tenkan_sen'], color='red', label='Tenkan-sen'),
            mpf.make_addplot(data['Kijun_sen'], color='blue', label='Kijun-sen'),
            mpf.make_addplot(data['Senkou_Span_A'], color='yellow', label='Senkou_Span_A'),
            mpf.make_addplot(data['Senkou_Span_B'], color='purple', label='Senkou_Span_B'),        
            mpf.make_addplot(data['Chikou_Span'], color='black', label='Chikou Span'),        
        ]
        
        # Define the fill_between Senkou_Span_A and Senkou_Span_B for the cloud directly in the plot call
        cloud_fill = [dict(y1=data['Senkou_Span_A'].values, y2=data['Senkou_Span_B'].values, where=data['Senkou_Span_A'] >= data['Senkou_Span_B'], alpha=0.3, color='green'),
                        dict(y1=data['Senkou_Span_A'].values, y2=data['Senkou_Span_B'].values, where=data['Senkou_Span_A'] < data['Senkou_Span_B'], alpha=0.3, color='red')]
        
        # Volume = True in mpf.plot(), being panel = 1
        
        # Define MACD panel
        macd_plots = [
            mpf.make_addplot(data['MACD'], color='blue', label='MACD', ylabel='MACD', y_on_right=False, panel=2, title="MACD"),
            mpf.make_addplot(data['Signal_Line'], color='orange', label='Signal Line', panel=2),
            mpf.make_addplot(data['MACD_Hist'], type='bar', color='gray', alpha=0.5, label='Histogram', panel=2),
            mpf.make_addplot(pd.Series(0, index=data.index), color='black', linestyle='--', panel=2, width=0.5)
        ]
        
        # Define RSI panel
        rsi_plots = [
            mpf.make_addplot(data['RSI'], color='blue', label='RSI', ylabel='RSI', y_on_right=False, panel=3, title="RSI"),
            mpf.make_addplot(pd.Series(70, index=data.index), color='red', linestyle='--', panel=3, width=0.5),
            mpf.make_addplot(pd.Series(30, index=data.index), color='green', linestyle='--', panel=3, width=0.5)
        ]
    
        all_plots = ichimoku_lines + macd_plots + rsi_plots
            
        # Plot using mplfinance
        mpf.plot(ohlc_data,
                 type='hollow_candle',  # Use candlestick chart, hollow
                 style='yahoo',  # Yahoo-style coloring
                 title=f'Ichimoku Cloud Chart - {stock_symbol}',
                 addplot=all_plots,
                 volume=True,   # panel = 1
                 panel_ratios=(3, 1, 1, 1),  # Adjust panel sizes
                 fill_between=cloud_fill, # Add cloud fill for Ichimoku
                 ylabel='Price',
                 ylabel_lower='Volume',
                 #y_on_right=False,
                 xlim=(start_date, xlim_end),
                 figscale=1.5,
                 tight_layout=True,
        )
    
    # Example usage
    if __name__ == "__main__":
        #Set parameters
        #ask suer for stock symbol
        stock_symbol = input("Please enter the stock symbol: ")
        start_date = dt.datetime(date.today().year - 1, date.today().month, date.today().day, tzinfo=pytz.UTC)
        end_date = dt.datetime(date.today().year, date.today().month, date.today().day, tzinfo=pytz.UTC)
        xlim_end = dt.datetime.today().replace(tzinfo=pytz.UTC) + relativedelta(months=1)
    
        # Get data and plot
        try:
            ichimoku_data = get_stock_data(stock_symbol, start_date, end_date)
            if ichimoku_data.empty:
                raise ValueError("No data returned for the specified stock symbol.")
            plot_ichimoku_with_indicators(stock_symbol, ichimoku_data)
        except Exception as e:
            print(f"Error: {str(e)}")
    
    # Requirements:
    # pip install yfinance pandas mplfinance numpy #
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions