2023年4月8日土曜日

【株予想】3月の予想結果

 毎日実施している株予想の月次集計結果

株画像


 過去のシミュレーションについての情報はこちら

 株予想のページ




■ルール

1.値上がりしそう判定が出た銘柄の翌日の始値で購入しその額を基準値とする

2.購入した3営業日後(判定日の4営業日後)の始値で売却しその額を評価値とする

3.評価値-基準値がプラスであれば勝利。マイナスであれば敗北とする


■予想の考え方

だいたい以下3点

1.日経平均の225銘柄から選定

2.過去4年分のシミュレーション結果から勝率60%以上の66銘柄を選定

3.25日移動平均、75日移動平均、日々の値動きから売られすぎな銘柄を選定


■3月の予想結果(3/28~3/31)

勝率:75%(3/4)

①購入費用      :¥1,704,000

②100株購入による利益: ¥  20,600

③手数料※      : ¥   2,480 

④税金暫定額     : ¥   4,185 

⑤純利益(②-③-④) : ¥  13,935 

⑥利益率(⑤/①)   :0.82%

判定日コード銘柄名基準日基準値評価日評価値利益評価購入費用手数料100株での利益
2023/3/285332TOTO3/29¥ 4,4354/3¥ 4,485¥ 50勝利¥443,500520¥ 5,000
2023/3/296098リクルート3/30¥ 3,6594/4¥ 3,774¥ 115勝利¥365,900520¥ 11,500
2023/3/306098リクルート3/31¥ 3,6414/5¥ 3,737¥ 96勝利¥364,100520¥ 9,600
2023/3/308630SOMPO3/31¥ 5,3054/5¥ 5,250¥ (55)敗北¥530,500920¥ (5,500)


■参考:3月事前検証込みの予想結果(3/20~3/31)

勝率:91%(10/11)

①購入費用      :¥3,140,300

②100株購入による利益: ¥  63,700 

③手数料※      : ¥     4,820  

④税金暫定額     : ¥    12,941 

⑤純利益(②-③-④) : ¥   45,939 

⑥利益率(⑤/①)   :1.46%

判定日コード銘柄名基準日基準値評価日評価値利益評価購入費用手数料100株での利益
2023/3/202002日清粉G3/22¥ 1,5573/27¥ 1,564¥ 7勝利¥155,700200¥ 700
2023/3/225703日軽金HD3/23¥ 1,4273/28¥ 1,462¥ 35勝利¥142,700200¥ 3,500
2023/3/225803フジクラ3/23¥ 8853/28¥ 919¥ 34勝利¥88,500180¥ 3,400
2023/3/226841横河電3/23¥ 2,0483/28¥ 2,089¥ 41勝利¥204,800520¥ 4,100
2023/3/227011三菱重3/23¥ 4,5223/28¥ 4,748¥ 226勝利¥452,200520¥ 22,600
2023/3/228304あおぞら銀3/23¥ 2,3743/28¥ 2,426¥ 52勝利¥237,400520¥ 5,200
2023/3/228804東建物3/23¥ 1,5503/28¥ 1,586¥ 36勝利¥155,000200¥ 3,600
2023/3/285332TOTO3/29¥ 4,4354/3¥ 4,485¥ 50勝利¥443,500520¥ 5,000
2023/3/296098リクルート3/30¥ 3,6594/4¥ 3,774¥ 115勝利¥365,900520¥ 11,500
2023/3/306098リクルート3/31¥ 3,6414/5¥ 3,737¥ 96勝利¥364,100520¥ 9,600
2023/3/308630SOMPO3/31¥ 5,3054/5¥ 5,250¥ (55)敗北¥530,500920¥ (5,500)


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



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か?

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



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




■関連情報