Pythonの勉強がてら、マネーフォワードのサイトから口座残高などの情報をスクレイピングしてきて、日々のポートフォリオを作成するというコードを書いてみました。
いろいろと勉強になることたくさんでして、忘れないように記録しておきます。(その1)では、プログラム作成の動機や内容などを、(その2)では実際のコーディングにあたってはまった点などを紹介します。
マネーフォワードの良さと問題点
マネーフォワードは、銀行・証券会社・クレジットカードの情報を登録しておくと、口座残高やカード使用履歴などを記録してくれるアプリで、すでに多くのひとが活用していると思います。
moneyforward.com
マネーフォワードの機能のひとつに、現在保有している資産の内訳や資産履歴をグラフ化してくれるものがあります。現金や預金だけでなく、株や投資信託の評価額も含めて資産管理をしてくれる点がとても便利ですが、1点こまったことがあります。それは、資産の区分が、「預金」、「株式」、「投資信託」、「債券」、「不動産」、「年金」、「ポイント・マイル」という分類で出力されること。
私の現在の資産運用は、以下の本などで紹介されている、低コストのインデックス投資信託を中心としたものです。よって、アセットアロケーションを意識して分類して、「流動資産」「国内債券」「国内株式」「海外債券」「海外株式」といった分け方をしたほうが、全体の資産状況を把握しやすいと考えました。
今までは、それぞれの銀行や証券会社のサイトから残高をダウンロードして、エクセルで集計していたのですが、なかなか面倒くさい。ということで、Pythonで自動化を試みました。
やりたいこと
実際にやろうとしたことは、以下のようになります。
- マネーフォワードに自動的にログイン
- 資産内訳のページにアクセスし、保有している資産の名前と評価額をスクレイピング
- それぞれの保有資産を、「流動資産」「国内債券」「国内株式」「海外債券」「海外株式」に分類し、アセットごとの合計を計算
- その結果をcsvファイルに保存。また、グラフ化して画像も保存
実装したコード
実際に作成したコードはこちら。まだまだ洗練されておらず、だいぶ泥臭いところも多々ありますが。
from selenium import webdriver
from selenium.webdriver.common.by import By
import pandas as pd
import datetime
import matplotlib.pyplot as plt
browser = webdriver.Chrome()
df = pd.read_csv("default.csv",index_col=0)
asset_type_list = pd.read_csv("asset_type_list.csv",encoding="SHIFT-JIS")
def get_asset_type(name):
for i in range(len(asset_type_list.index)):
if name == asset_type_list["name"][i]:
asset_type = asset_type_list["asset_type"][i]
return asset_type
url = "https://moneyforward.com/users/sign_in"
user_name = " ここにメールアドレスを入力"
password = " ここにパスワードを入力"
browser.get(url)
e = browser.find_element_by_id("sign_in_session_service_email")
e.clear()
e.send_keys(user_name)
e = browser.find_element_by_id("sign_in_session_service_password")
e.clear()
e.send_keys(password)
frm = browser.find_element_by_name("commit")
frm.click()
url_bs = "https://moneyforward.com/bs/portfolio"
browser.get(url_bs)
icount = 0
table_total_asset = browser.find_element_by_class_name("table-bordered")
trs = table_total_asset.find_elements(By.TAG_NAME,"tr")
for i in range(len(trs)):
name = trs[i].find_elements(By.TAG_NAME,"th")[0].text
values = trs[i].find_elements(By.TAG_NAME,"td")
print(name,":",values[0].text,values[1].text)
table_depo = browser.find_element_by_class_name("table-depo")
trs = table_depo.find_elements(By.TAG_NAME,"tr")
nrow = len(trs)
for i in range(1,nrow):
depo_name = trs[i].find_elements(By.TAG_NAME,"td")[0].text
depo_value = trs[i].find_elements(By.TAG_NAME,"td")[1].text
icount += 1
depo_type = get_asset_type(depo_name)
print(icount,depo_name,depo_value,depo_type)
depo_value = int(depo_value.replace("円","").replace(",",""))
se = pd.Series([depo_name,depo_value,depo_type],["name","value","asset_type"])
df = df.append(se,ignore_index=True)
table_eq = browser.find_element_by_class_name("table-eq")
trs = table_eq.find_elements(By.TAG_NAME,"tr")
nrow = len(trs)
for i in range(1,nrow):
eq_name = trs[i].find_elements(By.TAG_NAME,"td")[1].text
eq_value = trs[i].find_elements(By.TAG_NAME,"td")[5].text
icount += 1
eq_type = get_asset_type(eq_name)
print(icount,eq_name,eq_value,eq_type)
eq_value = int(eq_value.replace("円","").replace(",",""))
se = pd.Series([eq_name,eq_value,eq_type],["name","value","asset_type"])
df = df.append(se,ignore_index=True)
table_mf = browser.find_element_by_class_name("table-mf")
trs = table_mf.find_elements(By.TAG_NAME,"tr")
nrow = len(trs)
for i in range(1,nrow):
mf_name = trs[i].find_elements(By.TAG_NAME,"td")[0].text
mf_value = trs[i].find_elements(By.TAG_NAME,"td")[4].text
icount += 1
mf_type = get_asset_type(mf_name)
print(icount,mf_name,mf_value,mf_type)
mf_value = int(mf_value.replace("円","").replace(",",""))
se = pd.Series([mf_name,mf_value,mf_type],["name","value","asset_type"])
df = df.append(se,ignore_index=True)
browser.close()
filename1 = "./daily_asset/" + datetime.date.today().strftime("%Y%m%d") + "_asset-list.csv"
df.to_csv(filename1)
asset_allocation = df.groupby("asset_type").sum()["value"]
print(asset_allocation)
asset_allocation = asset_allocation.rename(index={"その他資産":"other","国内債券":"Domestic-bonds","国内株式":"Domestic-stocks","流動資産":"current-assets","海外債券":"foriegn-bonds","海外株式":"foriegn-stocks"})
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.pie(list(asset_allocation),labels=asset_allocation.index,counterclock=False,startangle=90,autopct="%1.1f%%")
title = "date: " + datetime.date.today().strftime("%Y/%m/%d") + " Total: " + '{:,}'.format(sum(asset_allocation)) + "JPY"
ax.set_title(title)
filename2 = "./daily_asset/" + datetime.date.today().strftime("%Y%m%d") + "_asset-pi-chart.png"
fig.savefig(filename2)
結果
アウトプットとしては、以下のように現在の資産合計とアセットごとの比率がグラフ化されます。
ということで、Pythonによるスクレイピングで、マネーフォワードのデータからポートフォリオを作成するプログラムでした。次回、プログラムの中身と作成する際にはまった点などを書きたいと思います。