python で債権利回りの表示

python で債権利回りの表示

債権は

https://investpy.readthedocs.io/_api/bonds.html
で取得できそう

ただし、債権利回りがでてないので検索

債権利回りコードは
https://stackoverflow.com/questions/65063436/pulling-yields-data-from-investpy-package
を参考に

import investpy
data = investpy.bonds.get_bond_historical_data(bond='South Africa 2Y',
                                               from_date='01/01/2019',
                                               to_date='31/12/2019')
data

で南アフリカ2年債の利回りを表示可能

米国債の2年債の利回りなら

data = investpy.bonds.get_bond_historical_data(bond='U.S. 2Y',
                                               from_date='01/01/2019',
                                               to_date='31/12/2019')

data

でOK

債権の国コードや種類については
https://za.investing.com/rates-bonds/world-government-bonds?maturity_from=10&maturity_to=310
で調べることができる

Find Government Bonds

Country of Listing で国を選べば
チャートの下のほうに債権の種類が表示されるので
これをもとに
米国債2年なら
U.S. 2Y
となる

altair で表示するなら
商品市場でWTI、金価格のときにやったのと同じように
行う

今回は日付を date で取得し
年始から今日までの米国債2年債の利回りチャートを表示

from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta

today = datetime.today().strftime('%d/%m/%Y')
today

で今日の日付を取得

US2Y = investpy.bonds.get_bond_historical_data(bond='U.S. 2Y',
                                               from_date='01/01/2021',
                                               to_date=today)
US2Y

で年始から今日までの利回りを取得

US2Y.index = US2Y.index.strftime('%Y/%m/%d')

で日付フォーマット変更

US2Y = US2Y.T
US2Y = US2Y.T.reset_index()


Date カラムを移動

chart =(
    alt.Chart(US2Y)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="Date:T",
        y=alt.Y("Close:Q",stack=None)
    )
)
chart

で債権利回りをチャートで表示できる

同様に10年債も表示

US10Y = investpy.bonds.get_bond_historical_data(bond='U.S. 10Y',
                                               from_date='01/01/2019',
                                               to_date=today)
US10Y.index = US10Y.index.strftime('%Y/%m/%d')
US10Y = US10Y.T
US10Y = US10Y.T.reset_index()

us10 =(
    alt.Chart(US10Y)
    .mark_line(opacity=0.8,clip=True,color='Yellow')
    .encode(
        x="Date:T",
        y=alt.Y("Close:Q",stack=None)
    )
)

あとはチャートを重ねて表示するので

alt.layer(chart,us10).resolve_scale(
    y = 'independent'
)

とすると
2年債と10年債の2つのチャートが表示されるようになる

python でWTI、金価格の表示

python でWTI、金価格の表示 その2

investpy でも可能らしいので実線

https://investpy.readthedocs.io/_api/commodities.html
のリファレンスを見ながら実線

経済指標の取得のときには

investpy.economic_calendar()

を使い

economic_data = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date='11/06/2021')

で取得

investpy.commodities.get_commodities(group=None)

で商品市場の情報が得られる

全部で66の行になる

途中が省かれて表示されるので

commodity.head(35)

というようにすれば任意の場所まで表示できる

今回なら上から35まで表示

逆に最後から表示したいのなら

commodity.tail(36)

group の部分を指定すると絞り込みができる

金属にするなら

commodity = investpy.commodities.get_commodities(group="metals")
commodity

とすればOK

今回調べたいのはWTI、つまり原油の価格と金の価格なので

group を energy を指定

commodity = investpy.commodities.get_commodities(group="energy")
commodity

name が Crude Oil WTI のものが該当

金は金属なので
group に metails で絞り込む

commodity = investpy.commodities.get_commodities(group="metals")
commodity

この中で name が Gold のものが該当

次にチャートなどに必要なデータの取得

株価の取得方法については
【Python】investpyを使ったInvesting.comからのデータ取得方法

によれば

investpy.get_stock_historical_data()

で取得できる

ETFなら

 investpy.get_etf_historical_data()

指数データなら

investpy.get_index_historical_data()

為替データなら

investpy.get_currency_cross_historical_data()

これらを元に
https://investpy.readthedocs.io/_api/commodities.html
をみると

investpy.commodities.get_commodity_recent_data()

なら最近のデータ

investpy.commodities.get_commodity_historical_data()

で直近のデータ
を取得できそう

構文は

investpy.commodities.get_commodity_historical_data(commodity, from_date, to_date, country=None, as_json=False, order='ascending', interval='Daily')

となっている

commodity には name カラムのものを当てはめる
from_date と to_date には日付を指定
フォーマットがdd/mm/yyyyなので注意

order は昇順、降順を指定
ascending は昇順
descending は降順

interval は取得するデータの間隔
デフォルトは daily
weekly や monthly にすることも可能

例が乗っていたので参考に

data = investpy.get_historical_data(commodity='gold', from_date='01/01/2018', to_date='01/01/2019')

としたがエラーとなる

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-69013139b965> in <module>
----> 1 data = investpy.get_historical_data(commodity='gold', from_date='01/01/2018', to_date='01/01/2019')

AttributeError: module 'investpy' has no attribute 'get_historical_data'

パラメータをしっかり設定して

gold =investpy.commodities.get_commodity_historical_data(commodity="Gold", from_date='01/01/2021', to_date='01/09/2021', country=None, as_json=False, order='ascending', interval='Daily')
gold

としたら成功

なお最近のデータであれば

data = investpy.get_commodity_recent_data(commodity='gold')
data

でも取得可能
期間は1ヶ月程度

次に原油WTI

wti = investpy.get_commodity_recent_data(commodity='Crude Oil WTI')
wti

で取得可能

途中でvolume が0になっているところは市場がお休みの日

次に WTI の close の値を altair で表示

chart =(
    alt.Chart(wti)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="date:T",
        y=alt.Y("close:Q",stack=None)
    )
)
chart

だと日付の形式の関係で表示されないので
日付形式を

wti['Date']=wti['Date'].str.replace('/','-')

としたが

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/anaconda3/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   3079             try:
-> 3080                 return self._engine.get_loc(casted_key)
   3081             except KeyError as err:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'Date'

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
<ipython-input-12-cf1271b5fd73> in <module>
----> 1 wti['Date']=wti['Date'].str.replace('/','-')

~/anaconda3/lib/python3.8/site-packages/pandas/core/frame.py in __getitem__(self, key)
   3022             if self.columns.nlevels > 1:
   3023                 return self._getitem_multilevel(key)
-> 3024             indexer = self.columns.get_loc(key)
   3025             if is_integer(indexer):
   3026                 indexer = [indexer]

~/anaconda3/lib/python3.8/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   3080                 return self._engine.get_loc(casted_key)
   3081             except KeyError as err:
-> 3082                 raise KeyError(key) from err
   3083 
   3084         if tolerance is not None:

KeyError: 'Date'

となる

wti.columns

で調べると

Index(['Open', 'High', 'Low', 'Close', 'Volume', 'Currency'], dtype='object')

となっているので

wti.reset_index()


Date をカラム側にする

これで

wti.index

とすると

DatetimeIndex(['2021-08-17', '2021-08-18', '2021-08-19', '2021-08-20',
               '2021-08-23', '2021-08-24', '2021-08-25', '2021-08-26',
               '2021-08-27', '2021-08-30', '2021-08-31', '2021-09-01',
               '2021-09-02', '2021-09-03', '2021-09-05', '2021-09-06',
               '2021-09-07', '2021-09-08', '2021-09-09', '2021-09-10',
               '2021-09-13', '2021-09-14', '2021-09-15', '2021-09-16',
               '2021-09-17'],
              dtype='datetime64[ns]', name='Date', freq=None)

となる

wti.index = wti.index.strftime('%Y/%m/%d')

で日付フォーマットを変更

wti[['Close']]

とすれば Close のみに絞り込める

wti= wti.T
wti

とすれば配置を変更して
日付をカラムにできる

udemy の講習のときにはいくつか株のコードを取得したけど
今回はそれはいらない

wti= wti.T.reset_index()

を実行すると
Date が追加された状態のカラムができる

あとは

chart =(
    alt.Chart(wti)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="Date:T",
        y=alt.Y("Close:Q",stack=None)
    )
)
chart

で折れ線グラフで WTI Close のグラフが作成できる

応用で金価格グラフも作成

gold =investpy.commodities.get_commodity_historical_data(commodity="Gold", from_date='01/01/2021', to_date='01/09/2021', country=None, as_json=False, order='ascending', interval='Daily')
gold

で年始から取得

gold.reset_index()
gold.index = gold.index.strftime('%Y/%m/%d')

で日付フォーマット変更

gold= gold.T
gold= gold.T.reset_index()

でカラムに Date を追加

chart =(
    alt.Chart(gold)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="Date:T",
        y=alt.Y("Close:Q",stack=None)
    )
)
chart

でチャート表示

これで金価格も表示可能

ラズパイゼロでドラレコもどきを作成

ラズパイゼロでドラレコもどきを作成

音声なしで動画と画像のみを撮影し
Google Drive に保存するようにする予定

なおセットアップには
microSD 以外に
HDMI と USB の変換するものがないと
microUSB しかコネクタがないので
モニターとマウスをつけれないので注意

以前はNOOBSでインストールしていたけど
最近では
Raspberry Pi Imager
を使うのが主流らしい
https://www.raspberrypi.org/software/
から各種OSに対応したものがダウンロード可能

今回は Ubuntu for x86 をダウンロード

UbuntuでのRaspberry Pi Imagerの使い方

で解説があるので
snap でもインストール可能らしい

今回は
パッケージ版をインストール

途中に必要なパッケージがないとエラーになるうえ
各種インストールしようとしてもエラーとなるため

sudo snap install rpi-imager

でインストール

これで
Imager を起動し
CHOOSE OS

Raspberry Pi OS(32-bit)
をクリックし

CHOOSE STORAGE

SD_MMC – 31.3GB
を選択

これで
WRITE
で書き込みされる
と思ったら
Cannot open storage device ‘/dev/sdc’
となる

他のmicroSD に変えても結果は同じなので

rpi image 1.6 cannot open storage device
で検索し

Raspberry Pi Imager update to v1.6

を参考に

Ctrl-Shift-X
でオプションをだしたがわからないので
NOOBSでインストールすることに
Raspberry PIのインストール方法が変わりNOOBSが使えない – 直接ダウンロードしてインストールする方法

を参考に
http://downloads.raspberrypi.org/
から
NOOBSを直接ダウンロード

http://downloads.raspberrypi.org/NOOBS/images/
からNOOBSのバージョンを選んでダウンロード可能

今回は
NOOBS_v3_7_0.zip
をダウンロード

ダウンロード完了後

unzip NOOBS_v3_7_0.zip -d /media/snowpool/0C12-788A/


microSD を指定して解凍する

次に
ラズパイゼロの準備

カメラモジュールの配線が長すぎるので
Raspberry Pi Zero Wにカメラモジュールを取り付ける

を参考に交換

部品をセットしたら
microSD を差し込んで起動するとインストール画面になるので
そのまま続ける

インストール完了したら
カメラモジュールとSSHができるように設定

sudo raspi-config


Interfacing opinion

PI Camera
P2 SSH
でyes を選ぶ

設定が終われば
Finishを選べばok

これで再起動するとカメラとSSHが使えるようになったので
ssh で ubuntu からアクセスして操作する

次にOS のアップデート

sudo apt update
sudo apt upgrade

実行すると

webkit2gtk (2.31.1-1) experimental; urgency=medium

  Starting from the 2.31.x development versions, support for NPAPI
  plugins has been completely removed from WebKitGTK. This technology is
  deprecated and has already been removed from all major web browsers.

  The last important user of this API was the Adobe Flash Player, which
  reached end of life in December 2020.

 -- Alberto Garcia <berto@igalia.com>  Fri, 15 Jan 2021 17:31:53 +0100

とでるので
とりあえず
q を押して終了させる

アップデートにかなり時間がかかる
約30分以上はかかったので
更新は時間があるときに行わないときついかも

アップデート完了したら
カメラが撮影できるかテスト

これは
raspistill コマンドでできる

オプションが色々あるけと
カメラの向きが変わってることが多々あるので
-o で出力先の変更以外に
-hf で垂直方向へ反転させたり
-hv で水平方向へ反転させることがある

とりあえず、向きに問題ないなら

raspistill -o test.jpg

撮影には5秒ほどのタイムラグがあるので注意

もし撮影できていないのなら
カメラケーブルを確認するといいかも

次に公開鍵認証にする

Ubuntu で ssh-keygenコマンドで作成

-t で暗号形式を rsa
-b で4096ビットに指定
なおデフォルトでは2048ビット

ssh-keygen -t rsa -b 4096

で作成

Enter file in which to save the key (/home/snowpool/.ssh/id_rsa): 

となったらファイル名を入力

今回は zero_camera
としておく

パスフレーズは省略するので

Enter passphrase (empty for no passphrase): 

Enter same passphrase again: 


Enter にすればパスフレーズなしとなる

次に公開鍵の登録

これは
ssh-copy-id コマンドを使う

なお接続するラズパイ3のIPは
Android ならFing で調べることが可能

ssh-copy-id -i zero_camera.pub pi@192.168.1.215

で登録

しかし

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Received disconnect from 192.168.1.215 port 22:2: Too many authentication failures
packet_write_wait: Connection to 192.168.1.215 port 22: Broken pipe

となる

このため
SSH 接続時に Too many authentication failures と表示される。
https://ez-net.jp/article/08/rJIOlRVJ/p56Xn7J2TJ13/
を参考に設定したがつながらない

Received disconnect from … : Too many authentication failures の解決案

を参考に
IdentitiesOnly=yesを指定すると解決

ssh -o IdentitiesOnly=yes pi@192.168.1.215

これでログインはできた

scp -o IdentitiesOnly=yes  .ssh/zero_camera.pub pi@192.168.1.215:/home/pi/

で作成したファイルをコピー

ssh -o IdentitiesOnly=yes pi@192.168.1.215

でラズパイにログイン

cat zero_camera.pub >> .ssh/authorized_keys
chmod 700 .ssh/
chmod 600 .ssh/authorized_keys 


一度ログアウトし

ssh -i .ssh/zero_camera pi@192.168.1.215


公開鍵認証でログインできるのを確認

sudo apt install vim


vim をインストール

sudo vim /etc/ssh/sshd_config

で設定ファイルを開き

パスワード認証を禁止

PermitEmptyPasswords no
PasswordAuthentication no

AuthorizedKeyFile .ssh/authorized_keys

を設定

sudo /usr/sbin/sshd -t

で設定の確認

sudo /etc/init.d/ssh restart


ssh の再起動

これで
次に Google Drive の設定

Google Drive のマウントに必要なものをインストール

sudo apt install opam
opam init
Do you want opam to modify ~/.profile? [N/y/f]

とでてくるので検索
opamを用いたOCamlプロジェクトのセットアップ方法

によれば
yでOK

A hook can be added to opam's init scripts to ensure that the shell remains in
sync with the opam environment when they are loaded. Set that up? [y/N] 

についても
yでOK

これは opam 設定を 更新するスクリプトをなにかに hook させるか
ということらしい

しかし

[ERROR] Solver failed: "/usr/bin/mccs -i
        /tmp/opam-pi-3186/solver-in-3186-8b8a2d -o
        /tmp/opam-pi-3186/solver-out-3186-d474c2
        -lexagregate[-removed,-count[version-lag:,true],-changed,-count[version-lag:,false],-new]"
        exited with code 255 "ERROR: Cannot read solution from lp solver."
Switch initialisation failed: clean up? ('n' will leave the switch partially
installed) [Y/n] y

となる

続いて

opam update
opam install depext

を実行すると

[ERROR] No switch is currently set. Please use 'opam switch' to set or install
        a switch

となる

OCaml の環境構築

によれば
OPAMがおかしくなったら、 ~/.opam を削除すれば初期化できる
とのことなので

rm -rf .opam/

で一度削除

opam init --solver=mccs

を実行

Do you want opam to modify ~/.profile? [N/y/f]
(default is 'no', use 'f' to choose a different file) no
A hook can be added to opam's init scripts to ensure that the shell remains in
sync with the opam environment when they are loaded. Set that up? [y/N] N

については
デフォルトが N なので
N
にしてみたが変わらないので
一度


<><> Required setup - please read <><><><><><><><><><><><><><><><><><><><><><><>

  In normal operation, opam only alters files within ~/.opam.

  However, to best integrate with your system, some environment variables
  should be set. If you allow it to, this initialisation step will update
  your bash configuration by adding the following line to ~/.profile:

    test -r /home/pi/.opam/opam-init/init.sh && . /home/pi/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true

  Otherwise, every time you want to access your opam installation, you will
  need to run:

    eval $(opam env)

  You can always re-run this setup with 'opam init' later.

Do you want opam to modify ~/.profile? [N/y/f]

で再度 y を選択

最後に

User configuration:
  ~/.profile is already up-to-date.
[NOTE] Make sure that ~/.profile is well sourced in your ~/.bashrc.

となるので

source .bashrc 

を実行

インストールしたOCamlをパスに加えるので

 eval $(opam env)

opam switch list-available

で利用可能なあっケージを調べる

Official release が公式らしい

ocaml-base-compiler                    4.12.0
          Official release 4.12.0
ocaml-variants                         4.12.0+domains
          OCaml 4.12.0, with support for multicore domains
ocaml-variants                         4.12.0+domains+effects
          OCaml 4.12.0, with support for multicore domains and effects
ocaml-variants                         4.12.0+options
          Official release of OCaml 4.12.0
ocaml-variants                         4.12.1+trunk
          Latest 4.12 development
ocaml-base-compiler                    4.13.0~alpha1
          First alpha release of OCaml 4.13.0
ocaml-variants                         4.13.0~alpha1+options
          First alpha release of OCaml 4.13.0
ocaml-base-compiler                    4.13.0~alpha2
          Second alpha release of OCaml 4.13.0
ocaml-variants                         4.13.0~alpha2+options
          Second alpha release of OCaml 4.13.0
ocaml-variants                         4.13.0+trunk
          Latest 4.13 developmet
ocaml-variants                         4.14.0+trunk
          Current trunk

となるので

 opam switch create 4.12.0

としたが

[ERROR] ocaml-base-compiler = 4.12.0 unknown package

となる

OCamlについてとりあえずメモ

を参考に

sudo apt install opam ocaml gcc make bubblewrap m4 pkg-config

をしたが変わらない

再度

rm -rf .opam

で削除し

<><> Creating initial switch (ocaml-system>=4.02.3) <><><><><><><><><><><><><><>
[ERROR] Solver failed: "/usr/bin/mccs -i
        /tmp/opam-pi-1045/solver-in-1045-8b8a2d -o
        /tmp/opam-pi-1045/solver-out-1045-d474c2
        -lexagregate[-removed,-count[version-lag:,true],-changed,-count[version-lag:,false],-new]"
        exited with code 255 "ERROR: Cannot read solution from lp solver."
Switch initialisation failed: clean up? ('n' will leave the switch partially
installed) [Y/n] y

となったので

opam init --solver=mccs

を実行

しかし
同じエラーがでる

再度

Do you want opam to modify ~/.bash_profile? [N/y/f]

のとき
N
を選択し

A hook can be added to opam's init scripts to ensure that the shell remains in
sync with the opam environment when they are loaded. Set that up? [y/N] N

もN
とした

[ERROR] Solver failed: "/usr/bin/mccs -i
        /tmp/opam-pi-1326/solver-in-1326-8b8a2d -o
        /tmp/opam-pi-1326/solver-out-1326-d474c2
        -lexagregate[-removed,-count[version-lag:,true],-changed,-count[version-lag:,false],-new]"
        exited with code 255 "ERROR: Cannot read solution from lp solver."
Switch initialisation failed: clean up? ('n' will leave the switch partially
installed) [Y/n] 

のときに
Y
とした後に

opam update

を実行

このあと

opam install depext

を実行したが

[ERROR] No switch is currently set. Please use 'opam switch' to set or install
        a switch

となる

opam switch create 4.12.0

を実行すると

[ERROR] Solver failed: "/usr/bin/mccs -i
        /home/pi/.opam/log/solver-in-1418-7afd23 -o
        /home/pi/.opam/log/solver-out-1418-5f1023
        -lexagregate[-removed,-count[version-lag:,true],-changed,-count[version-lag:,false],-new]"
        exited with code 255 "ERROR: Cannot read solution from lp solver."
Switch initialisation failed: clean up? ('n' will leave the switch partially
installed) [Y/n] Y

となる

エラーログから

Please use 'opam switch' to set or install         a switch

とあったので検索
opam not creating a switch #4023

の中の

There is some packaging issues of opam (cf. #3827), it should use builtin solver, but it packaged with aspcud.

Can you try this workaround ?

を参考に

aspcud install

で検索

How To Install “aspcud” Package on Ubuntu

を参考に

sudo apt install aspcud 

でインストール

debian testing/ubuntu disco opam packages result in solver failure on init

を参考に

opam switch create 4.12.0 --solver=mccs

としたが変わらない

このため一度以前作成したラズパイゼロとの
バージョン差分を調べることにする

opam --version 

で調べた結果
2.0.3
に対し

以前作成したものは
ver 1.2.2
だった

このため一度 Google Drive への保存を保留にして
先に Bluetooth ボタンでシャットダウン機能の実装とOpenCVを先に実験する

今回作成するものは車で走行しているときの動画の保存と解析が目的
なので
古い写真と動画を圧縮保存するようにして
自宅に帰ったときにNASに保存するようにする

まず bluetooth の設定

sudo apt install bluez bluetooth libbluetooth-dev build-essential
sudo apt install bluez-cups

で必要なパッケージのインストール

次にgem でインストール

sudo apt install ruby
sudo gem install bluebutton

これはダイソーの300円のボタンを使う

sudo bluetoothctl
power on
scan on 


MACアドレスを表示されたら

connect FF:FF:9A:4A:49:94
pair FF:FF:9A:4A:49:94
trust FF:FF:9A:4A:49:94

とする

しかし電池が少ないため途中で接続が途切れる

このため先に opencv の設定をする

【Raspberry Pi】Raspberry Pi Zero WにOpenCVの環境を構築する

sudo apt-get install python3-pip
sudo apt-get install libatlas-base-dev
sudo apt-get install libjasper-dev
sudo apt-get install qt4-dev-tools qt4-doc qt4-qtconfig libqt4-test
pip3 install opencv-python

これでpython3 の後に

import cv2 

とすると

Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/.local/lib/python3.7/site-packages/cv2/__init__.py", line 5, in <module>
    from .cv2 import *
ImportError: numpy.core.multiarray failed to import

となる

このため
import cv2 で謎の”ImportError”が出た…[OpenCV for Python3]

を参考に

pip install -U numpy

インストールはできたようだが

  The scripts f2py, f2py2 and f2py2.7 are installed in '/home/pi/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

とエラーがでる

  The scripts f2py, f2py2 and f2py2.7 are installed in '/home/pi/.local/bin' which is not on PATH.


検索した結果
NumPy、pandas、Matplotlib をpipでインストールする方法

によれば
f2pyは
FORTRANのコードをPythonで使えるようにするプログラム

警告内容のようにPATHを通さなくても

py -m numpy.f2py

で呼び出せるらしいので
そのまますすめる

この状態で

import cv2

として何もエラーがでなければ成功

バージョン確認は

cv2.__version__

でOK

ctrl + d で抜ける

とりあえず
opencv の設定はできたので
次に定期的にカメラで動画撮影する

動画の撮影は
raspivid コマンド
もしくは
motion コマンド
でできる

motion の場合動体検知などができるが
今回は raspivid コマンドで実行する

出力されるファイル形式は
.h264 になる

-t でミリ秒単位で撮影時間を指定できる
なおミリ秒は0.001 秒なので
10000ミリ秒なら10秒となる

-rot で角度の指定が可能
180度回転させるなら
-rot 180
となる

カメラの向きが上下反転しているなら
-vf

左右反転なら
-hf
を指定することで解決

これについては

Raspberry Pi Zeroで簡易ドライブレコーダーを自作する

を参考に

取り付ける場所がルームミラーの裏にしたいので
横向きになるので

raspivid -o test.h264 -rot 270 -t 10000

とすることで角度調整ができた

次に
-fps でフレームノート
-b でビットレートを指定する

ファイル名がかぶらないように
date コマンドで日時を撮影した日時にして保存する

raspivid -o `date '+%Y%m%d-%H%M'`.h264 \
-rot 270 -w 1280 -h 720 -t 20000 -fps 30 -b 2000000

これをスクリプトファイルにするので

vim video.sh

でファイルを作成し

#!/bin/sh
raspivid -o `date '+%Y%m%d-%H%M'`.h264 \
-rot 270 -w 1280 -h 720 -t 20000 -fps 30 -b 2000000

として保存

なお

 `date '+%Y%m%d-%H%M'

はバッククォートで囲っている
shift + @ でバッククォートになる

‘ と似ているので注意

chmod +x video.sh

で実行権限を付与

これを cron で実行できるようにする

crontab -e

を実行

no crontab for pi - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

となりどのエディタを使うか聞かれる
今回はvim にしたいので
2
を選択

最終行に

*/1 * * * * /home/pi/video.sh

を追記して保存

これで1分ごとに20秒の動画が撮影される

このままだとどんどんファイルが増えていくので

mkdir drive_rec

で動画を保存するディレクトリを作成

#!/bin/sh
raspivid -o /home/pi/drive_rec/`date '+%Y%m%d-%H%M'`.h264 \
-rot 270 -w 1280 -h 720 -t 20000 -fps 30 -b 2000000

というように保存先を指定

今まで撮影したファイルについては

mv *.h264 drive_rec/

で一緒に保存しておく

これで一日おいておいたらすごい量のファイルになっているので
シャットダウンボタンを設定する

sudo pip3 install evdev


キーイベント取得のためのモジュールインストール

あと
100均Bluetoothボタンをラズパイ活用


別の機器(ラズパイやスマホ)に繋ぐ場合は、最後に繋げた機器とペアリングを確実に削除すること(デバイスの電源OFFや電池を抜いてもダメ)
とあったので
新規に電池とともに
ダイソーで購入することに

一日たってから

df -h

で容量を確認したところ
5GBほど容量をとりほぼ夜中は起動しても無駄になりそうなので
motion で撮影することに

これなら動体検知になるのでそこまで容量をとらないはず

 sudo nano /etc/modules

でファイルを開き

bcm2835-v4l2

を最終行に追記

あとは

sudo reboot

で再起動

次に motion のインストール

sudo apt update

でリポジトリを更新し

sudo apt install -y motion

で motion をインストール

次に設定ファイルの編集

sudo vim /etc/motion/motion.conf 

で設定ファイルを開き

11行めの

daemon off

daemon on

に変更

79行目あたりの

width 320 

width 640 

に変更

height 240

height 480

に変更

86行目あたりの

framerate 2

framerate 10

に変更
framerateは
動体を検知した時に画像をキャプチャするフレームレートの最大値
大きくするとCPU負荷も上がるが
動きがなめらかになる

233行目あたりの

event_gap 60

event_gap 10

に変更
eventgap は
動体検知が収まってから再度検知するまでの秒

461行めの

stream_localhost on

stream_localhost off

に変更
stream_localhost は
ライブストリームへのアクセスをローカルホストからのみに制限する
on だとローカルホストのみ

次に撮影関連の設定
デフォルトだと撮影時間が無制限なので
237行目の

max_movie_time 0

から任意の撮影秒数に変更

今回は20秒に設定

max_movie_time 20

とした

これで保存

そして、自動的に motion を起動できるようにしたいので

sudo nano /etc/default/motion 

でファイルを開き

start_motion_daemon=no

start_motion_daemon=yes

として保存

次に insserv パッケージをインストール

 sudo apt install insserv

あとは

sudo insserv motion

これで自動起動設定も完了

もし、自動起動していないのなら

sudo motion

で motion を起動

しかしうまく起動していないため
深夜での撮影はしないため
撮影する時刻を
朝5時から夜9時までに変更するため

crontab -e

*/1 * * * * /home/pi/video.sh

*/1 5-21 * * * /home/pi/video.sh

として保存

設定は左から
分 時 日 月 曜日
となっている

書き方については
crontabの書き方

を参考に

次に古いファイルの削除

基本的に週1でデータ管理しようと思うので
それ以前のデータは削除するようにする

Raspberry Pi で監視カメラを作ってみた

を参考にスクリプトを設定

sudo vim /etc/cron.daily/delete_movie.sh

内容を

#!/bin/bash
find ~/drive_rec/ \( -name '*.h264' \) -mtime +7 -delete 
exit 0

として保存

sudo chmod +x /etc/cron.daily/delete_movie.sh 

で実行権限付与

これで7日間変更がないなら削除されるようになる

ボタン電池を購入したのでbluetooth ボタンの続き

簡易ドライブレコーダーZeroWにBluetoothボタンでオンオフ編

を参考に

sudo apt install bluez bluetooth libbluetooth-dev build-essential
sudo apt install bluez-cups

これで

vim shutdown.sh

でファイルを作成

#!/bin/bash
sudo shutdown -h now

として保存

sudo chmod +x shutdown.sh 

で実行権限付与

sudo vim ~/.config/bluebutton

で内容を

keyup=echo UP && ~/shutdown.sh
keydown=echo DOWN
longup=echo LONG UP
longdown=echo LONG DOWN

として保存

sudo bluebutton -c ~/.config/bluebutton

だと

sh: 1: /root/shutdown.sh: not found

となってしまうが

bluebutton -d="AB Shutter3" -c /home/pi/.config/bluebutton

として
ボタンを押すと無事にシャットダウンができた

このままだと使えないので
起動したら
bluetooth が使えるように設定

Crontabにシステム起動時に1度だけコマンドが実行されるように設定する方法

によれば

@reboot
で設定ができるらしい
Shutter3とRaspberry Pi Zero Wを使ったBluetoothボタンの制御まとめ

で書いてあったものを参考に

vim blbtn.sh

#!/bin/sh
command="bluebutton -d="AB Shutter3" -c /home/pi/.config/bluebutton"
eval $command

として保存

chmod +x blbtn.sh

で実行権限付与

crontab -e

で最終行に

@reboot /home/pi/blbtn.sh

を記述して保存

実際に起動しているか調べるため再起動

しかし動作しないためこれは保留
100均のBluetoothシャッターとRaspberry Piカメラでオンラインデジカメを作ってみた

を参考に

sudo vim ~/.config/bluebutton 

でファイルを編集

内容を

keyup=echo UP ; ~/shutdown.sh
keydown=echo SHUTDOWN 
longup=echo LONG UP
longdown=echo LONG DOWN

として保存

 which bluebutton 


bluebutton のパスを確認したら

/usr/local/bin/bluebutton

だったので

crohtab -e

で設定ファイルを開き

@reboot /home/pi/blbtn.sh

を削除

@reboot /usr/local/bin/bluebutton -d="AB Shutter3" -c /home/pi/.config/bluebutton

を最終行に追記

これで

sudo reboot

で再起動させて
しらばくたってから
AB Shutter3
のボタンを押すとシャットダウンが実行される

なお端末画面には
ECHO で設定した画面が表示されないので注意

またすでに他のラズパイzero で実験している場合
一度ペアリングを解除しないと他の端末で使えないので注意

bluetoothctl

でペアリング解除などが載っているので参考に

python で今日の日付を dd/mm/YY で取得 その2

python で今日の日付を dd/mm/YY で取得 その2

ほとんどの場合は
yymmdd だけど
investpy で指定するときに
ddmmyy で期間を取得することになる

今日の日付を[yyyymmdd]形式の文字列で取得する。

今日の日付を[yyyymmdd]形式の文字列で取得する。【Python】


を参考に

today =datetime.date.today().strftime('%Y%d%m')
today

とすると

‘20210409’

となる

today =datetime.date.today().strftime('%d/%m/%Y')
today

とすれば

’04/09/2021′

となる

【Python】investpyを使ったInvesting.comからのデータ取得方法

【Python】investpyを使ったInvesting.comからのデータ取得方法



経済指標カレンダーも investpy で取得可能

calendar = investpy.news.economic_calendar(from_date='01/01/2021',to_date=today,
                                           countries=['united states','germany','japan'])
# countriesでの国指定は省略可能。

# 重要度の高・中度の予定
important = investpy.news.economic_calendar(from_date='01/01/2021',to_date=today,
                                            countries=['united states'],importances=['high','medium'])

で取得ができる

あとは
important

calendar
で表示ができるけど

日時を毎回直接打つのはミスするので別の方法で取得

Pythonで翌日や翌月みたいな日付の計算をする

Pythonで今月、前月、来月、昨年、毎月あたりを取得する

を参考に今月と月末を取得して指定するようにする

from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta

で必要なライブラリをインポート

# 月初(今月の1日にする)
first_day = (datetime.today() + relativedelta(day=1)).strftime('%d/%m/%Y')
# 月末 (来月の1日に合わせて1日分戻る)
last_day = (datetime.today() + relativedelta(months=+1,day=1,days=-1)).strftime('%d/%m/%Y')

# 1週間後
week_later =(datetime.today() + relativedelta(weeks=+1)).strftime('%d/%m/%Y')


月末、月始の日付が取得できる

あとは

# 今月の重要度の高・中度の予定
important = investpy.news.economic_calendar(from_date=first_day,to_date=last_day,
                                            countries=['united states'],importances=['high','medium'])


# 1週間の重要度の高・中度の予定
important = investpy.news.economic_calendar(from_date=today,to_date=week_later,
                                            countries=['united states'],importances=['high','medium'])

で指定して
経済指標カレンダーの取得が可能になる

python で今日の日付を dd/mm/YY で取得

python で今日の日付を dd/mm/YY で取得

ほとんどの場合は
yymmdd だけど
investpy で指定するときに
ddmmyy で期間を取得することになる

今日の日付を[yyyymmdd]形式の文字列で取得する。

を参考に

today =datetime.date.today().strftime('%Y%d%m')
today

とすると

‘20210409’

となる

today =datetime.date.today().strftime('%d/%m/%Y')
today

とすれば

’04/09/2021′

となる

あとは経済指標の取得期間を

economic_data = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date=today)

というように

to_date=
で指定する部分を today などの取得した変数にすればOK

経済指標グラフを altair で表示 その2

経済指標グラフを altair で表示 その2

investpy で経済指標を取得し
altair で表示する

import pandas as pd
import investpy
import altair as alt
import datetime

economic_data = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date='11/06/2021')

ISM =economic_data[economic_data['event'].str.contains('ISM Non-Manufacturing PMI')]

date2 =[]
for i in ISM['date']:
    new_date = datetime.datetime.strptime(i,"%d/%m/%Y").strftime("%Y-%m-%d")
    date2.append(new_date)

ISM['date']=ISM['date'].str.replace('/','-')
ISM['date'] = date2
ISM.fillna(0)

chart =(
    alt.Chart(ISM)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="date:T",
        y=alt.Y("actual:Q",stack=None)
    )
)

chart

とすると
ISM の actual の数値が折れ線グラフで表示される

実際の値だけでなく予測値の forecast もほしいので

actual =(
    alt.Chart(ISM)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="date:T",
        y=alt.Y("actual:Q",stack=None)
    )
)

forecast =(
    alt.Chart(ISM)
    .mark_line(opacity=0.8,clip=True,color='red')
    .encode(
        x="date:T",
        y=alt.Y("forecast:Q",stack=None),       
    )
)

として2つの折れ線データを用意する

あとは
alt.layer で重ねて表示すると2つ表示される

alt.layer(actual,forecast).resolve_scale(
    y = 'independent'
)

independent を指定するとy軸が独立した2つになる

なお重ねて表示するのは3つでも可能

試しに previous の値も追加するのなら

previous =(
    alt.Chart(ISM)
    .mark_line(opacity=0.8,clip=True,color='green')
    .encode(
        x="date:T",
        y=alt.Y("previous:Q",stack=None),       
    )
)

alt.layer(actual,forecast,previous).resolve_scale(
    y = 'independent'
)

とすれば3つの折れ線グラフが表示される

重ねて折れ線グラフを表示するのについては
Layered chart with Dual-Axis

を参考に

altair で線の色を指定するには
altairでとあるアイドルグループのメンバー在籍期間のチャート化してみた

を参考に

最初に
altair.encode() で指定したときにはエラーとなった

color=
で指定するとラベル指定となってしまうらしい

経済指標グラフの日付問題

経済指標グラフの日付問題

形式が
dd/mm/yy
となっているので
altairで表示が月と間違えて表示される

月の表示を英語にすればいけるかもしれない

株価可視化複数アプリでそうしたので

import pandas as pd
import investpy
import altair as alt

economic_data = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date='11/06/2021')

economic_data2 = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date='31/01/2021')

ISM =economic_data[economic_data['event'].str.contains('ISM Non-Manufacturing PMI')]

chart =(
    alt.Chart(ISM)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="date:T",
        y=alt.Y("actual:Q",stack=None)
    )
)
chart

これだと
dd/mm/yy
の mm 部分を日付と間違えるようだ

インタラクティブなデータの視覚化

をみたところ
プロット
のところで
プロットに使用する列が正しいデータ型であり、日付が(YYYY-MM-DD)の形式であることを確認しました。そのために、高価格列と低価格列をdoubleデータ型に変換し、日付列を文字列形式に変換しました。続いて、日付列をDD / MM / YYYY形式からYYYY / MM / DDに変換し、最後にYYYY-MM-DDに変換しました。
をみて

import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True)
import plotly.plotly as py
import plotly
import pandas as pd
import datetime

df = pd.read_csv("TSLA.csv")

df['date'] = df['date'].astype('str') 
df['high'] = df['high'].astype('double')
df['low'] = df['low'].astype('double') 

date2 = []
for i in df['date']:
    new_date = datetime.datetime.strptime(i, "%d/%m/%Y").strftime("%Y-%m-%d")
    date2.append(new_date)
    
df['date'] = df['date'].str.replace('/', '-')
df['date'] = date2
df.fillna(0)
df.head()

のうち

df = pd.read_csv("TSLA.csv")

df['date'] = df['date'].astype('str') 
df['high'] = df['high'].astype('double')
df['low'] = df['low'].astype('double') 

date2 = []
for i in df['date']:
    new_date = datetime.datetime.strptime(i, "%d/%m/%Y").strftime("%Y-%m-%d")
    date2.append(new_date)
    
df['date'] = df['date'].str.replace('/', '-')
df['date'] = date2
df.fillna(0)
df.head()

をみたところ
date の部分をループさせて
date2 に格納
date の値を date2 に書き換えて
df.fillna で反映しているみたいだ

df.fillna は欠損値の置き換えらしい

とりあえず実験

date2 =[]
for i in ISM['date']:
    new_date = datetime.datetime.strptime(i,"%d/%m/%Y").strftime("%Y-%m-%d")
    date2.append(new_date)

とすれば

date2 に

['2021-01-08',
 '2021-02-04',
 '2021-03-04',
 '2021-04-05',
 '2021-05-05',
 '2021-06-03']

と格納される

あとは代入すればいけると思って

ISM['date']=ISM['date'].str.replace('/','-')
ISM['date'] = date2
ISM.fillna(0)

としたら

<ipython-input-15-e3cb61543e3a>:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  ISM['date']=ISM['date'].str.replace('/','-')
<ipython-input-15-e3cb61543e3a>:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  ISM['date'] = date2

と警告がでる

これで

chart

とすればいちおう望み通りのグラフにはなる

エラーを

<ipython-input-15-e3cb61543e3a>:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

で検索してみたら
pandas の SettingWithCopyWarning で苦労した話

にその原因っぽいのが乗っていた

元のデータの一部を抽出→そのうち一部へ代入した場合、「元のデータのその部分」を修正したかったのか、「一部を変更した新しいデータ」を作りたかったのかどっちかわからないよ、という感じ
らしい

PandasのSettingWithCopyWarningに対する対処方法

も参考にしてみた

view か copy かを明確にしないとダメで
copy なら元の DataFrane は変更されない
view だと元まで変更となる

python で経済指標の取得とグラフ化その2

python で経済指標の取得とグラフ化その2

ISM Manufacturing PMI
ISM製造業PMI

altair でグラフにする

economic_data[economic_data['event'].str.contains('ISM Non-Manufacturing PMI')]

で結果の取得はできた

以前
apple の情報を取得し
そこから特定のカラムの Close だけ取り出したことがあるので

economic_data[economic_data['event'].str.contains('ISM Non-Manufacturing PMI')]['actual']

とすると

99      57.2
535     58.7
1016    55.3
1566    63.7
2027    62.7
2540    64.0
Name: actual, dtype: object

となり
ID と actual の数値がでる

ただし

chart =(
    alt.Chart(ISM)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="Date:T",
        y=alt.Y("Stock Prices(USD):Q",stack=None),
        color='Name:N'
    )
)
chart

としてもエラーになる

ISM.dtype

を実行すると

dtype('O')

となる

検索して調べてみた
dtype( ‘O’)とは何ですか?

によれば
python object
とのこと

なので数値にしないとダメ
おそらくやり方が違っているので
株価可視化アプリでやったことを思い出す

economic_data.columns

でカラムを調べると

Index(['id', 'date', 'time', 'zone', 'currency', 'importance', 'event',
       'actual', 'forecast', 'previous'],
      dtype='object')

となる

過去に apple の株価取得したときには

Index(['Open', 'High', 'Low', 'Close', 'Volume', 'Dividends', 'Stock Splits'], dtype='object')

だった

今回は指標を絞ってみる

ISM =economic_data[economic_data['event'].str.contains('ISM Non-Manufacturing PMI')]
ISM.columns

とすると

Index(['id', 'date', 'time', 'zone', 'currency', 'importance', 'event',
       'actual', 'forecast', 'previous'],
      dtype='object')

となる
あまり変わっていない

ISM.reset_index()

でインデックスを振りなおしてみる

ism_act = ISM[['actual']]
ism_act


actual へ絞り込みができた

ただし、そのまま

chart =(
    alt.Chart(ism_act)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="Date:T",
        y=alt.Y("Stock Prices(USD):Q",stack=None)
    )
)

としても日付がないので表示できない

pandas.DataFrameから条件を満たす行名・列名の行・列を抽出(選択)

を参考に

ism_act = ISM.filter(items=['date','actual'])
ism_act

とすれば日付も取得できる

chart =(
    alt.Chart(ism_act)
    .mark_line(opacity=0.8,clip=True)
    .encode(
        x="date:T",
        y=alt.Y("actual:Q",stack=None)
    )
)

ででたけど
表示がおかしい

原因は日付表示

99 	08/01/2021 	57.2
535 	04/02/2021 	58.7
1016 	04/03/2021 	55.3
1566 	05/04/2021 	63.7
2027 	05/05/2021 	62.7
2540 	03/06/2021 	64.0

の場合日付を月と認識されるので
表記を変える必要がある

ism_act.index = ism_act.index.strftime('%d %B %Y')

としたが

AttributeError: 'Int64Index' object has no attribute 'strftime'

となる

[Python]pandasの日付データから年、月、日、曜日への変換方法

を参考に

ism_act['date'] = pd.to_datetime(ism_act['date'],format='%Y-%m-%d')

としたがエラー
Pandasデータフレームを日付で並べ替え

を参考に

ism_act['date']=pd.to_datetime(ism_act.date)
ism_act.sort_values(by='date')

とすれば
ソートはできるが日付フォーマットを修正しないとバグる

df_ism_act = pd.DataFrame(ism_act)


Dataframe にしてみたが
おそらく株価アプリのときみたいに
DatetimeIndex を作成したほうがいいかもしれない

ism_act['date']=pd.to_datetime(ism_act['date'], format='%Y%m%d')
ism_act.sort_values(by='date')

だと
08/01/2021
を8/1
として認識して変換している

python で経済指標の取得とグラフ化

python で経済指標の取得とグラフ化

経済指標を取得しグラフ化することで
ニュース発表時の期待値との乖離を理解しやすくなる

まずは経済指標の値を取得

できればあとは
dow index
gold
WTI
なども取得できるようにする

jupyter-notebook
で実験をしてそれから
streamlit で表示
というコンセプトで

FXで重要な経済指標をWebスクレイピングで取得する方法

[Python]investpyで株、為替、経済指標データを取得する

を参考に

investpy
をインストール

!pip install investpy


jupyter notebook でインストールできる

investpyで世界の株価データを取得してみた

も参考に

import pandas as pd
import investpy

で必要なライブラリをインポート

code = '7203' #トヨタ自動車
stock_data = investpy.get_stock_historical_data(stock=code, country='japan', from_date='01/02/2021', to_date='28/03/2021')
stock_data.tail(5)

とすると

2021/2/1 から 2021/3/28
までのトヨタ自動車の株価を取得して表示できる

investpy.get_stock_historical_data


企業シンボルを stock=
国を country=
期間を from_date=, to_date
で指定する

これを APPle にするなら

symbol = "AAPL" #アップル
stock_data = investpy.get_stock_historical_data(stock=symbol, country='united states', from_date='01/02/2021', to_date='28/03/2021')
stock_data.tail(5)

とすればOK

違いはstock= を symbol にして

contury= を united states

にしていること

なお指定期間の為替の取得も可能

usd_jpy = investpy.get_currency_cross_historical_data(currency_cross='USD/JPY', from_date='01/02/2021', to_date='28/03/2021')
usd_jpy.tail(5)


from_date と to_date
で指定した期間の為替情報を

get_currency_cross_historical_data()

で取得している

currency_cross= で通過ペアの指定をしている

次に経済指標

investpy.economic_calendar

で各国の経済指標を得ることができる

economic_data = investpy.economic_calendar(time_zone='GMP +9:00', countries=['japan', 'united states'], from_date='01/02/2021', to_date='28/03/2021')
economic_data.tail(5)

だと

ValueError                                Traceback (most recent call last)
<ipython-input-16-10b765be85cc> in <module>
----> 1 economic_data = investpy.economic_calendar(time_zone='GMP +9:00', countries=['japan', 'united states'], from_date='01/02/2021', to_date='28/03/2021')
      2 economic_data.tail(5)

~/anaconda3/lib/python3.8/site-packages/investpy/news.py in economic_calendar(time_zone, time_filter, countries, importances, categories, from_date, to_date)
     80     else:
     81         if time_zone not in cst.TIMEZONES.keys():
---> 82             raise ValueError("ERR#0108: the introduced time_zone does not exist, please consider passing time_zone as None.")
     83 
     84     if not isinstance(time_filter, str):

ValueError: ERR#0108: the introduced time_zone does not exist, please consider passing time_zone as None.

となる

github で調べたら
https://github.com/alvarobartt/investpy/search?q=economic_calendar
にあるように

def economic_calendar(time_zone=None, time_filter='time_only', countries=None, importances=None, categories=None, from_date=None, to_date=None):

と定義されている

さらに詳細を
https://github.com/alvarobartt/investpy/blob/f7f43c4458a155237321528c9a46e2aa4a3e824d/investpy/news.py
で確認

        time_zone (:obj:`str`, optional): 
            time zone in GMT +/- hours:minutes format, which will be the reference time, if None, the local GMT time zone will be used.
        time_filter (:obj:`str`, optional):
            it can be `time_only` or `time_remain`, so that the calendar will display the time when the event will occurr according to 
            the time zone or the remaining time until an event occurs.

とあるので約してみると

time_zone(:obj: `str`、オプション):
GMT +/-時間:分形式のタイムゾーン。これが参照時間になります。[なし]の場合、ローカルGMTタイムゾーンが使用されます。
time_filter(:obj: `str`、オプション):
それは「time_only」または「time_remain」にすることができ、カレンダーはイベントが発生する時間を表示します
タイムゾーンまたはイベントが発生するまでの残り時間。

ということなので

economic_data = investpy.economic_calendar(countries=['japan', 'united states'], from_date='01/02/2021', to_date='28/03/2021')
economic_data.tail(5)

というように
time_zone を省略したらできた

次に

economic_data[economic_data['importance']=='high']

というように
importance カラムが high になっているものだけを抽出すれば
重要指標のみ表示ができる

actual
が実際の値

forecast が予測値
previousが前回の値

つまりこの3つのうち
forecast
previous
でグラフを作成、もしくは該当する経済指標でグラフを作成すればいい

とりあえずグラフにするサンプル
とはいっても株価のだけど
investpyで世界の株価データを取得してみた

で日立製作所の株価データをグラフにするのがあったので実線

stock = '6501' # Hitachi Ltd
country = 'japan'

stock_df = investpy.get_stock_recent_data(stock=stock, country=country)
stock_df.reset_index(drop=False, inplace=True)
stock_df.head()

ででる

reset_index() のオプションについて調べてみた
Pandas.DataFrameのインデックスをreset_indexメソッドで振り直す

によれば
DataFrameのreset_indexメソッドを使えば、DataFrameの行のindexを簡単に振り直すことができる

ということ

drop=False
については
オリジナルのindexを列として保存しておくならFalse、保存しないならTrue

inplace=True
については
reset_indexを実行したオブジェクト自体を変更する場合はTrue、変更しないのならFalse

つまり reset_index() でインデックス番号が振られるので
head() などで絞り込みができる

あとはグラフにしてみる

from matplotlib import pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns; sns.set()


fig,ax = plt.subplots(figsize=(12,4))
locator = mdates.DayLocator()
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_minor_locator(locator)
ax.xaxis.set_major_formatter(formatter)

sns.lineplot(data=stock_df, x='Date', y='Close')
ax.set_title('Hitachi Ltdt')
plt.show()

でできる

今度は経済指標に戻って
米国原油在庫量であるCrude Oil Inventories
が経済指標にあったので
event からこれを指定する

economic_data = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date='11/06/2021')
economic_data[economic_data['event']=='Crude Oil Inventories']

これで一覧で取得できた
あとは
actual
forecast
previous
の3つをグラフにして
対応する通貨の値動きを追加すれば
どんな値動きをしていたのかがわかる

次に新規失業保険申請件数
これは
Initial Jobless Claims
なので

economic_data[economic_data['event']=='Initial Jobless Claims']

となる

ただし
ISM Non-Manufacturing PMI (Jan)
というように月などが入っていると完全一致しないため
== では判定できない

python 文字列 含む 判定 pandas
で検索し
pandasで特定の文字列を含む行を抽出(完全一致、部分一致)

を参考に特定の文字列で始まるものを試す

str.contains(): 特定の文字列を含む
str.startswith(): 特定の文字列で始まる
があたりっぽい

print(df[df['name'].str.contains('li')])

がサンプル
なので

economic_data[economic_data['event'].str.contains('ISM Non-Manufacturing PMI')]

とすれば

ISM Non-Manufacturing PMI
を含むものを抽出することができるので
月ごとの結果が取得できるようになる

とりあえず取得するべき経済指標に関しては

economic_data2 = investpy.economic_calendar(time_zone=None, time_filter='time_only', countries=['japan', 'united states'], from_date='01/01/2021', to_date='31/01/2021')
economic_data2[economic_data2['importance']=='high']

で1月の重要経済指標を取得し表示

あとはグラフなどにしたい経済指標を絞り込む
英語なので google 翻訳などで調べていくと

ISM Manufacturing PMI
ISM製造業PMI

ADP Nonfarm Employment Change
ADP非農業部門雇用者数

Crude Oil Inventories
米国 原油在庫量

新規失業保険申請件数
これは
Initial Jobless Claims

ISM非製造業指数
ISM Non-Manufacturing PMI

Nonfarm Payrolls
米非農業部門雇用者数

Unemployment Rate
失業率

JOLTs Job Openings
JOLTS求人労働異動調査
つまり求人情報の数

Core CPI
消費者物価指数
正式名称は生鮮食品除く総合指数。生鮮食品とは、生鮮魚介、生鮮野菜、生鮮果物のこと。

Core Retail Sales
米国コア小売売上高前月比

PPI
生産者物価指数
生産者が出荷した製品や原材料などの販売価格の変動を調査・算出した経済指標

Retail Sales
小売売上高
米国の小売・サービス業の月間売上高
インフレと経済活動を評価する

Building Permits
(Building Permits)は、政府や他の規制当局が発行した新施設の建設のための許可数
中期的に不動産市場を予測する

Philadelphia Fed Manufacturing Index
フィラデルフィア連銀製造業景況指数

Existing Home Sale
中古住宅販売件数

CB Consumer Confidence
米国 消費者信頼感指数

Core Durable Goods Orders
コア耐久財受注
報告月の前月と比較した米国耐久財製造業者が受注した受注額を反映します。耐久財とは家具、電気器具などで、3年以上もつことが予想

Fed Interest Rate Decision
FRB政策金利

GDP (QoQ) 
実質GDP

New Home Sales
新築住宅販売戸数

Pending Home Sales
住宅販売契約指数

が重要指標

なお調べるときに
actual が None のものを除外すると見やすいと思うが

economic_data2[economic_data2['actual']=='None']

pandasで複数条件のAND, OR, NOTから行を抽出(選択)

を参考にやったがダメ

Pandasで NaN (Null) の行だけ抽出

を参考に
isnull() で抽出可能になった

python では not は ~ でなり
複数条件にするときには () で条件を囲む

今回
importance==hight
actual が isnull() でないもの
のものを表示するので

economic_data2[~(economic_data2['actual'].isnull()) & (economic_data2['importance']=='high')]

とすればOK

とりあえず経済指標の絞り込みはできるようになったので
次にグラフにする

複数のグラフを表示するには
altair でできたのでこれをつかう

経済指標カレンダーの取得

経済指標カレンダーの取得

FXで重要な経済指標をWebスクレイピングで取得する方法

を参考にみんかぶからスクレイピング

でーたを綺麗にするために
列名を主導で追加
必要の無い列、行を削除

が必要になる

しかし

import pandas as pd

url = 'https://fx.minkabu.jp/indicators' #みんかぶFXの経済指標URLを取得
dfs = pd.read_html(url) #テーブルのオブジェクトを生成

を実行してもリストになってしまう

Pandasで超簡単!WEBスクレイピング(表・htmlのtable取得)

を参考に
read?html に
必要なライブラリ不足かと思い

pip install beautifulsoup4 lxml html5lib

でインストールしてみたが変わらない

BeautifulSoupでテーブルスクレイピング

を参考に

import pandas as pd
url2 = 'https://en.wikipedia.org/wiki/Transistor_count'# 対象のwebページのurl
dfs = pd.read_html(url2)# webページに複数のテーブルがある場合、リスト形式でdfsに格納されます

とすると
webページに複数のテーブルがあるとリストになってしまう

なので

import pandas as pd

url = 'https://fx.minkabu.jp/indicators' #みんかぶFXの経済指標URLを取得
dfs = pd.read_html(url) #テーブルのオブジェクトを生成
dfs[0]

とすればテーブルとして表示できる

よくみたら出力するときに
dfs[0]
で指定していた….

とりあえずこれで当日の経済指標カレンダーは取得できそう

0からカウントされるので
0〜4までで1週間のカレンダー取得ができる

なお変動の pips については
米ドル/円やクロス円(ユーロ/円、ポンド/円など)の場合
1pip=0.01円(1銭)
10 pips=0.1円(10銭)
100 pips=1円(100銭)

米ドルストレート(ユーロ/ドル、ポンド/ドルなど)の場合
1pip=0.0001ドル(0.01セント)
10pip=0.001ドル(0.1セント)
100pip=0.01ドル(1セント)
となっている

これで
streamlit で表示できれば次にループ表示すれば週間カレンダーが表示できる
ので

mkdir fx_tool


作業ディレクトリを作成

使用するエディタは VS Code

cd fx_tool/
code ./

で作業ディレクトリに移動
vscode が起動する

main.py
を作成

久しぶりなのでほぼ忘れているので
Visual Studio Code キーボード ショートカット

をみながら操作

しかし途中でライブラリインストール済みでも import でエラー

このため
vscide import
で検索
VSCode で Python の import や from のエラーが消えない

を参考に

F1 を押す
Python: Select Interpreter を入力

使用する python を conda のものに設定

デフォルトの
Use default Python interpreter path
だとなぜか pandas のインポートができなかったけど
これで解決

from bs4 import BeautifulSoup
import pandas as pd
import streamlit as st

でライブラリインポート

アプリのタイトルは

st.title() 

で追加

経済指標カレンダーは
サイドバーで表示したいので

st.sidebar.write()

で記述していく

st.title('FX tool')

st.sidebar.write("""
# 経済指標カレンダー
今週の経済指標カレンダー
""")

url = 'https://fx.minkabu.jp/indicators' #みんかぶFXの経済指標URLを取得
dfs = pd.read_html(url) #テーブルのオブジェクトを生成
dfs[0]

dfs1 = dfs[0].dropna(subset = [4]) #4番にNaNが入っている行はバグなので、削除
dfs2 = dfs1.drop(2,axis =1) #2番目の列を削除。axis = 1は列を削除するオプション
dfs2.columns = ["発表時間", "経済指標", "前回変動幅(USD/JPY)","前回","予想","結果"]#列名を手動で追加。

#前処理終了

dfs2

st.sidebar.table(dfs2)
としてみたが
サイドバー表示だと見えにくいので本体の方にテーブル表示にする

なおサイドバーのwidth を変更する方法として
Change width of sidebar

にあるように
st.markdown
で設定も考えたが、使いにくいものになりそうなので別のレイアウトにすることに