实时K线图(matplotlib)

5

我想实时使用Interactive Brokers的数据绘制matplotlib.finance的蜡烛图。有没有人有一个简单的例子可以做到这一点?我能够使用一些类似以下代码的简单线型图来完成它:

class Data:
    def __init__(self, maxLen=50):
        self.maxLen = maxLen
        self.x_data = np.arange(maxLen)
        self.y_data = deque([], maxLen)

    def add(self, val):
        self.y_data.append(val)

class Plot:
    def __init__(self, data):
        plt.ion()
        self.ayline, = plt.plot(data.y_data)
        self.ayline.set_xdata(data.x_data)

    def update(self, data):
        self.ayline.set_ydata(data.y_data)
        plt.draw()

if __name__ == "__main__":
    data = Data()
    plot = Plot(data)

    while 1:
        data.add(np.random.randn())
        plot.update(data)
        sleep(1)

我该如何通过提供5元组作为y值,将其更改为蜡烛图?

我不确定我真正理解你的问题。你是想添加新的蜡烛图还是只有一个单一的标记需要更新?此外,请注意在1.4版本中,matplotlib.finance将进行重大重构,以更好地匹配约定的参数顺序。(1.4版本尚未发布,更改在开发分支上进行) - tacaswell
是的,主要想法是添加新的蜡烛图。然而,在每个tick上更新最新的也会很好。 - Morten
你还需要获取时间(使用dt = datetime.datetime.utcnow()),并将其转换为Unix时间戳。使用模运算(与您的时间框架一起)来确定何时必须添加新的蜡烛。 - working4coins
time_round = int(unix_timestamp / timeframe_seconds) * timeframe_seconds 如果 time_round 大于 time_round_previous,则表示出现了新的蜡烛。 - working4coins
1个回答

8
我刚刚成功实现了类似的功能。为了更简单地说明这种方法,我修改了matplotlib网站上的finance_demo示例。
#!/usr/bin/env python
import matplotlib.pyplot as plt
from matplotlib.dates import  DateFormatter, WeekdayLocator, HourLocator, \
     DayLocator, MONDAY
from matplotlib.finance import quotes_historical_yahoo, candlestick,\
     plot_day_summary, candlestick2


# make plot interactive in order to update
plt.ion()

class Candleplot:
    def __init__(self):
        fig, self.ax = plt.subplots()
        fig.subplots_adjust(bottom=0.2)

    def update(self, quotes, clear=False):

        if clear:
            # clear old data
            self.ax.cla()

        # axis formatting
        self.ax.xaxis.set_major_locator(mondays)
        self.ax.xaxis.set_minor_locator(alldays)
        self.ax.xaxis.set_major_formatter(weekFormatter)

        # plot quotes
        candlestick(self.ax, quotes, width=0.6)

        # more formatting
        self.ax.xaxis_date()
        self.ax.autoscale_view()
        plt.setp( plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')

        # use draw() instead of show() to update the same window
        plt.draw()


# (Year, month, day) tuples suffice as args for quotes_historical_yahoo
date1 = ( 2004, 2, 1)
date2 = ( 2004, 4, 12 )
date3 = ( 2004, 5, 1 )

mondays = WeekdayLocator(MONDAY)        # major ticks on the mondays
alldays    = DayLocator()              # minor ticks on the days
weekFormatter = DateFormatter('%b %d')  # e.g., Jan 12
dayFormatter = DateFormatter('%d')      # e.g., 12

quotes = quotes_historical_yahoo('INTC', date1, date2)

plot = Candleplot()
plot.update(quotes)

raw_input('Hit return to add new data to old plot')

new_quotes = quotes_historical_yahoo('INTC', date2, date3)

plot.update(new_quotes, clear=False)

raw_input('Hit return to replace old data with new')

plot.update(new_quotes, clear=True)

raw_input('Finished')

基本上,我使用plt.ion()打开交互模式,使绘图在程序继续运行时可以更新。要更新数据,似乎有两个选项。(1)您可以再次调用candlestick()并传入新数据,这将在不影响先前绘制的数据的情况下将其添加到绘图中。这可能更适合向结尾添加一个或多个新蜡烛;只需传递包含新蜡烛的列表即可。(2)使用ax.cla()(清除轴)在传递新数据之前删除所有先前的数据。如果要移动窗口(例如,仅绘制最后50个蜡烛),则应优先选择此选项,因为仅向末尾添加新蜡烛将导致越来越多的蜡烛在图表中累积。同样,如果要更新最后一个蜡烛,在它关闭之前,您应该首先清除旧数据。清除轴也会清除一些格式设置,因此应设置函数以在调用ax.cla()后重复轴的格式设置。

不确定问题是否仍然与原始发布者相关,但希望这对某人有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接