如何在matplotlib中用datetime绘制ohlc烛台?

时间:2016-03-31 13:18:44

标签: python numpy matplotlib

我需要每5分钟(一支蜡烛)绘制交易数据

这是我到目前为止所做的:

from matplotlib.finance import candlestick2_ohlc
fig, ax = plt.subplots()
candlestick2_ohlc(ax,quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)

它看起来像这样:

result

我需要改进它:

  1. 蓝色标记显示xticks显示int,我希望它们采用datetime格式。

  2. 红色标记显示状态栏中的x值。我希望它也是datetime格式。

  3. 以下是quotes演示数据:

    array([ (1459388100, 29.799999237060547, 29.799999237060547, 29.799999237060547, 29.799999237060547, 148929.0, 450030016.0),
       (1459388400, 29.799999237060547, 29.979999542236328, 29.709999084472656, 29.920000076293945, 10395.0, 31069984.0),
       (1459388700, 29.959999084472656, 30.18000030517578, 29.719999313354492, 30.149999618530273, 38522.0, 114999968.0),
       (1459389000, 30.170000076293945, 30.479999542236328, 30.0, 30.149999618530273, 29823.0, 90220032.0),
       (1459389300, 30.149999618530273, 30.75, 30.1299991607666, 30.549999237060547, 38903.0, 118620032.0),
       (1459389600, 30.59000015258789, 30.93000030517578, 30.559999465942383, 30.65999984741211, 42308.0, 130000000.0),
       (1459389900, 30.6200008392334, 30.690000534057617, 30.3799991607666, 30.3799991607666, 20209.0, 61689984.0),
       (1459390200, 30.3700008392334, 30.489999771118164, 30.18000030517578, 30.18000030517578, 18491.0, 56169984.0),
       (1459390500, 30.190000534057617, 30.329999923706055, 30.010000228881836, 30.010000228881836, 17641.0, 53200000.0),
       (1459390800, 30.030000686645508, 30.399999618530273, 30.030000686645508, 30.280000686645508, 9526.0, 28899968.0),
       (1459391100, 30.299999237060547, 30.31999969482422, 30.200000762939453, 30.209999084472656, 9282.0, 28100096.0),
       (1459391400, 30.190000534057617, 30.280000686645508, 30.049999237060547, 30.1200008392334, 8663.0, 26099968.0),
       (1459391700, 30.110000610351562, 30.110000610351562, 29.959999084472656, 30.100000381469727, 15677.0, 47099904.0),
       (1459392000, 30.1200008392334, 30.260000228881836, 30.0, 30.059999465942383, 5649.0, 17000064.0),
       (1459392300, 30.079999923706055, 30.299999237060547, 30.0, 30.280000686645508, 6057.0, 18199936.0),
       (1459392600, 30.290000915527344, 30.34000015258789, 30.1200008392334, 30.1200008392334, 7914.0, 24000000.0),
       (1459392900, 30.1299991607666, 30.15999984741211, 30.079999923706055, 30.139999389648438, 4521.0, 13600000.0),
       (1459393200, 30.139999389648438, 30.139999389648438, 29.829999923706055, 29.899999618530273, 16255.0, 48600064.0),
       (1459393500, 29.93000030517578, 30.1200008392334, 29.889999389648438, 30.1200008392334, 6877.0, 20600064.0),
       (1459393800, 30.1299991607666, 30.15999984741211, 29.979999542236328, 30.030000686645508, 3803.0, 11499904.0),
       (1459394100, 30.040000915527344, 30.1299991607666, 30.0, 30.030000686645508, 4421.0, 13300096.0),
       (1459394400, 29.989999771118164, 30.389999389648438, 29.989999771118164, 30.389999389648438, 7011.0, 21099904.0),
       (1459394700, 30.399999618530273, 30.450000762939453, 30.270000457763672, 30.299999237060547, 12095.0, 36800000.0),
       (1459395000, 30.34000015258789, 30.450000762939453, 30.280000686645508, 30.43000030517578, 9284.0, 28099968.0),
       (1459400700, 30.510000228881836, 30.729999542236328, 30.5, 30.600000381469727, 17139.0, 52500096.0),
       (1459401000, 30.600000381469727, 30.799999237060547, 30.530000686645508, 30.790000915527344, 11888.0, 36400000.0),
       (1459401300, 30.809999465942383, 31.100000381469727, 30.809999465942383, 31.049999237060547, 30692.0, 95099904.0),
       (1459401600, 31.06999969482422, 31.559999465942383, 30.93000030517578, 31.559999465942383, 24473.0, 76200064.0),
       (1459401900, 31.600000381469727, 31.860000610351562, 31.299999237060547, 31.450000762939453, 34497.0, 109200000.0),
       (1459402200, 31.43000030517578, 31.600000381469727, 31.18000030517578, 31.18000030517578, 18525.0, 58200064.0),
       (1459402500, 31.18000030517578, 31.350000381469727, 31.040000915527344, 31.18000030517578, 10153.0, 31599872.0),
       (1459402800, 31.200000762939453, 31.399999618530273, 31.010000228881836, 31.389999389648438, 9668.0, 30100096.0),
       (1459403100, 31.399999618530273, 31.399999618530273, 31.110000610351562, 31.360000610351562, 8445.0, 26499968.0),
       (1459403400, 31.360000610351562, 31.399999618530273, 31.040000915527344, 31.100000381469727, 9538.0, 29799936.0),
       (1459403700, 31.1200008392334, 31.399999618530273, 31.100000381469727, 31.270000457763672, 7996.0, 25000064.0),
       (1459404000, 31.270000457763672, 31.399999618530273, 31.15999984741211, 31.399999618530273, 6760.0, 21100032.0),
       (1459404300, 31.389999389648438, 32.400001525878906, 31.389999389648438, 32.189998626708984, 26108.0, 83700096.0),
       (1459404600, 32.209999084472656, 32.400001525878906, 31.860000610351562, 32.29999923706055, 15736.0, 50599936.0),
       (1459404900, 32.29999923706055, 32.310001373291016, 31.489999771118164, 31.489999771118164, 12945.0, 41399808.0),
       (1459405200, 31.5, 32.0, 31.40999984741211, 31.81999969482422, 11901.0, 37700096.0),
       (1459405500, 31.809999465942383, 31.940000534057617, 31.719999313354492, 31.770000457763672, 6503.0, 20700160.0),
       (1459405800, 31.760000228881836, 31.790000915527344, 31.399999618530273, 31.790000915527344, 10103.0, 31899904.0),
       (1459406100, 31.780000686645508, 32.029998779296875, 31.780000686645508, 31.850000381469727, 12033.0, 38500096.0),
       (1459406400, 31.809999465942383, 33.310001373291016, 31.809999465942383, 33.029998779296875, 58238.0, 192199936.0),
       (1459406700, 33.029998779296875, 33.310001373291016, 32.79999923706055, 32.79999923706055, 36689.0, 121900032.0),
       (1459407000, 32.79999923706055, 32.869998931884766, 32.61000061035156, 32.70000076293945, 15245.0, 49799936.0),
       (1459407300, 32.68000030517578, 32.689998626708984, 31.799999237060547, 32.0099983215332, 20507.0, 65999872.0),
       (1459407600, 32.02000045776367, 32.02000045776367, 31.760000228881836, 31.799999237060547, 29610.0, 94300160.0)], 
      dtype=[('time', '<i4'), ('open', '<f4'), ('high', '<f4'), ('low', '<f4'), ('close', '<f4'), ('volume', '<f4'), ('amount', '<f4')])
    

7 个答案:

答案 0 :(得分:17)

以下是一些有效的代码。

首先,我们使用datetime.datetime.fromtimestamp将时间戳转换为日期时间对象。

然后,我们使用ticker.MaxNLocator设置刻度线位置。

然后我创建了一个函数来提供给ticker.FuncFormatter以使用datetime对象作为刻度标签,并使用tick的整数值来索引xdate列表我们早些时候创建。

如果try... except数组中的最终时间戳超出了勾号,quotes子句就在那里,在这种情况下函数会失败。

我还添加autofmt_xdate()来旋转刻度线,tight_layout()为它们腾出空间

from matplotlib.finance import candlestick2_ohlc
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime as datetime
import numpy as np

quotes = np.array(...)

fig, ax = plt.subplots()
candlestick2_ohlc(ax,quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)

xdate = [datetime.datetime.fromtimestamp(i) for i in quotes['time']]

ax.xaxis.set_major_locator(ticker.MaxNLocator(6))

def mydate(x,pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax.xaxis.set_major_formatter(ticker.FuncFormatter(mydate))

fig.autofmt_xdate()
fig.tight_layout()

plt.show()

enter image description here

答案 1 :(得分:2)

在这里,我想由Daniele扩展此页面上的代码,因为有些人想看看DataFrame(价格)的样子。这是我的看法(感谢Daniele提出的这个好主意)。

listTimestamp = list(<timestamp data>)
listOpen = list(<Open data>)
listHigh = list(<High data>)
listLow = list(<Low data>)
listClose = list(<Close data>)

dictdata = {'Timestamp':listTimestamp,'Open':listOpen,
          'High':listHigh,'Low':listLow,'Close':listClose}
prices = pd.DataFrame(dictdata,columns=['Timestamp','Open','High','Low','Close'])

width=0.9
width2=0.1
pricesup=prices[prices.Close>=prices.Open]
pricesdown=prices[prices.Close<prices.Open]
plt.bar(pricesup.index,pricesup.Close-pricesup.Open,width,bottom=pricesup.Open,color='g')
plt.bar(pricesup.index,pricesup.High-pricesup.Close,width2,bottom=pricesup.Close,color='g')
plt.bar(pricesup.index,pricesup.Low-pricesup.Open,width2,bottom=pricesup.Open,color='g')
plt.bar(pricesdown.index,pricesdown.Close-pricesdown.Open,width,bottom=pricesdown.Open,color='r')
plt.bar(pricesdown.index,pricesdown.High-pricesdown.Open,width2,bottom=pricesdown.Open,color='r')
plt.bar(pricesdown.index,pricesdown.Low-pricesdown.Close,width2, bottom=pricesdown.Close,color='r')
plt.grid()
plt.show()

答案 2 :(得分:2)

我建议使用finplot,它会自动处理日期。

import finplot as fplt
import pandas as pd

a = [[1459388100, 29.799999237060547, 29.799999237060547, 29.799999237060547, 29.799999237060547, 148929.0, 450030016.0],
     [1459388400, 29.799999237060547, 29.979999542236328, 29.709999084472656, 29.920000076293945, 10395.0, 31069984.0],
     [1459388700, 29.959999084472656, 30.18000030517578, 29.719999313354492, 30.149999618530273, 38522.0, 114999968.0],
     [1459389000, 30.170000076293945, 30.479999542236328, 30.0, 30.149999618530273, 29823.0, 90220032.0]]
     # add some more data...
df = pd.DataFrame(a, columns='time open high low close volume amount'.split())
fplt.candlestick_ochl(df[['time','open','close','high','low']])
fplt.show()

enter image description here

免责声明:我写了finplot是由于我对matplotlib和plotly的API的厌恶,性能和功能不足。

答案 3 :(得分:1)

您应首先将数组中的日期戳转换为datetime对象,然后使用date2num转换它。

http://matplotlib.org/api/finance_api.html

中所述

matplotlib.finance.candlestick_ochl(ax,引用,width = 0.2,colorup ='k',colordown ='r',alpha = 1.0)

引用:(时间,开放,关闭,高,低,...)序列的序列

只要前5个元素是这些值,就可以根据需要记录(例如,它可以存储音量)。

时间必须采用浮动日格式 - 请参阅date2num

import datetime
from matplotlib.dates import date2num

a = your_array
d = [date2num(datetime.datetime.fromtimestamp(x[0])) for x in a]

答案 4 :(得分:1)

在没有matplotlib.finance的情况下绘制OHLC蜡烛

假设价格是一个数据框

import pandas as pd
import matplotlib.pyplot as plt

plt.figure()
width=1
width2=0.1
pricesup=prices[prices.close>=prices.open]
pricesdown=prices[prices.close<prices.open]

plt.bar(pricesup.index,pricesup.close-pricesup.open,width,bottom=pricesup.open,color='g')
plt.bar(pricesup.index,pricesup.high-pricesup.close,width2,bottom=pricesup.close,color='g')
plt.bar(pricesup.index,pricesup.low-pricesup.open,width2,bottom=pricesup.open,color='g')

plt.bar(pricesdown.index,pricesdown.close-pricesdown.open,width,bottom=pricesdown.open,color='r')
plt.bar(pricesdown.index,pricesdown.high-pricesdown.open,width2,bottom=pricesdown.open,color='r')
plt.bar(pricesdown.index,pricesdown.low-pricesdown.close,width2, bottom=pricesdown.close,color='r')
plt.grid()

答案 5 :(得分:0)

我不想使用任何外部库,并且发现这里的其他答案非常复杂。这是我的代码:

def candlestick(t, o, h, l, c):
    plt.figure(figsize=(12,4))
    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["2020-02":"2020-04"].index,
    df["2020-02":"2020-04"]["Open"],
    df["2020-02":"2020-04"]["High"],
    df["2020-02":"2020-04"]["Low"],
    df["2020-02":"2020-04"]["Close"]
)

plt.grid(alpha=0.2)
plt.show()

我将它与如下所示的 Pandas 数据框一起使用:

                 Open       High        Low      Close
Date                                                  
2020-02-03  76.074997  78.372498  75.555000  77.165001
2020-02-04  78.827499  79.910004  78.407501  79.712502
2020-02-05  80.879997  81.190002  79.737503  80.362503
2020-02-06  80.642502  81.305000  80.065002  81.302498
2020-02-07  80.592499  80.849998  79.500000  80.007243

结果如下: enter image description here

注意有时条的宽度会很奇怪,因此可能看不到细条。这是通过改变图形的 dpi 来解决的:https://stackoverflow.com/a/62856898/9439097

作为确认,下面是 https://www.tradingview.com 如何显示同一时期。 enter image description here

答案 6 :(得分:0)

新的matplotlib财务模块非常好用(link) 它也可以处理没有谈判的日子

您只需要一个包含 [high,low,open,close,volume] 列的 Pandas 数据框,以刻度时间戳作为索引和 2 行代码:

import mplfinance as mpf
mpf.plot(daily,type='candle',mav=(3,6,9),volume=True)

enter image description here