Life is Like a Boat

忘備録や経済、投資、プログラミングに関するメモやtipsなど

帝王の投資哲学を読み返す

最近読み返している1999年初版の帝王の投資哲学という投資本があります。

アメリカの公共放送PBSで制作されたマネー番組を書籍化したものです。(原題はBeyond Wall Street)

マークモビアスやピーターバーンスタインなど著名な投資家のスタイル、手法の概要が取材されています。

それだけでなく、長くマーケットで生き抜いてきた知恵や人生観、マーケットの歴史などをそれぞれの投資家の半生を通じて読める部分が面白いです。

Amazonでは中古が13円から出ており、これはお買い得すぎる値だと思います。

帝王の投資哲学

帝王の投資哲学

  • 作者: スティーブンミンツ,トーマスウィルソン,ダナデイキン,Steven L. Mintz,Thomas Willison,Dana Dakin,石井吉文
  • 出版社/メーカー: 日本経済新聞社
  • 発売日: 1999/03
  • メディア: 単行本
  • この商品を含むブログ (1件) を見る

NBRの10月29日放送回より

S&P500が新高値をつけたわけですが、Nightly Business ReportでCIOのRaymond James氏が1. リセッションはこない、2. 予想より良い利益の伸び、3.季節性を理由にこのトレンドは持続すると解説しています。

特に3.の季節性については、4Qが歴史的にパフォーマンスがよい四半期であること、大統領選の前年であることをあげています。ちなみに過去60年間で行われた16回の大統領選のうち、S&P500がプラスになった年は14回あります。

同氏が推奨するのは米大型株、特にIT、通信サービス、ヘルスケアセクターです。 f:id:nerimplo:20191030162455p:plain

f:id:nerimplo:20191030162458p:plain

番組の動画はこちらから。 www.youtube.com

Pandasを使って営業日ベースで騰落率を調べる

例えば、トヨタ、ソフトバンク、任天堂、村田製作所、日本たばこ産業で構成されるポートフォリオがあるとします。ここからそれぞれの企業の四半期決算発表日前後の株価の騰落率を調べてみようと思います。

Pandasでこのようなデータフレームを作ります。

txt = """7974,任天堂,20190731
7203,トヨタ自動車,20190802
9984,ソフトバンクグループ,20190807
6981,村田製作所,20190731
2914,日本たばこ産業,20190731"""


companies = []
for row in txt.split('\n'):
    d = {}
    r = row.split(',')
    code, name = r[0], r[1]
    d['code']=r[0]
    d['name']=r[1]
    d['t']=r[2]
    companies.append(d)

df = pd.DataFrame(companies).set_index('code')

このようなデータフレームになります。日付はSBI証券から7~8月にかけての決算発表スケジュール(国内株式)を参照しました。

f:id:nerimplo:20190926121509p:plain

さらに決算発表日の2営業日前後の日付を取得します。

例えばGW期間直前や月曜日に決算発表をする場合、営業日ベースで考えると土日祝日を考慮する必要があります。

特に今年は譲位に伴う特別な祝日がGW期間中にありましたし、昨年まで休日だった上皇陛下の誕生日(12月23日)は休日ではなくなります。

私の知る限り、Pythonのdatetime周りのライブラリーで最新の日本の祝日を考慮してくれるものはないと思います。(あったら教えてください!)

date.weekday()で土日判定は可能なので、休日判定のためには総務省の祝日csvファイルを使うのがいいと思います。 このcsvは2020年までの休日が含まれているので、来年のどこかの時点で2021年分を取得して休日リストをアップデートしてあげる必要があります。

国民の祝日について - 内閣府

いろいろ試してみて結局、営業日APIを自作してHeroku Appにしてみました。 2019年9月26日の15営業日後を知りたい場合、クエリパラメータでfromとnを指定してあげます。 https://aio-business-days.herokuapp.com/biz?from=20190926&n=15

レスポンスはこのようにしてます。2019年9月26日の10営業日後の日付は10月18日。

{"date": "20191018", "from": "20190926", "n": "15"}

話をデータフレームに戻すと決算発表日のtがわかっているので前後2営業日の日付を取得します。 上記APIを叩くための関数を作り、それを呼び出した戻り値をデータフレームのセルの値にしてあげます。

df['t-2']=''
df['t+2']=''

BASE_URL = 'https://aio-business-days.herokuapp.com/biz?from={0}&n={1}'

def get_date(t,n):
    res = requests.get(BASE_URL.format(t,n))
    return res.json()

for idx, row in df.iterrows():
    value = get_date(row['t'],-2)
    df.at[idx,'t-2']=value['date']

for idx, row in df.iterrows():
    value = get_date(row['t'],2)
    df.at[idx,'t+2']=value['date']

f:id:nerimplo:20190926131305p:plain

同じ要領で二期間の騰落率(終値ベースで)を計算するAPIを使い(以前自作していました)、セルの値として入れてみるとこのようなデータフレームになりました。

f:id:nerimplo:20191028100834p:plain

決算発表後の騰落率がプラスであれば、ポジティブサプライズ、そうでなければネガティブサプライズと定義してパターン分けできそうです。

- +ve -ve
2営業日前 村田 任天堂、トヨタ、SBG、JT
2営業日後 任天堂 村田、トヨタ、SBG、JT

Pandasデータフレームのセルに色をつけたい

PandasのデータフレームをJupyter Notebook上でテーブル表示する際、セルに色をつけたいケースがあります。

具体的にはこんな風にしたい時です。

f:id:nerimplo:20190911105839p:plain

このテーブルは TOPIXコア30採用銘柄の毎月のベストとワーストパフォーマーを色付けしたものです。 例えば、今年の4月の騰落率でみると、任天堂が+17.10%でコア30銘柄中のベストパフォーマー、武田薬が-8.74とワーストになっています。

セルに色をつける事ができるとは聞いた事がありましたが、実際にどうするのか知らなかったので調べてみました。

まず、Pandas公式にはStylingを使うとあります。

pandas.pydata.org

よく読むと、やりたいことはカラム毎(毎月)に最大値、最小値を見つける関数を適用するのようです。

コードにすると下記のようになります。

  • データフレームの1つのカラムを指すデータ構造であるSeriesに対して、series.max()で最大(小)値を見つけ、最大(小)値でなければtrueで色付け(background-color)、そうでなければ何もしないという関数を作る。
def highlight_highest_on_each_month(series):
    is_max = series == series.max()
    return ['background-color: #FC6C4D' if v else '' for v in is_max]

def highlight_lowest_on_each_month(series):
    is_min = series == series.min()
    return ['background-color: #5B60F8' if v else '' for v in is_min]

is_max = series == series.max()の部分が直感的にわからない感じがしますが、

is_max = series == series.max()
print(is_max)

でboolのSeriesを生成しています。

  • メソッドチェーンを使ってそれぞれの関数をapplyしてあげます。
df = df.style.apply(highlight_highest_on_each_month).apply(highlight_lowest_on_each_month)
  • htmlファイルとして書き出します。
with open("df.html","w", encoding='utf-8') as f:
    f.write(df.render())

書き出したあとは、cssを調整するなどして見栄えを整えてあげればいいと思います。

参考記事

stackoverflow.com

PythonユーザのためのJupyter[実践]入門

PythonユーザのためのJupyter[実践]入門

Dockerメモ

株価等データをためているDBに対していろいろテストしたく、実験用の環境欲しいなと思っていました。

Dockerを使って環境をサクッと作りたいのですが、MacbookProの容量が足りなくなりそうで、サブ機のWin10Homeがインストールされた旧型MacbookでDocker環境を構築することにしました。

ポイントとして、Docker for WindowsがWin10Homeだと使えないので(Hyper-Vがない)、Docker Toolboxをインストールする必要があります。

導入にはこのQiita記事が役立ちました。 qiita.com

qiita.com

嵌りどころしてあるのは、DockerへのアクセスにはVMのIPアドレスを使う点です。 qiita.com

上記Qiita記事にあるように、例えばnginxコンテナを立ち上げて、ブラウザからhttp://localhostするとアクセスできません。自分はこれが分からないままで2時間くらい無駄にしました。

自分の環境構築に使ったdocker-compose.ymlです。 github.com

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

試して学ぶ Dockerコンテナ開発

試して学ぶ Dockerコンテナ開発

LambdaとSQSを使った自動化

決算発表が過ぎ、やっぱり進捗率を網羅的に把握しておく必要あるなと再認識するに至りました。よく株探で上方修正期待の高進捗率ランキングなどと記事が出ますが、幅広くみたい場合はやはり手元にデータセットを作るしかないのではないかと。こうした動機から、せっかくなので今まで触った機会が少なかったAWSを使って日次で進捗率を把握する仕組みを作ってみました。

処理の流れ

  1. PuppeteerスクリプトをHeroku Schedulerで毎日定期実行。
  2. 結果をCSVにしてAWS S3に保存。
  3. S3にCSVファイルが保存されたタイミングでAWS SQSを介してファイルが生成された旨のイベントを生成、AWS Lambdaを実行。
  4. LambdaはPythonのPandasで前処理しているイメージ。不用なカラムの除去、データ型の変更、カンマ区切りの除去、憎き全角スペースの除去などを行います。結果はHeroku Postgresにupsertする。

成果

こんな感じで進捗率が把握できます。18年分も取得して決算期変更等がなければ前年同期比の比較ができるようにしました。 f:id:nerimplo:20190826131031p:plain

ポイント

Pandasはdataframeをto_sqlする際に、PostgreSQLにupsertする仕組みがありません。 Dataframeを一度array of dictionaryに変換、sqlalchemy.dialects.postgresqlを使ってupsertのステートメントを作るようにしました。

python - Bulk Upsert with SQLAlchemy Postgres - Stack Overflow

コスト

AWS側は無料枠を使い切るまで残り98%くらいあり、このペースの日次の実行だと十分余裕がありそうです。 Heroku Postgres側は毎月$9のHobby Basicを使っています。

ゼロからわかるAmazon Web Services超入門 はじめてのクラウド (かんたんIT基礎講座)

ゼロからわかるAmazon Web Services超入門 はじめてのクラウド (かんたんIT基礎講座)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

熊本県南部のおすすめ海水浴場

梅雨明けして一気に暑くなりバテ気味です。

子供が夏休みに入り、盆よりもチケットが安い7月中に実家に帰った方がいいだろうということで先週水曜から今週月曜まで実家に帰省していました。

今日のエントリーは、帰省中に海水浴で訪れた熊本県芦北町の御立岬海水浴場の紹介です。

御立岬海水浴場

南九州西回り自動車道を田浦ICで降りて、だいたい15分くらいの場所にあります。

公営の駐車場があり1日500円で駐められます。

駐車場から浜辺へと抜ける道にトンネルがあります。

人の高さ+2mくらいのトンネルでかなり声が響きます。

そしてトンネルを抜けると、目の前に広がるのは青い海と白い砂浜。 f:id:nerimplo:20190731222144j:plain

写真映えする場所なので観光協会主催のフォトコンテストをやっているとのことでした。

f:id:nerimplo:20190731222614j:plain

海の家でテント1張り1日千円で貸し出してました。シャワーは1回5分で100円。

一緒に行った奥さんがインスタ映えしそうな写真を撮ってました。

f:id:nerimplo:20190731222814j:plain

ゴーカート場

海水浴場の駐車場横に全長1kmのゴーカート場があります。2人乗りで500円です。 子供も運転できるのでマリカー気分で楽しめます。

f:id:nerimplo:20190731222426j:plain

道の駅たのうら

海水浴場から車で10分くらいのところに「道の駅たのうら」があります。

田浦IC降りてすぐの場所にあるので海水浴場に行く前にお昼ご飯を済ませるといいでしょう。

この道の駅のおすすめはタチウオ丼です。マツコDXの番組でも紹介されたらしいです。 セルフ式の食堂に入ると注文聞かれます。支払い済ませて席で待っているとアナウンスされますので取りに行きます。

このタチウオ、地元の漁師さんが一本釣りするそうです。網で取るとタチウオが傷つき値段が下がるとのこと。

丸ごと一尾揚げた分が丼ぶりに乗ってまして、サクサクと竜田揚げのような食感です。

お値段は750円。定食だと1050円。

子供も頼んだんですが、パクパク食べていました。

f:id:nerimplo:20190731221953j:plain

www.otachimisaki.com

人がうじゃうじゃいる都会のプールよりも、田舎の広い人が少ない海水浴場で思いっきり遊んだほうがいいなと感じた次第です。