【问题标题】:Python: Need help creating an Intraday 1m tick OHLC ChartPython:需要帮助创建日内 1m 刻度 OHLC 图表
【发布时间】:2021-02-19 08:21:06
【问题描述】:

我对 python 的所有东西都非常陌生,令我懊恼的是,我一直在尝试制作一个相当简单的 OHLC 图表。下面的代码带有数据框示例。 我正在尝试在单个交易日以 100 万个刻度为单个股票绘制并保存 OHLC 图表。 yaxis 似乎工作正常,但是显示的图表是空白的。 xaxis 显示 09:30 的开始时间,但没有其他 1m 刻度。将图表移到空白图上会显示 y 轴的值,但 x= nada。 Example

我希望最终实现的是 xaxis 标签,以分钟为单位显示时间,不需要 dae,旋转 90 度,间隔为 15 分钟。我更喜欢 OHLC 图表而不是烛台,但我也希望它是可辨认的,因为我见过许多版本,它们只是对任何人都没有用的微小垂直线的模糊。如果需要水平拉伸大小以适应数据框中的一些 376 1m 记录,那就这样吧。如果它太杂乱,那么我希望能够每隔 2 或 5 分钟间隔一次滴答间隔。但是,xaxis xticks 仍应保持 15 分钟间隔。然后我想将结果另存为 jpg。

我已经尝试了很多 mplfinace 的变体,现在不再知道什么是最新的有效模块。我在烛台_ohlc 语句中尝试了“引号”和值,似乎没有明显区别。我已经阅读并重新阅读并尝试了很多示例,但所有与 xaxis 相关的时间的翻译似乎都失败了,这对我来说非常令人困惑,而且令人沮丧.. 呵呵。

如果有人能在这里为我指明正确的方向,我将非常感谢任何和所有的帮助。

非常感谢,蒂姆.D

import pandas as pd
import numpy as np

from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from mplfinance.original_flavor import candlestick_ohlc

sym = sys.argv[1] #symbol in all caps
run_dt = sys.argv[2] #run date of the required process requires the date to be surrounded by 'quotes'
run_int = sys.argv[2].replace('/', '-')
run_int = run_int.replace("'", "")

import pyodbc #database connectivity
cnxn = pyodbc.connect(dsn='abc', user='abc', password='abc', autocommit=False)

df = pd.read_sql_query(" \
    SELECT TIMESTAMP(ACT_DATE||' '||TIME(TICK)) AS TIME, OPEN, HIGH, LOW, CLOSE \
    FROM INTRADAY_IDX \
    WHERE ACT_DATE = "+run_dt+" \
    AND SYMBOL = '"+sym+"' \
    ORDER BY 1",cnxn, )

print(df)

这会产生如下的数据框:

TIME OPEN HIGH LOW CLOSE

0 2021-02-12 09:30:00 314.27 314.50 314.22 314.49

1 2021-02-12 09:31:00 314.51 314.73 314.44 314.63

2 2021-02-12 09:32:00 314.63 314.79 314.54 314.73

.. ... ... ... ... ... ...

375 2021-02-12 15:59:00 315.01 315.14 314.85 315.00

376 2021-02-12 16:00:00 315.00 315.18 314.97 315.18


df.TIME = mdates.date2num(df.TIME.dt.to_pydatetime())
print(df.head(5))

TIME OPEN HIGH LOW CLOSE

0 737833.395833 314.27 314.50 314.22 314.49

1 737833.396528 314.51 314.73 314.44 314.63

2 737833.397222 314.63 314.79 314.54 314.73

3 737833.397917 314.83 314.89 314.76 314.85

...

#quotes = [tuple(x) for x in df[['TIME', 'OPEN', 'HIGH', 'LOW', 'CLOSE']].to_records(index=False)]
#print(quotes)

fig, ax = plt.subplots(figsize=(12,7)) 

plt.yscale('linear') #default scaling of the y axis

ax.set_xlim('09:30', '16:00') #sets the start and end values for the xaxis charting
start, end = ax.get_xlim() #initializes the start and end variables
ax.xaxis.set_ticks(np.arange(start, end, 1800)) #sets the tick values for charting
plt.xticks(rotation=90, fontsize=12) #sets the rotation value of the x axis ticks
plt.yticks(fontsize=12)

ax.set_title(sym+' OHLC Intraday Chart', fontsize=14, fontweight = 'bold')
ax.set_ylabel('Price', fontsize=12, fontweight = 'bold')
ax.set_xlabel('Time', fontsize=12, fontweight = 'bold')

plt.tight_layout() #reduces the space padding surrounding the graph

ax.grid(True)

candlestick_ohlc(ax, df.values, width = 1/(24*60*2.5), alpha = 1.0, colorup = 'g', colordown ='r')
#candlestick_ohlc(ax, quotes, width = 1/(24*60*2.5), alpha = 1.0, colorup = 'g', colordown ='r')

bbox_inches='tight') #saves the data to to jpg file
#plt.savefig('c:\\temp\\charts\\'+sym+'_OHLC_'+run_int+'.jpg', format='jpg', quality=95, #plt.close()
plt.show()

【问题讨论】:

    标签: python dataframe matplotlib


    【解决方案1】:

    非常感谢您的回复。使用您的代码,我现在设法让它工作,还添加了一个辅助图。代码如下:

    import sys, os, time, warnings #csv
    import pandas as pd
    from pandas.plotting import register_matplotlib_converters
    register_matplotlib_converters()
    #import numpy as np
    #from datetime import datetime, date, timedelta
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    #from matplotlib import dates, ticker
    from mplfinance.original_flavor import candlestick_ohlc
    
    sym = sys.argv[1] #symbol in all caps
    run_dt = sys.argv[2] #run date of the required process requires the date to be surrounded by 'quotes'
    run_int = sys.argv[2].replace('/', '-') #reformat the date
    run_int = run_int.replace("'", "") #reformat the date
    
    import pyodbc #database connectivity
    cnxn = pyodbc.connect(dsn='abc', user='abc', password='abc', autocommit=False)
    
    db = pd.read_sql_query(" \
        SELECT timestamp(ACT_DATE||' '||TIME(TICK)) AS TIME, OPEN, HIGH, LOW, CLOSE \
        FROM SQ4_INTRADAY_IDX \
        WHERE ACT_DATE = "+run_dt+" \
        AND SYMBOL = '"+sym+"' \
        ORDER BY 1",cnxn, )
    
    print(db)
    db['TIME']= pd.to_datetime(db['TIME'])
    db.set_index('TIME', inplace=True) #this resets the dataframe index to the time values
    #db.info() #shows column data types
    
    #setup an array for the candlestick chart
    dd = db.copy() #create a copy of the dataframe
    dd.index = mdates.date2num(dd.index) #set the datetime to numeric for the chart to work
    dd_data = dd.reset_index().values #set the index
    #print(dd_data)
    
    clse = db["CLOSE"] #setup the data for plotting an additional subplot line
    
    fig, ax = plt.subplots(figsize=(12,7))
    
    ax.set_title(sym+' OHLC Intraday Chart', fontsize=14, fontweight='bold')
    ax.set_ylabel('Price', fontsize=12, fontweight='bold')
    ax.set_xlabel('Time', fontsize=12, fontweight='bold')
    
    candlestick_ohlc(ax, dd_data, width=.0003, alpha=.8, colorup='g', colordown='r')
    ax.plot(clse, color = 'k', linestyle='--', linewidth = .5, label='Close')
    
    plt.xticks(rotation=90, fontsize=12) #sets the rotation value of the x axis ticks
    plt.yticks(fontsize=12) #sets the rotation value of the x axis ticks
    
    ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=30))
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
    
    plt.tight_layout() #reduces the space padding surrounding the graph
    plt.savefig('c:\\temp\\'+sym+'_OHLC Intrday Chart for '+run_int+'.jpg', format='jpg', quality=95, bbox_inches='tight') #saves the data to to jpg file
    
    plt.show()
    

    这会产生附加的图表。 我的问题是我试图删除左右 y 轴刻度之间的填充空间。换句话说,我希望 9:30 标签直接显示在左侧下方,而 16:00 显示在右侧边距下方。基本上我想我正在尝试拉伸图表以填充整个图表框。

    还有没有办法在左右两边加上左边的价格刻度值?

    感谢您的帮助,非常感谢。 问候,蒂姆.D

    【讨论】:

    • 实现自我回答中添加的要求的代码请参考我的回复。
    【解决方案2】:

    这个函数的参数必须是一个数组。此外,日期和时间的格式必须转换为mdates2num()。其余时间,日期和时间由定位器和格式化程序控制。我认为您的代码中相关的ax.set_xlim('09:30', '16:00') 是导致错误的原因。数据来自雅虎财经。

    import pandas as pd
    import numpy as np
    from datetime import datetime, date, timedelta
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    from mplfinance.original_flavor import candlestick_ohlc
    import yfinance as yf
    
    dia = yf.download("DIA", period='1d', interval='1m', start="2021-02-11", end='2021-02-12')
    
    df = dia.copy()
    df.index = mdates.date2num(df.index)
    data = df.reset_index().values
    
    fig, ax = plt.subplots(figsize=(12,7)) 
    
    sym = 'DIA'
    candlestick_ohlc(ax, data, width=1/(24*60*2.5), alpha=1.0, colorup='g', colordown='r')
    
    ax.set_title(sym+' OHLC Intraday Chart', fontsize=14, fontweight='bold')
    ax.set_ylabel('Price', fontsize=12, fontweight='bold')
    ax.set_xlabel('Time', fontsize=12, fontweight='bold')
    # update start
    ax.set_xlim(data[0][0], data[382][0])
    ax1 = ax.twinx()
    ax1.set_yticks(ax.get_yticks())
    ax1.set_ybound(ax.get_ybound())
    ax1.set_yticklabels([str(x) for x in ax.get_yticks()])
    # update end
    ax.grid()
    
    locator = mdates.AutoDateLocator()
    ax.xaxis.set_major_locator(locator)
    ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))
    
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 2011-08-02
      • 2013-12-08
      相关资源
      最近更新 更多