ラベル #Python の投稿を表示しています。 すべての投稿を表示
ラベル #Python の投稿を表示しています。 すべての投稿を表示

2023年3月26日日曜日

【Python】株価データの移動平均線からゴールデンクロスの場所を探す

 前回(【Python】株価データに移動平均を付ける)、移動平均線を引いてみたところやはりゴールデンクロス以降は株価が上昇していることがわかりましたので、ゴールデンクロスが発生したタイミングをデータの中から抽出してみたいと思います。


■プログラム

import pandas as pd

df=pd.read_csv('9432.csv',encoding='shift-jis', index_col=0)

df.index=pd.to_datetime(df.index)

df['25MA']=df['Close'].rolling(25).mean()
df['75MA']=df['Close'].rolling(75).mean()

#shiftで縦方向に1つ行をずらす。
#1日前の値が欲しければ下(正方向)に1行ずらせば同じ行内で前日の値が取得できる
df['1日前_25MA']=df['25MA'].shift(1)
df['1日前_75MA']=df['75MA'].shift(1)

#関数:ゴールデンクロス判定
def goldenX(row):
    if row["1日前_75MA"] > row["1日前_25MA"] and row["25MA"] > row["75MA"] :
        row["goldenX"] = 1
    else:
        row["goldenX"] = 0

    return row

#関数「goldenX(ゴールデンクロス判定)」を各行に追加
df = df.apply(goldenX, axis=1)

#ゴールデンクロスが発生したタイミングを抽出
df2=df[df['goldenX']==1]


■解説

for文を使用してもできるのですが、データ量が多いとかなり時間がかかると思うので、なるべくfor文以外の方法でやってみました。

1.データを1日分ずらして別カラムに格納する

ゴールデンクロスは長期移動平均>短期移動平均から短期移動平均>長期移動平均となる日を指すので前日は長期移動平均(75MA)が短期移動平均(25MA)よりも高く、当日は短期移動平均(25MA)が長期移動平均(75MA)よりも高くなります。

そこで

df['25MA'].shift(1)

でデータを1段下げることで、前日のデータを当日のレコードに入れます。

#shiftで縦方向に1つ行をずらす。
#1日前の値が欲しければ下(正方向)に1行ずらせば同じ行内で前日の値が取得できる
df['1日前_25MA']=df['25MA'].shift(1)
df['1日前_75MA']=df['75MA'].shift(1)


こうすることで1レコードの中で前日のデータがわかるようになります。

shiftを使用してデータを1段ずらして格納することで1レコードの中で前日との比較ができる

2.applyで各レコードに関数の結果を追加する

1レコードの中で前日のデータがわかるようになったので、各レコードにゴールデンクロス判定を行う関数を追加します。

まず、このようなIf文で関数を作成します。

#関数:ゴールデンクロス判定
def goldenX(row):
    if row["1日前_75MA"] > row["1日前_25MA"] and row["25MA"] > row["75MA"] :
        row["goldenX"] = 1
    else:
        row["goldenX"] = 0

    return row


次にこの関数をapplyで各レコードに追加します。

#関数「goldenX(ゴールデンクロス判定)」を各行に追加
df = df.apply(goldenX, axis=1)


最後にゴールデンクロス判定が1(True)のものを抽出します。

#ゴールデンクロスが発生したタイミングを抽出
df2=df[df['goldenX']==1]


データを見てみると、2018年1月1日~2023年3月23日の間で12回ゴールデンクロスを迎えていたことがわかりました。

ゴールデンクロス時のデータ

↓よろしければクリックをお願いします!


■関連情報


2023年3月25日土曜日

【Python】株価データに移動平均を付ける

前回(【Python】APIで日本の個別株情報を取得する)、株価データを取得しましたが、それだけでは単なるコレクションなので分析するために、移動平均を追加していきたいと思います。

データは前回同様9432:日本電信電話になります。

9432:日本電信電話 5年間の終値

APIで取得した終値のデータに5日、25日、75日の移動平均線を追加してみます。

今回はJupyter Labでグラフとして表示させます。

■プログラム

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

df=pd.read_csv('9432.csv',encoding='shift-jis', index_col=0)

df.index=pd.to_datetime(df.index)

df['5MA']=df['Close'].rolling(5).mean()
df['25MA']=df['Close'].rolling(25).mean()
df['75MA']=df['Close'].rolling(75).mean()


■解説

1.必要なライブラリのインポート

まずpandasとグラフを描画するmatplotlibをインポートします。

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline


2.CSVを読み込む

1列目をindexとして読み込みます。

df=pd.read_csv('9432.csv',encoding='shift-jis', index_col=0)

読み込んだ状態ではindexが文字列Object型になるので、日付型に変更します。

df.index=pd.to_datetime(df.index)

データの型を確認すると以下のようになります。

df.info()
DatetimeIndex: 1272 entries, 2018-01-03 to 2023-03-03
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Open    1272 non-null   float64
 1   High    1272 non-null   float64
 2   Low     1272 non-null   float64
 3   Close   1272 non-null   float64
 4   Volume  1272 non-null   int64  
dtypes: float64(4), int64(1)
memory usage: 59.6 KB


3.移動平均を付ける

DataFrame[カラム名].rolling(期間).mean() でそのサイクルに対する平均値を出すことができます。

今回は移動平均なので.mean()ですが、.sum()だとその期間の合計値とかも行けます。

df['5MA']=df['Close'].rolling(5).mean()


データフレームの中を確認するとそれぞれの移動平均値が格納されています。

df
データフレームの中に移動平均値が格納されている


4.グラフに描画する

実際にグラフに描画してみます。

df[['Close','5MA','25MA','75MA']].plot(color=['skyblue','pink','blue','red'])
株価の終値に5日25日75日の移動平均線が表示される

■少し見てみる

よく短期移動平均が長期移動平均を上回るとゴールデンクロスとして株価が上昇する兆し、短期移動平均が長期移動平均を下回るとデッドクロスとして株価が下がる兆しと言われますが、グラフで表現するとホントその通りなんですね。

ゴールデンクロス以降は株価が上がっている

これはゴールデンクロスのポイントを毎日見つければ、上がる株価がわかるんですかね。


↓よろしければクリックをお願いします!



■関連情報

2023年3月11日土曜日

【Python】APIで日本の個別株情報を取得する

 なんかstooqというポーランドのサイトから日本の個別株情報をAPIで取得できるみたいなので試してみました。

スクレイピングでやっていたのが馬鹿らしくなるほど簡単ですね。


■目的

stooqのサイトからAPIで5年分の日本の個別株情報を取得する


■前準備

pandas_datareaderのインストール

APIを使うためにpandas_datareaderをインストールします。

pip install pandas_datareader


■プログラム

日本電信電話(9432)のデータを取得してみます。
import pandas_datareader as pdr
import pandas as pd
from datetime import datetime

#データソースと期間と銘柄を変数に格納
cd='9432'
source='stooq'
start = datetime(2018,1,1)
end = datetime(2099,12,31)
brand=cd + '.jp'

df = pdr.DataReader(brand, data_source=source,start=start, end=end)

#日付で照準ソート
df=df.sort_index(axis='index')


■処理結果

始値、高値、安値、終値、出来高が取得できました。

stooqから取得した株情報

これはループして銘柄コードを可変にすれば、全銘柄のデータ取得できそうですね。


↓よろしければクリックをお願いします!



■関連情報

2023年2月19日日曜日

【Python】スクレイピングでGoogleファイナンスの日本の個別株情報を取得する

 APIは有料だったり、スクレイピングやAPIが禁止なところが多かったり、Googleファイナンス関数は日本株非対応だったり、GASで日本株を無理やり取ろうとしても始値が取れなかったり。

そこでスクレイピングが許されているGoogleファイナンスのページから情報を取得できるPythonプログラムを考えてみました。

目的

Googleファイナンスのページから、日本個別銘柄の

・始値
・終値
・安値
・高値
・出来高(ざっくり)

を取得する

前準備

Seleniumのインストール

Selenium は Web ブラウザの操作を自動化するためのフレームワークで、タスクの自動化や Web サイトのスクレイピングでも利用されています。

pip install selenium

でインストールしましょう。


ChromeDriverのインストール

Seleniumでは、WebDriverを使用してブラウザを操作します。
ブラウザをChomeで行うので、ChromeDriverをインストールします。

https://chromedriver.chromium.org/downloads

こちらで自分が使用しているChromeのVer.に近いドライバーをダウンロードします。

ZIPファイルを解凍し、chromedriver.exeを適当なフォルダに置きます。
※私はScrapingするフォルダに入れています。


取得する情報

市場が閉まった後を前提に考えていますが、以下の情報を取得します。

例で日本電信電話(9432)の株価を取得したいと思います。

1日のページから日付・始値・終値・安値・高値を取得

5日のページから出来高を取得


プログラム

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time
import datetime

#GoogleChromeを起動
browser = webdriver.Chrome(executable_path = 'C:\\Users\\****\\Documents\\Scraping\\chromedriver.exe')
browser.implicitly_wait(3)

cd='9432'
url = 'https://www.google.com/finance/quote/' + cd + ':TYO'
browser.get(url)
time.sleep(3)

#終値を取得
strClose=browser.find_element(By.CLASS_NAME,"kf1m0").text
strClose=strClose.replace("¥","")
floatClose=float(strClose.replace(",",""))

#日付を取得
strDay=browser.find_element(By.CLASS_NAME,"ygUjEc").text
strDay2=strDay.split(',')
strDay2[0]=strDay2[0].replace("月","-")
strDay2[0]=strDay2[0].replace("日","")
dateNow=datetime.datetime.now()
strDay3=str(dateNow.year)+"-"+strDay2[0]
dateDay=datetime.datetime.strptime(strDay3, '%Y-%m-%d')

#安値-高値を取得
#CLASS_NAMEだと取得できないので、CSS_SELECTORで取得
strLowHigh=browser.find_element(By.CSS_SELECTOR,"#yDmH0d > c-wiz > div > div.e1AOyf > div > main > div.Gfxi4 > div.HKO5Mb > div > div.eYanAe > div:nth-child(3) > div").text
strLowHigh=strLowHigh.replace("¥","")
strLowHigh=strLowHigh.replace(",","")
strLowHigh2=strLowHigh.split(" - ")
floatLow=float(strLowHigh2[0])
floatHigh=float(strLowHigh2[1])

#取得するグラフの取得
graph = browser.find_element(By.CLASS_NAME,"ushogf")

#マウスの動きを記述
actions = ActionChains(browser)

#チャートの中心にマウスを移動
actions.move_to_element(graph)

#チャートの左端にマウスを持ってくる
#なぜか.rect['width']/2だと左端に行ってくれないので、ベタ打ち
actions.move_by_offset(-385,0).perform()

#始値を取得
strOpen=browser.find_element(By.CLASS_NAME,"hSGhwc-SeJRAd").text
strOpen=strOpen.replace("JPY ¥","")
floatOpen=float(strOpen.replace(",",""))

#出来高を取得
#5日のページに移って取得
url = url+'?window=5D'
browser.get(url)
time.sleep(3)

#取得するグラフの取得
graph = browser.find_element(By.CLASS_NAME,"ushogf")

#マウスの動きを記述
actions = ActionChains(browser)

#チャートの中心にマウスを移動
actions.move_to_element(graph)

#チャートの→端にマウスを持ってくる
#なぜか.rect['width']/2で右端に行っても値が取得できないので-1して補正
actions.move_by_offset((graph.rect['width']/2)-1,0).perform()

#出来高を取得
#ざっくりしか出てこないけど。
strVolume=browser.find_element(By.CLASS_NAME,"hSGhwc-IOpRCf").text
strVolume=strVolume.replace("出来高: ","")
if '万' in strVolume:
    strVolume=strVolume.replace("万","")
    floatVolume=float(strVolume)*10000
else:
    floatVolume=float(strVolume)

print(str(dateDay)+' 始値:'+str(floatOpen)+' 終値:'+str(floatClose)+' 安値:'+str(floatLow)+' 高値:'+str(floatHigh)+' 出来高:'+str(floatVolume))

browser.close()
browser.quit()

解説

CLASS名、CSSセレクタ値の取得

本スクレイピングはhtmlに記載されているクラス名やCSSセレクター等の情報をキーにそのテキストを取得していっています。
ページ上で右クリック→[検証]をクリックすると以下のような情報が出てきますので、ほしい情報のところのCLASS名やCSSセレクタを取得しています。
検証でhtml内を解析し必要なキーを取得

グラフ内のデータを取得する

ページを取得しただけではグラフ内に入っている始値や出来高のデータが取得できないので、以下のページを参考にグラフ内にマウスカーソルを合わせ値を取得しました。
Seleniumでマウスを自動操縦して、Googleから株価データを取得する - Qiita
thumbnail
https://qiita.com/i_shot1997/items/f2d1e6a0e9f665412faa

出力結果

こんな感じで出力されます。
2023-02-17 00:00:00 始値:3857.0 終値:3888.0 安値:3853.0 高値:3894.0 出来高:890000.0



↓よろしければクリックをお願いします!




■関連情報

2023年1月28日土曜日

【Python環境構築】jupyterlab variableinspector インストール編

 Pythonを使う上で一番大変なのは環境構築だと思う。


■jupyterlab variableinspector

Jupyter Lab上で変数に値を代入したタイミングでその中身と型が確認できる拡張機能

jupyterlab variableinspectorによる変数の中身の確認


■インストール方法

※Windows10、Anaconda前提で記載しています。

1.node.jsのインストール

Jupyter Lab上で

conda install -c conda-forge nodejs

もしくは

conda install nodejs

を実行。


2.Jupyter Labを一度Shutdown

私の環境だけかもしれませんが、一度Buildしないとそのあとの「jupyterlab variableinspector」が入りませんでした。


3.Jupyter Labをリビルド

コマンドプロンプト上で

jupyter lab build

を実行。


4.jupyterlab variableinspectorのインストール

コマンドプロンプト上で

jupyter labextension install @lckr/jupyterlab_variableinspector@3.0.7

を実行。

多くのサイトでは

jupyter labextension install @lckr/jupyterlab_variableinspector

とあるのですが、今のVer.(3.0.9)はなんかインストールに失敗したので、以下の記事を参考に、古いVer.(3.0.7)をインストールすることにしました。

jupyterlab variable inspectorのインストール
thumbnail
https://zenn.dev/toitoy8/articles/220508_jup-extend01


5.Jupyter Labで確認

Jupyter Labのセル上で右クリックし、「Open Variable Inspector」が表示されていればインストール完了です。

Open Variable Inspector


■jupyterlab variableinspector使用方法

Jupyter Labのセル上で右クリックし、「Open Variable Inspector」をクリックすると、Variable Inspectorというタブが出てきます。

Variable Inspector

Variable Inspectorタブを右にドラッグするとタブが分割されてセルとVariable Inspectorの両方が見えるようになります。

タブを分割

その状態でセルに変数を代入すると、自動でVariable Inspectorに変数の名前・型・値とうが表示されます。

Variable Inspectorで変数を確認

↓よろしければクリックをお願いします!


TOPページに戻る


■関連情報

【Python】スクレイピングでGoogleファイナンスの日本の個別株情報を取得する

【Python】APIで日本の個別株情報を取得する

【Python】株価データに移動平均を付ける

【Python】株価データの移動平均線からゴールデンクロスの場所を探す