Search code examples
python-3.xmatplotlibdebuggingplottrading

How to correctly plot a trading chart using a custom function on Python3? MatPlotLib related


Say I have the following df called df_trading_pair which contains the following data from the BTC/USDT trading pair:

            Start Date  Open Price  High Price  Low Price  Close Price                End Date
0  2022-08-11 11:25:00    24512.25    24548.24   24507.78     24542.74 2022-08-11 11:29:59.999
1  2022-08-11 11:30:00    24543.54    24576.21   24524.36     24545.57 2022-08-11 11:34:59.999
2  2022-08-11 11:35:00    24545.08    24598.75   24541.00     24582.48 2022-08-11 11:39:59.999
3  2022-08-11 11:40:00    24583.40    24587.86   24552.52     24585.19 2022-08-11 11:44:59.999
4  2022-08-11 11:45:00    24586.40    24629.78   24578.02     24605.81 2022-08-11 11:49:59.999
5  2022-08-11 11:50:00    24605.81    24685.20   24597.07     24605.73 2022-08-11 11:54:59.999
6  2022-08-11 11:55:00    24605.73    24627.63   24533.40     24559.37 2022-08-11 11:59:59.999
7  2022-08-11 12:00:00    24559.37    24629.27   24546.00     24605.93 2022-08-11 12:04:59.999
8  2022-08-11 12:05:00    24606.71    24629.72   24592.89     24608.49 2022-08-11 12:09:59.999
9  2022-08-11 12:10:00    24608.49    24690.00   24582.14     24643.84 2022-08-11 12:14:59.999
10 2022-08-11 12:15:00    24644.79    24734.49   24602.37     24653.81 2022-08-11 12:19:59.999
11 2022-08-11 12:20:00    24653.81    24711.33   24635.80     24658.57 2022-08-11 12:24:59.999
12 2022-08-11 12:25:00    24658.57    24686.70   24593.81     24612.47 2022-08-11 12:29:59.999
13 2022-08-11 12:30:00    24613.83    24918.54   24531.05     24614.16 2022-08-11 12:34:59.999
14 2022-08-11 12:35:00    24617.40    24770.00   24567.41     24738.36 2022-08-11 12:39:59.999
15 2022-08-11 12:40:00    24737.14    24766.82   24640.00     24687.93 2022-08-11 12:44:59.999
16 2022-08-11 12:45:00    24690.17    24780.00   24687.21     24729.00 2022-08-11 12:49:59.999
17 2022-08-11 12:50:00    24730.52    24779.32   24698.54     24768.73 2022-08-11 12:54:59.999

When running df_trading_pair.dtypes, the following output is returned:

Start Date     datetime64[ns]
Open Price            float64
High Price            float64
Low Price             float64
Close Price           float64
End Date       datetime64[ns]
dtype: object

I'm interested in plotting the data above to make it look like this:

expected output

So, I decided to build the following code to do so:

import matplotlib.pyplot as plt
import numpy as np

def candlestick(t, o, h, l, c):
    plt.figure(figsize=(16, 12), dpi=80)
    color = ["green" if close_price >= open_price else "red" for close_price, open_price in zip(c, o)]
    plt.bar(x=t, height=np.abs(o-c), bottom=np.min((o,c), axis=0), width=0.6, color=color)
    plt.bar(x=t, height=h-l, bottom=l, width=0.1, color=color)

candlestick(df_trading_pair["Start Date"],
                df_trading_pair["Open Price"],
                df_trading_pair["High Price"],
                df_trading_pair["Low Price"],
                df_trading_pair["Close Price"])
plt.grid(alpha=0.2)
plt.show()

In theory, it should work as expected, but in reality it ended up being pretty disappointing:

problem

I came here to politely request a feedback and alternative to make it work.

I think the sentence yaxis.set_label_position("right") could be added at the beginning of the candlestick function to set the y label to the right, but I don't know how could the x label be set to show only the time format in HH:MM:00 (i.e. 11:25:00) from the Start Date column.

May I get some assistance here?


Solution

  • I decided to go for an alternative:

    import mplfinance as mpf
    import matplotlib.pyplot as plt
    import pandas as pd
    from binance.client import Client
    
    client = Client(api_key= api_key, api_secret= secret_key, tld= "com")
    
    def klines_to_df(df_trading_pair):
    
        #drop unnecesary columns
        df_trading_pair.drop(5, inplace = True, axis=1)
        df_trading_pair.drop(7, inplace = True, axis=1)
        df_trading_pair.drop(8, inplace = True, axis=1)
        df_trading_pair.drop(9, inplace = True, axis=1)
        df_trading_pair.drop(10, inplace = True, axis=1)
        df_trading_pair.drop(11, inplace = True, axis=1)
    
        # Rename the column names for best practices
        df_trading_pair.rename(columns = { 0 : 'Start Date', 
                                           1 : 'Open Price',
                                           2 : 'High Price',
                                           3 : 'Low Price',
                                           4 :'Close Price',
                                           6 :'End Date',
                                          }, inplace = True)
    
        # Convert Unix Time values to actual dates
        df_trading_pair['Start Date'] = pd.to_datetime(df_trading_pair['Start Date'], unit='ms')
        df_trading_pair['End Date'] = pd.to_datetime(df_trading_pair['End Date'], unit='ms')
        df_trading_pair = df_trading_pair.astype({'Open Price': 'float'})
        df_trading_pair = df_trading_pair.astype({'High Price': 'float'})
        df_trading_pair = df_trading_pair.astype({'Low Price': 'float'})
        df_trading_pair = df_trading_pair.astype({'Close Price': 'float'})
    
        return df_trading_pair
    
    def set_DateTimeIndex(df_trading_pair):
        df_trading_pair = df_trading_pair.set_index('Start Date', inplace=False)
        # Rename the column names for best practices
        df_trading_pair.rename(columns = { "Open Price" : 'Open',
                                           "High Price" : 'High',
                                           "Low Price" : 'Low',
                                           "Close Price" :'Close',
                                  }, inplace = True)
        return df_trading_pair
    
    #get historical klines
    klines = client.get_historical_klines(symbol="BTCUSDT", interval="5m", start_str = "1660235100000", end_str="1660240200000")
    
    # Customize the df_trading_pair that stored klines
    df_trading_pair = klines_to_df(pd.DataFrame(klines))
    # Modify the previous df so the next lines of code run perfectly
    df_trading_pair_date_time_index = set_DateTimeIndex(df_trading_pair)
    
    # Plotting
    # Create my own `marketcolors` style:
    mc = mpf.make_marketcolors(up='#2fc71e',down='#ed2f1a',inherit=True)
    # Create my own `MatPlotFinance` style:
    s  = mpf.make_mpf_style(base_mpl_style=['bmh','dark_background'],marketcolors=mc, y_on_right=True)    
    
    # Plot it
    btc_plot, axlist = mpf.plot(df_trading_pair_date_time_index,
                                figratio=(10, 6),
                                type="candle",
                                style=s,
                                tight_layout=True,
                                datetime_format = '%H:%M',
                                ylabel = "Precio ($)",
                                returnfig=True)
    # Add Title
    axlist[0].set_title("BTC/USDT - 5m", fontsize=25, style='italic', fontfamily='fantasy' )
    

    Output:

    enter image description here