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年3月2日木曜日

【社内DX案件紹介】値の入っているシートのみ印刷する

 ■社内DXの依頼内容

ブックの中でB1セル以下に値があるシートのみを印刷したい


■社内DXの条件

・1シート目は印刷対象外としたい

・2シート目以降でB1セル以降に値があるシートを印刷したい

・印刷するシートはマクロが入っているブック内にある


■諸元

・2シート目から全シートを周回する

・B2セル以降に値があれば配列にシート名を格納する

・シート名が入った配列を対象として印刷プレビューする


■作成方法

1.2シート目からデータのあるファイルを準備する。

2シート目4シート目6シート目に値があるブック

2.実際にマクロを書いていく

Sub Sample()

Dim st() As String  '/--シート名を格納する配列--/'
Dim i As Integer    '/--シート周回カウンタ--/'
Dim m As Integer    '/--最大シート数--/'
Dim c As Integer    '/--配列用カウンタ--/'
Dim y As Long       '/--行数を格納--/'

'/--全シート数を入れる--/'
m = Worksheets.Count

'/--配列は0スタートなので+1したときに0になるようカウンタは-1からスタート--/'
c = -1
For i = 2 To m
    y = Sheets(i).Cells(Rows.Count, 2).End(xlUp).Row
    If y > 1 Then
        c = c + 1
        ReDim Preserve st(c)
        '/--シート名を配列に格納する--/'
        st(c) = Sheets(i).Name
    End If
Next i

'/--配列に格納したシート名のみを印刷プレビューする--/'
Sheets(st).PrintPreview


End Sub


3.マクロ処理結果

2シート目、4シート目、6シート目の印刷プレビュー画面が表示されます。

印刷プレビュー


■マクロ解説

1.複数シートを印刷する(今回は印刷プレビュー)

Sheets(配列名).PrintPreview


st(0)="値あり1"

st(1)="値あり2"

st(2)="値あり3"

という配列があったととして、

Sheets(st).PrintPreview

とすると、中身は

Sheets(Array("値あり1","値あり2","値あり3")).PrintPreview

と同義となるので、シート「値あり1」、シート「値あり2」、シート「値あり3」が選択された状態で印刷プレビューがかかる


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



TOPページへ戻る


■社内DX案件紹介

【社内DX案件紹介】アンケートの集計-1-

【社内DX案件紹介】アンケートの集計-2-

【社内DX案件紹介】架電内容ごとの情報振り分け-1-

【社内DX案件紹介】架電内容ごとの情報振り分け-2-

【社内DX案件紹介】2つのファイルの内容を比較する

【社内DX案件紹介】封入物の重さによって印刷会社を変える

【社内DX案件紹介】データの期間によってレコードを分割しファイル出力する


■社内DXの進め方

【社内DXの進め方】ブログの目的(会社が求めるDX)

【社内DXの進め方】社内DXの推進について

【社内DXの進め方】社内DXは具体的に何をすればよいのか?

【社内DXの進め方】なぜ今Excelか?