[解決!Python]Excelワークシートに移動平均線を作成するには(OpenPyXL)解決!Python

OpenPyXLが提供するTrendlineクラスを使って、グラフに移動平均線を追加したり、その線色を変更したりする方法を紹介。

» 2022年04月19日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

values = [
    ['日付', '始値', '高値', '安値', '終値'],
    ['2022年03月09日', 1270, 1527, 1170, 1421],
    ['2022年03月10日', 1480, 1624, 1380, 1588],
    ['2022年03月11日', 1620, 1650, 1550, 1623],
    ['2022年03月14日', 1652, 1782, 1622, 1743],
    ['2022年03月15日', 1729, 1829, 1729, 1784],
    ['2022年03月16日', 1839, 1956, 1780, 1760],
    ['2022年03月17日', 1798, 1834, 1726, 1750],
    ['2022年03月18日', 1759, 1875, 1715, 1725],
    ['2022年03月22日', 1719, 1789, 1551, 1623],
    ['2022年03月23日', 1650, 1725, 1502, 1552],
    ['2022年03月24日', 1527, 1602, 1420, 1509],
    ['2022年03月25日', 1531, 1584, 1325, 1340],
    ['2022年03月28日', 1362, 1452, 1402, 1422],
    ['2022年03月29日', 1444, 1605, 1399, 1529],
    ['2022年03月30日', 1589, 1712, 1530, 1612],
    ['2022年03月31日', 1625, 1681, 1552, 1547],
    ['2022年04月01日', 1559, 1658, 1508, 1524],
    ['2022年04月04日', 1482, 1523, 1400, 1423],
    ['2022年04月05日', 1405, 1625, 1579, 1592],
    ['2022年04月06日', 1568, 1569, 1524, 1569],
    ['2022年04月07日', 1603, 1752, 1592, 1638],
    ['2022年04月08日', 1601, 1621, 1425, 1485],
    ['2022年04月11日', 1522, 1739, 1518, 1688],
    ['2022年04月12日', 1727, 1854, 1694, 1749],
    ['2022年04月13日', 1780, 1906, 1755, 1832],
]

for v in values:
    ws.append(v)

wb.save('sample_chart.xlsx')

from openpyxl.chart import Reference, StockChart
from openpyxl.chart.axis import ChartLines
from openpyxl.chart.updown_bars import UpDownBars
from openpyxl.chart.shapes import GraphicalProperties
from openpyxl.chart.data_source import NumData, NumVal

rmin = ws.min_row
rmax = ws.max_row
cmin = ws.min_column
cmax = ws.max_column

chart = StockChart()
labels = Reference(ws, min_col=cmin, min_row=rmin+1, max_row=rmax)
src = Reference(ws, min_col=cmin+1, max_col=cmax, min_row=rmin, max_row=rmax)
chart.add_data(src, titles_from_data=True)
chart.set_categories(labels)
chart.title = '株価チャート(始値-高値-安値-終値)'
chart.anchor = 'A28'
chart.width = 24
chart.height = 16

for idx, ser in enumerate(chart.ser):
    ser.graphicalProperties.line.noFill = True

# 高低線を引くためのハック
pts = [NumVal(idx=i) for i in range(rmin, rmax)]
dummy_cache = NumData(pt=pts)
chart.ser[-1].val.numRef.numCache = dummy_cache
chart.hiLowLines = ChartLines()  # 高低線を設定

# 陽線/陰線を設定
upPr = GraphicalProperties(solidFill='FF0000')
downPr = GraphicalProperties(solidFill='0000FF')
upBars = ChartLines(spPr=upPr)
downBars = ChartLines(spPr=downPr)
chart.upDownBars = UpDownBars(upBars=upBars, downBars=downBars)

ws.add_chart(chart)

wb.save('sample_chart.xlsx')

from openpyxl.chart.trendline import Trendline
tl = Trendline(period=7, trendlineType='movingAvg')
chart.ser[-1].trendline = tl

wb.save('sample_chart.xlsx')


サンプルのワークシート

 本稿では以下のコードで作成したワークシートを例に取る。

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

values = [
    ['日付', '始値', '高値', '安値', '終値'],
    ['2022年03月09日', 1270, 1527, 1170, 1421],
    ['2022年03月10日', 1480, 1624, 1380, 1588],
    ['2022年03月11日', 1620, 1650, 1550, 1623],
    ['2022年03月14日', 1652, 1782, 1622, 1743],
    ['2022年03月15日', 1729, 1829, 1729, 1784],
    ['2022年03月16日', 1839, 1956, 1780, 1760],
    ['2022年03月17日', 1798, 1834, 1726, 1750],
    ['2022年03月18日', 1759, 1875, 1715, 1725],
    ['2022年03月22日', 1719, 1789, 1551, 1623],
    ['2022年03月23日', 1650, 1725, 1502, 1552],
    ['2022年03月24日', 1527, 1602, 1420, 1509],
    ['2022年03月25日', 1531, 1584, 1325, 1340],
    ['2022年03月28日', 1362, 1452, 1402, 1422],
    ['2022年03月29日', 1444, 1605, 1399, 1529],
    ['2022年03月30日', 1589, 1712, 1530, 1612],
    ['2022年03月31日', 1625, 1681, 1552, 1547],
    ['2022年04月01日', 1559, 1658, 1508, 1524],
    ['2022年04月04日', 1482, 1523, 1400, 1423],
    ['2022年04月05日', 1405, 1625, 1579, 1592],
    ['2022年04月06日', 1568, 1569, 1524, 1569],
    ['2022年04月07日', 1603, 1752, 1592, 1638],
    ['2022年04月08日', 1601, 1621, 1425, 1485],
    ['2022年04月11日', 1522, 1739, 1518, 1688],
    ['2022年04月12日', 1727, 1854, 1694, 1749],
    ['2022年04月13日', 1780, 1906, 1755, 1832],
]

for v in values:
    ws.append(v)

wb.save('sample_chart.xlsx')


 これは架空の企業の株価の値動きを示したものだ。Excelでこれを表示したものを以下に示す。

サンプルのワークシート サンプルのワークシート

 ここでは、前回に紹介した株価チャートをワークシートに描画した上で、近似曲線として7日間の移動平均を描画する。

移動平均

 Excelでグラフに移動平均線(特定区間の値の平均値からなるグラフ)を描画するには、まず移動平均線を表示したい系列を右クリックして、[近似曲線の追加]を選択する。

近似曲線の追加 近似曲線の追加

 そして、ウィンドウ右側に表示された近似曲線の書式設定画面で[近似曲線のオプション]から[移動平均]を選択して、[区間]に移動平均を取る区間を指定する。以下は[移動平均]を選択し、[区間]を「7」にしたところだ。左側のグラフに既に移動平均線が表示されている点に注目されたい。

近似曲線のオプション 近似曲線のオプション

 OpenPyXLでこれと同じことを行うには、openpyxl.chart.trendline.Trendlineクラスを使用する。このクラスのインスタンスを生成して、それを系列データのtrendline属性にセットすることで、移動平均線を描画できる。

 実際には以下のようなコードになる。

chart = StockChart()

# 省略

from openpyxl.chart.trendline import Trendline
tl = Trendline(period=7, trendlineType='movingAvg')
chart.ser[-1].trendline = tl


 Trendlineクラスのインスタンス生成時には「period引数に平均を取る区間数」を、「trendlineTypeに移動平均を意味する'movingAvg'」を指定する。それはグラフ(上のコード例ではchart)の系列データのtrendline属性に代入するだけだ。ここでは「chart.ser[-1]」となっているので、最後の系列データ、つまり終値の移動平均線が描画されるようになる。なお、trendlineType属性には'movingAvg'以外に'power'/'exp'/'log'/'poly'/'linear'を指定でき、それぞれ累乗近似曲線/指数近似曲線/対数近似曲線/多項式近似曲線/線形近似曲線を描画することを意味する。

 以下では、株価チャートの終値の移動平均線を描画するコードを見る。

株価チャートの描画

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。