python で株価指数の取得その2

python で株価指数の取得その2

日経平均株価とかダウはよくテレビとかででるけど
フランスとかイギリスなどのはネットで調べる必要があり
アプリなどでもあまりでないことが多いので表示できるように
investpy で実験

import investpy
from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta
import altair as alt
import pandas as pd

でライブラリをインポート

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

で今日の日付を取得し
フォーマットを investpy で使う日付に変更

今回はイギリスの指標の
FTSE 100

フランスの
CAC 40

を取得

フランスは
france

イギリスは
united kingdom
が国名になるので

uk_index =investpy.indices.get_indices(country="united kingdom")
f_index =investpy.indices.get_indices(country="france")

で取得して

uk_index[uk_index['full_name'].str.contains('FTSE 100')]

で検索し 
name が FTSE 100 を確認

ftse = investpy.get_index_historical_data(index='FTSE 100',country='united kingdom',
                                        from_date='01/01/2010',to_date=today)

でFTSE 100の値を取得し

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

でDateをカラムに追加

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

でチャートで表示

次にCAC 40

f_index[f_index['full_name'].str.contains('CAC 40')]

で検索

cac40 = investpy.get_index_historical_data(index='CAC 40',country='france',
                                        from_date='01/01/2010',to_date=today)

で値を取得

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

で日付フォーマット変更と
Date をカラムに追加

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

でチャート表示

他にもアジアや中東などの株価指数なども
おなじ要領で調べてグラフ化が可能

python で株価指数の取得

python で株価指数の取得
【Python】investpyを使ったInvesting.comからのデータ取得方法


指数データの取得方法が乗っていたので参考に

import investpy
from datetime import datetime, date, timedelta
from dateutil.relativedelta import relativedelta
import altair as alt
import pandas as pd

でライブラリをインポート

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

で今日の日付を取得し
フォーマットを investpy で使う日付に変更

df = investpy.get_index_historical_data(index='S&P 500',country='united states',
                                        from_date='01/01/2010',to_date=today)


2010年1月1日から今日までの
S&P500
のデータを取得

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

で日付フォーマットを altair で使う形式に変更

df = df.T
df= df.T.reset_index()

でDate をカラムに追加

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

でチャートを表示

S&P500 ができたのでダウ平均を取得

使用したメソッドの
get_index_historical_data
については
investpy.indices

を参考に

パラメータに指定する株価指数については
https://jp.investing.com/indices/world-indices
で日本語版がでるがコードを指定するので

https://www.investing.com/indices/usa-indices
を参考に

dow =  investpy.get_index_historical_data(index='Dow Jones',country='united states',
                                        from_date='01/01/2010',to_date=today)

としたが

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-23-37a90ad00d34> in <module>
----> 1 dow =  investpy.get_index_historical_data(index='DJI',country='united states',
      2                                         from_date='01/01/2010',to_date=today)

~/anaconda3/lib/python3.8/site-packages/investpy/indices.py in get_index_historical_data(index, country, from_date, to_date, as_json, order, interval)
    511 
    512     if index not in list(indices['name'].apply(unidecode).str.lower()):
--> 513         raise RuntimeError("ERR#0045: index " + index + " not found, check if it is correct.")
    514 
    515     full_name = indices.loc[(indices['name'].apply(unidecode).str.lower() == index).idxmax(), 'full_name']

RuntimeError: ERR#0045: index dji not found, check if it is correct.

となり
指定するコードが違うらしい

VIX 指数(恐怖指数)については

vix = investpy.get_index_historical_data(index='S&P 500 VIX',country='united states',
                                        from_date='01/01/2010',to_date=today)
vix

とすれば表示される

どうやら名称が違うようなので
プライマリーセクターに絞り検索

stock_index =investpy.indices.get_indices(country="united states")
stock_index[stock_index['class']=='primary_sectors']

64に絞りこみできるので

stock_index =investpy.indices.get_indices(country="united states")
stock_index[stock_index['class']=='primary_sectors'].head(35)


stock_index =investpy.indices.get_indices(country="united states")
stock_index[stock_index['class']=='primary_sectors'].tail(35)

で探すが該当するものがでない

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

で部分一致で検索をする

str.startswith()

で文字列で始まるもの
もしくは

str.contains()

で文字列を含むもの
を対象にする

dow =stock_index[(stock_index['market']=='global_indices') & (stock_index['class']=='other_indices')]
dow[dow['name'].str.contains('DJ')]

で探したがそれらしいものはでてこない

stock_index =investpy.indices.get_indices(country="united states")
stock_index[stock_index['full_name'].str.contains('Dow Jones Industrial')]

で検索すると
Dow 30 が表示される

dow =  investpy.get_index_historical_data(index='Dow 30',country='united states',
                                        from_date='01/01/2010',to_date=today)
dow

で表示されるので
S&P500のときと同じようにチャートを表示する

dow=dow.T
dow = dow.T.reset_index()

で Date をカラムに追加

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

でチャート表示

vix 恐怖指数をチャートにするなら

vix = investpy.get_index_historical_data(index='S&P 500 VIX',country='united states',
                                        from_date='01/01/2010',to_date=today)

でデータを取得

vix = vix.T
vix = vix.T.reset_index()


Date をカラムに追加

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

でチャートで表示

他の国の株価指数も取得できる
その場合、国の指定をする必要があり

investpy.indices.get_index_countries()

で取得可能な国が表示できる

index_list = investpy.indices.get_index_countries()
index_list

で取得可能な国を表示可能

ユーロ圏の株価指数を調べるのなら
https://www.investing.com/indices/european-indices

株価指数の名前を調べる
ダウ平均が Dow 30 というように
名称が investpy のときわからないときがあるので

DAX
Euro Stoxx 50
がある国を調べる

Germany なので

euro_index =investpy.indices.get_indices(country="germany")

で取得し
https://www.investing.com/indices/germany-30
から
名称が DAX(GDAXI)
であるのを確認したら

euro_index[euro_index['full_name'].str.contains('DAX')]

で探すと出てこないので

euro_index[euro_index['name'].str.contains('DAX')]

で検索すると出てきた

あとは

dax = investpy.get_index_historical_data(index='DAX',country='germany',
                                        from_date='01/01/2010',to_date=today)

でDAXの値を取得

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

で日付フォーマット変更と
Date をカラムに追加

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

でチャート表示

応用でユーロストック50なら
https://www.investing.com/indices/eu-stoxx50

Euro Stoxx 50 (STOXX50E)
となっているのを確認できるので

euro_index =investpy.indices.get_indices(country="germany")
euro_index[euro_index['name'].str.contains('Euro Stoxx 50')]

で検索すると簡単にヒットする

あとは

euro_stock50 = investpy.get_index_historical_data(index='Euro Stoxx 50',country='germany',
                                        from_date='01/01/2010',to_date=today)

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

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

で表示できる

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

でチャート表示

これで金価格も表示可能

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'])

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

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

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

形式が
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 でできたのでこれをつかう