Pythonで読み込んだFXデータをチャートとして表示させる

前回の記事で説明した、EUR/USDの1分足データを入力して、時刻を7時間シフトさせるコードです。なお、TF_ohlc()関数では、'NaN'行の削除する部分も追加しています。

In [1]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pandas.tseries.offsets as offsets

# dfのデータからtfで指定するタイムフレームの4本足データを作成する関数
def TF_ohlc(df, tf):
    x = df.resample(tf).ohlc()
    ret = pd.DataFrame({'Open': x['Open']['open'],
                       'High': x['High']['high'],
                       'Low': x['Low']['low'],
                       'Close': x['Close']['close']},
                       columns=['Open','High','Low','Close'])
    return ret.dropna()
    
dataM1 = pd.read_csv('C:\Python\DAT_ASCII_EURUSD_M1_2015.csv', sep=';',
                     names=('Time','Open','High','Low','Close', ''),
                     index_col='Time', parse_dates=True)
dataM1.index += offsets.Hour(7) #7時間のオフセット

このTF_ohlc()を使うと、日足データは次のように簡単に作れます。

In [2]:
ohlcD1 = TF_ohlc(dataM1, 'D')
ohlcD1
Out[2]:
Open High Low Close
Time
2015-01-01 1.20965 1.21041 1.20959 1.21002
2015-01-02 1.21037 1.21072 1.20002 1.20009
2015-01-05 1.19427 1.19763 1.18664 1.19327
2015-01-06 1.19329 1.19687 1.18841 1.18893
2015-01-07 1.18894 1.18965 1.18021 1.18392
2015-01-08 1.18377 1.18474 1.17541 1.17916
2015-01-09 1.17930 1.18459 1.17626 1.18407
2015-01-12 1.18499 1.18709 1.17862 1.18334
2015-01-13 1.18331 1.18595 1.17534 1.17722
2015-01-14 1.17722 1.18462 1.17272 1.17887
2015-01-15 1.17888 1.17924 1.15678 1.16299
2015-01-16 1.16304 1.16487 1.14600 1.15620
2015-01-19 1.15516 1.16389 1.15513 1.16019
2015-01-20 1.16068 1.16148 1.15405 1.15485
2015-01-21 1.15483 1.16802 1.15414 1.16092
2015-01-22 1.16095 1.16509 1.13159 1.13647
2015-01-23 1.13649 1.13738 1.11144 1.12024
2015-01-26 1.11511 1.12953 1.10978 1.12386
2015-01-27 1.12377 1.14225 1.12236 1.13805
2015-01-28 1.13761 1.13829 1.12760 1.12863
2015-01-29 1.12862 1.13678 1.12617 1.13192
2015-01-30 1.13183 1.13636 1.12786 1.12839
2015-02-02 1.13105 1.13620 1.12922 1.13411
2015-02-03 1.13407 1.15340 1.13123 1.14785
2015-02-04 1.14788 1.14847 1.13155 1.13433
2015-02-05 1.13433 1.14987 1.13038 1.14768
2015-02-06 1.14763 1.14856 1.13117 1.13154
2015-02-09 1.12964 1.13592 1.12702 1.13231
2015-02-10 1.13229 1.13454 1.12730 1.13202
2015-02-11 1.13200 1.13472 1.12799 1.13354
... ... ... ... ...
2015-11-19 1.06572 1.07630 1.06552 1.07346
2015-11-20 1.07323 1.07384 1.06397 1.06436
2015-11-23 1.06377 1.06568 1.05927 1.06356
2015-11-24 1.06354 1.06731 1.06195 1.06428
2015-11-25 1.06419 1.06892 1.05660 1.06236
2015-11-26 1.06237 1.06273 1.05998 1.06093
2015-11-27 1.06095 1.06380 1.05685 1.05900
2015-11-30 1.05881 1.05949 1.05578 1.05631
2015-12-01 1.05629 1.06370 1.05623 1.06313
2015-12-02 1.06312 1.06356 1.05508 1.06127
2015-12-03 1.06129 1.09811 1.05223 1.09376
2015-12-04 1.09376 1.09562 1.08359 1.08832
2015-12-07 1.08725 1.08876 1.07960 1.08369
2015-12-08 1.08362 1.09021 1.08300 1.08917
2015-12-09 1.08909 1.10425 1.08791 1.10240
2015-12-10 1.10226 1.10245 1.09251 1.09401
2015-12-11 1.09392 1.10308 1.09266 1.09886
2015-12-14 1.09823 1.10486 1.09455 1.09909
2015-12-15 1.09905 1.10594 1.09045 1.09280
2015-12-16 1.09284 1.10110 1.08879 1.09115
2015-12-17 1.09105 1.09138 1.08027 1.08251
2015-12-18 1.08238 1.08744 1.08050 1.08652
2015-12-21 1.08531 1.09389 1.08470 1.09145
2015-12-22 1.09137 1.09841 1.09021 1.09555
2015-12-23 1.09550 1.09565 1.08701 1.09093
2015-12-24 1.09093 1.09676 1.09028 1.09630
2015-12-28 1.09676 1.09924 1.09547 1.09652
2015-12-29 1.09650 1.09915 1.08992 1.09193
2015-12-30 1.09172 1.09436 1.09018 1.09312
2015-12-31 1.09309 1.09372 1.08527 1.08545

260 rows × 4 columns

plot()関数を使うと、このデータをグラフにプロットさせることができます。

In [3]:
ohlcD1.plot()
Out[3]:
<matplotlib.axes._subplots.AxesSubplot at 0x2897b079cc0>

一応、4本のラインが表示されてます。本当はローソク足のチャートにしたいのですが、その方法は後述します。

次に表示させるデータの期間を選択してみます。その方法も色々あるようですが、ここではわかりやすい方法を書いておきます。例えば、6月分のデータのみを選択したい場合、次のように書きます。

In [4]:
ohlcD1_6 = ohlcD1['2015-06-01':'2015-06-30']
ohlcD1_6
Out[4]:
Open High Low Close
Time
2015-06-01 1.09802 1.09881 1.08872 1.09261
2015-06-02 1.09261 1.11942 1.09159 1.11500
2015-06-03 1.11498 1.12853 1.10793 1.12739
2015-06-04 1.12730 1.13797 1.12227 1.12377
2015-06-05 1.12371 1.12800 1.10492 1.11110
2015-06-08 1.10972 1.13067 1.10841 1.12904
2015-06-09 1.12910 1.13451 1.12140 1.12819
2015-06-10 1.12821 1.13863 1.12601 1.13237
2015-06-11 1.13235 1.13313 1.11817 1.12571
2015-06-12 1.12572 1.12965 1.11511 1.12618
2015-06-15 1.12104 1.12945 1.11891 1.12825
2015-06-16 1.12834 1.13298 1.12050 1.12470
2015-06-17 1.12469 1.13577 1.12064 1.13368
2015-06-18 1.13358 1.14362 1.13301 1.13584
2015-06-19 1.13575 1.13968 1.12919 1.13487
2015-06-22 1.13771 1.14101 1.13117 1.13395
2015-06-23 1.13393 1.13473 1.11351 1.11664
2015-06-24 1.11663 1.12352 1.11544 1.12039
2015-06-25 1.12028 1.12275 1.11536 1.12030
2015-06-26 1.12029 1.12197 1.11302 1.11661
2015-06-29 1.10036 1.12785 1.09530 1.12343
2015-06-30 1.12336 1.12440 1.11121 1.11454

確かに6月分のデータのみが抽出されました。このデータをプロットさせると次のようになります。

In [5]:
ohlcD1_6.plot()
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x28900b4d588>
こんどは、日中足のチャートを表示させてみます。例えば、30分足の4本値データを作成して、そのなかで6月11日の部分のみを抽出してみます。
In [6]:
ohlcM30 = TF_ohlc(dataM1, '30Min')
ohlcM30_6_11 = ohlcM30['2015-06-11']
ohlcM30_6_11
Out[6]:
Open High Low Close
Time
2015-06-11 00:00:00 1.13235 1.13263 1.13196 1.13208
2015-06-11 00:30:00 1.13208 1.13232 1.13142 1.13186
2015-06-11 01:00:00 1.13186 1.13247 1.13136 1.13246
2015-06-11 01:30:00 1.13246 1.13252 1.13181 1.13236
2015-06-11 02:00:00 1.13236 1.13236 1.13121 1.13170
2015-06-11 02:30:00 1.13170 1.13175 1.13063 1.13098
2015-06-11 03:00:00 1.13097 1.13117 1.13007 1.13012
2015-06-11 03:30:00 1.13012 1.13081 1.13001 1.13014
2015-06-11 04:00:00 1.13013 1.13023 1.12941 1.12969
2015-06-11 04:30:00 1.13027 1.13051 1.12835 1.12856
2015-06-11 05:00:00 1.12854 1.12967 1.12846 1.12921
2015-06-11 05:30:00 1.12921 1.13020 1.12896 1.13020
2015-06-11 06:00:00 1.13020 1.13051 1.12986 1.13021
2015-06-11 06:30:00 1.13023 1.13047 1.12981 1.13011
2015-06-11 07:00:00 1.13013 1.13131 1.13013 1.13125
2015-06-11 07:30:00 1.13124 1.13137 1.13001 1.13022
2015-06-11 08:00:00 1.13023 1.13100 1.12945 1.13015
2015-06-11 08:30:00 1.13015 1.13052 1.12958 1.13031
2015-06-11 09:00:00 1.13030 1.13313 1.12924 1.13164
2015-06-11 09:30:00 1.13163 1.13210 1.12975 1.12991
2015-06-11 10:00:00 1.12990 1.12997 1.12805 1.12867
2015-06-11 10:30:00 1.12868 1.12870 1.12505 1.12621
2015-06-11 11:00:00 1.12621 1.12627 1.12409 1.12559
2015-06-11 11:30:00 1.12561 1.12685 1.12532 1.12663
2015-06-11 12:00:00 1.12665 1.12690 1.12458 1.12564
2015-06-11 12:30:00 1.12565 1.12679 1.12500 1.12651
2015-06-11 13:00:00 1.12651 1.12842 1.12632 1.12655
2015-06-11 13:30:00 1.12653 1.12734 1.12648 1.12667
2015-06-11 14:00:00 1.12666 1.12689 1.12550 1.12554
2015-06-11 14:30:00 1.12551 1.12676 1.12322 1.12336
2015-06-11 15:00:00 1.12343 1.12463 1.12212 1.12217
2015-06-11 15:30:00 1.11954 1.12694 1.11817 1.12531
2015-06-11 16:00:00 1.12535 1.12559 1.12131 1.12170
2015-06-11 16:30:00 1.12171 1.12282 1.12051 1.12278
2015-06-11 17:00:00 1.12276 1.12410 1.12179 1.12372
2015-06-11 17:30:00 1.12368 1.12384 1.12113 1.12320
2015-06-11 18:00:00 1.12323 1.12536 1.12301 1.12492
2015-06-11 18:30:00 1.12492 1.12519 1.12320 1.12365
2015-06-11 19:00:00 1.12364 1.12409 1.12315 1.12328
2015-06-11 19:30:00 1.12328 1.12416 1.12253 1.12403
2015-06-11 20:00:00 1.12401 1.12465 1.12327 1.12365
2015-06-11 20:30:00 1.12366 1.12381 1.12320 1.12353
2015-06-11 21:00:00 1.12358 1.12484 1.12358 1.12477
2015-06-11 21:30:00 1.12475 1.12655 1.12404 1.12636
2015-06-11 22:00:00 1.12637 1.12667 1.12563 1.12589
2015-06-11 22:30:00 1.12586 1.12751 1.12579 1.12701
2015-06-11 23:00:00 1.12703 1.12775 1.12624 1.12631
2015-06-11 23:30:00 1.12630 1.12634 1.12557 1.12571

このデータをプロットさせると次のようになります。

In [7]:
ohlcM30_6_11.plot()
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x28900fa4da0>

このように折れ線のチャートなら簡単に表示させられるのですが、ローソク足チャートの場合、pandasplot()関数では表示できないようなので、matplotlib.financecandlestick_ohlc()を使ってみることにします。

まずは、OHLCの系列を別々に引数にするcandlestick2_ohlc()を使った方法です。ローソク足の幅を表すwidth、陽線、陰線の色を表すcolorupcolordownを指定すると、次のように書けます。

In [8]:
import matplotlib.finance as mpf
ohlc = ohlcM30_6_11
ax = plt.subplot()
mpf.candlestick2_ohlc(ax, ohlc['Open'], ohlc['High'], ohlc['Low'], ohlc['Close'],
                      width=0.7, colorup='blue', colordown='red')
Out[8]:
(<matplotlib.collections.LineCollection at 0x28901122ac8>,
 <matplotlib.collections.PolyCollection at 0x28901122c50>)

こんな感じです。上下のヒゲがローソク足本体を突き抜けていてちょっと変な感じですね。

次に時間と4本値の5系列をまとめて引数とするcandlestick_ohlc()の場合です。この引数がDataFrame型に対応していれば簡単だったのですが、このまま代入してもエラーになってしまいます。仕方ないので、DataFramevaluesの部分が配列になっているので、それに整数のインデックスの配列を結合して、5系列の配列データにしたものを代入してみました。

In [9]:
ohlc = ohlcM30_6_11
t = np.arange(1,len(ohlc)+1).reshape((len(ohlc),1))
tohlc = np.hstack((t, ohlc.values))
ax = plt.subplot()
mpf.candlestick_ohlc(ax, tohlc, width=0.7, colorup='blue', colordown='red')
Out[9]:
([<matplotlib.lines.Line2D at 0x289010c4898>,
  <matplotlib.lines.Line2D at 0x289011a43c8>,
  <matplotlib.lines.Line2D at 0x289011aa4e0>,
  <matplotlib.lines.Line2D at 0x289011b05f8>,
  <matplotlib.lines.Line2D at 0x289011b5710>,
  <matplotlib.lines.Line2D at 0x289011bb828>,
  <matplotlib.lines.Line2D at 0x289011c2940>,
  <matplotlib.lines.Line2D at 0x289011c6a58>,
  <matplotlib.lines.Line2D at 0x289011cbb70>,
  <matplotlib.lines.Line2D at 0x289011d3c88>,
  <matplotlib.lines.Line2D at 0x289011d9da0>,
  <matplotlib.lines.Line2D at 0x289011dfeb8>,
  <matplotlib.lines.Line2D at 0x289011e5fd0>,
  <matplotlib.lines.Line2D at 0x289011f1128>,
  <matplotlib.lines.Line2D at 0x289011f5240>,
  <matplotlib.lines.Line2D at 0x289011fb358>,
  <matplotlib.lines.Line2D at 0x28901201470>,
  <matplotlib.lines.Line2D at 0x289010fcc50>,
  <matplotlib.lines.Line2D at 0x28901166208>,
  <matplotlib.lines.Line2D at 0x28901209160>,
  <matplotlib.lines.Line2D at 0x2890120d278>,
  <matplotlib.lines.Line2D at 0x28901212390>,
  <matplotlib.lines.Line2D at 0x289012194a8>,
  <matplotlib.lines.Line2D at 0x2890121e5c0>,
  <matplotlib.lines.Line2D at 0x289012246d8>,
  <matplotlib.lines.Line2D at 0x2890122a7f0>,
  <matplotlib.lines.Line2D at 0x28901230908>,
  <matplotlib.lines.Line2D at 0x28901234a20>,
  <matplotlib.lines.Line2D at 0x2890123bb38>,
  <matplotlib.lines.Line2D at 0x28901241c50>,
  <matplotlib.lines.Line2D at 0x28901249d68>,
  <matplotlib.lines.Line2D at 0x2890124de80>,
  <matplotlib.lines.Line2D at 0x28901253f98>,
  <matplotlib.lines.Line2D at 0x28901259fd0>,
  <matplotlib.lines.Line2D at 0x28901263208>,
  <matplotlib.lines.Line2D at 0x2890126a320>,
  <matplotlib.lines.Line2D at 0x2890126f438>,
  <matplotlib.lines.Line2D at 0x28901275550>,
  <matplotlib.lines.Line2D at 0x2890127b668>,
  <matplotlib.lines.Line2D at 0x28901281780>,
  <matplotlib.lines.Line2D at 0x28901285898>,
  <matplotlib.lines.Line2D at 0x2890128c9b0>,
  <matplotlib.lines.Line2D at 0x28901291ac8>,
  <matplotlib.lines.Line2D at 0x28901297be0>,
  <matplotlib.lines.Line2D at 0x2890129dcf8>,
  <matplotlib.lines.Line2D at 0x289012a3e10>,
  <matplotlib.lines.Line2D at 0x289012a9f28>,
  <matplotlib.lines.Line2D at 0x289012aff60>],
 [<matplotlib.patches.Rectangle at 0x2890119f5c0>,
  <matplotlib.patches.Rectangle at 0x289011a42e8>,
  <matplotlib.patches.Rectangle at 0x289011aa400>,
  <matplotlib.patches.Rectangle at 0x289011b0518>,
  <matplotlib.patches.Rectangle at 0x289011b5630>,
  <matplotlib.patches.Rectangle at 0x289011bb748>,
  <matplotlib.patches.Rectangle at 0x289011c2860>,
  <matplotlib.patches.Rectangle at 0x289011c6978>,
  <matplotlib.patches.Rectangle at 0x289011cbc50>,
  <matplotlib.patches.Rectangle at 0x289011d90b8>,
  <matplotlib.patches.Rectangle at 0x289011df1d0>,
  <matplotlib.patches.Rectangle at 0x289011e52e8>,
  <matplotlib.patches.Rectangle at 0x289011ea3c8>,
  <matplotlib.patches.Rectangle at 0x289011f1048>,
  <matplotlib.patches.Rectangle at 0x289011f5160>,
  <matplotlib.patches.Rectangle at 0x289011fb278>,
  <matplotlib.patches.Rectangle at 0x28901201390>,
  <matplotlib.patches.Rectangle at 0x2890116feb8>,
  <matplotlib.patches.Rectangle at 0x28901162ef0>,
  <matplotlib.patches.Rectangle at 0x28901209080>,
  <matplotlib.patches.Rectangle at 0x2890120d198>,
  <matplotlib.patches.Rectangle at 0x289012122b0>,
  <matplotlib.patches.Rectangle at 0x289012193c8>,
  <matplotlib.patches.Rectangle at 0x2890121e4e0>,
  <matplotlib.patches.Rectangle at 0x289012245f8>,
  <matplotlib.patches.Rectangle at 0x2890122a710>,
  <matplotlib.patches.Rectangle at 0x28901230828>,
  <matplotlib.patches.Rectangle at 0x28901234940>,
  <matplotlib.patches.Rectangle at 0x2890123ba90>,
  <matplotlib.patches.Rectangle at 0x28901249160>,
  <matplotlib.patches.Rectangle at 0x2890124d198>,
  <matplotlib.patches.Rectangle at 0x289012532b0>,
  <matplotlib.patches.Rectangle at 0x28901259358>,
  <matplotlib.patches.Rectangle at 0x2890125e208>,
  <matplotlib.patches.Rectangle at 0x28901263128>,
  <matplotlib.patches.Rectangle at 0x2890126a240>,
  <matplotlib.patches.Rectangle at 0x2890126f358>,
  <matplotlib.patches.Rectangle at 0x28901275470>,
  <matplotlib.patches.Rectangle at 0x2890127b588>,
  <matplotlib.patches.Rectangle at 0x289012816a0>,
  <matplotlib.patches.Rectangle at 0x289012857b8>,
  <matplotlib.patches.Rectangle at 0x2890128c8d0>,
  <matplotlib.patches.Rectangle at 0x289012919e8>,
  <matplotlib.patches.Rectangle at 0x28901297cf8>,
  <matplotlib.patches.Rectangle at 0x289012a3128>,
  <matplotlib.patches.Rectangle at 0x289012a9240>,
  <matplotlib.patches.Rectangle at 0x289012af2e8>,
  <matplotlib.patches.Rectangle at 0x289012b4160>])

こんどはこんな感じです。ヒゲの色が本体と同じになっているので、突き抜けたような違和感はありません。ただ、どちらの関数を使うにしろ、横軸に時刻を表示させるのは、もうちょっと細工しないといけないようです。これ以上手間がかかるのならPython使う意味ないので、今回はここまでにしておきます。