CYBOS Plusで機関及び外国人の取引量を取り込む方法
ガイド1
CpSysDib.CpSvr7254
は、投資主体別現況を日別・期間別、純購入・売買比率、数量・金額を日付ごとに確認するために使われる。株式会社シージェンの投資主体別データを呼び出すためのPython例として使い方を学ぼう。CYBOS APIに慣れていない場合は、先に以下のガイドを参照してみよう。
ハイライト
>>> data7254
종가 등락률 거래량 기관계 외국인
0 76000 -0.26 873525 -31512 34478
1 76200 -3.18 1546826 -128698 19419
2 78700 -1.75 1406556 -62565 -111363
3 80100 3.49 2544337 73141 214885
4 77400 0.26 2012656 -24802 7375
.. ... ... ... ... ...
97 62066 0.49 522518 4608 -50814
98 61765 -2.77 279088 3672 -908
99 63524 -1.56 403473 -7307 -26027
100 64529 0.23 388193 -6985 -36055
101 64378 2.89 1060835 787 163109
2021年7月25日午後3時頃を基準に、終値、変動率、取引量、機関、外国人の純購入量が正しく呼び出されたことが確認できる。
説明
days = 100
yesterday = int((date.today() - timedelta(days=1)).strftime("%Y%m%d"))
firstday = int((date.today() - timedelta(days=(days + 1))).strftime("%Y%m%d"))
...
data7254 = None
data7254 = pd.DataFrame(columns=('종가', '등락률', '거래량', '기관계', '외국인'))
昨日から100日前までのデータを呼び出し、データを記録するための空の pandas
データフレームを作成した。
for j in range((days // 17) + 1):
time.sleep(0.1)
stock.BlockRequest()
foreigner.BlockRequest()
firm.BlockRequest()
numData = stock.GetHeaderValue(1)
for i in range(numData):
oneday = {}
...
if stock.Continue != True:
break
注意深い外側のループについて説明する必要がある。なぜかは分からないが、CpSysDib.CpSvr7254
でディスパッチされたオブジェクトは、指定された日数が何日であっても、最大17日までしか照会されないし、新しいデータリクエストをするたびに、純粋なPythonのイテレータのように次のデータを取得してしまう。
range((days // 17) + 1)
を使って外側のループは、全体の日数を17で割った商に1だけを足して回り、この度回りごとにBlockRequest()
で次の17日分のデータを取得する。これによれば、データの長さは常に17になるが、最後ではそうではないかもしれないから、正確にnumData = stock.GetHeaderValue(1)
を受け取って、日別データの数を照会する。stock.Continue
: 境界エラーを回避するためのプロパティで、データがまだ残っていれば真で、最後なら偽。実際には、上記のコードはダブルfor
ループで正確に計算されているため、エラーになる可能性はないが、while True
などを使う場合は、このようなチェックが必要になる。
このプロセスは公式ヘルプでは「連続処理」と呼ばれているので、そのように覚えておこう。
for i in range(numData):
oneday = {}
oneday['종가'] = stock.GetDataValue(14, i)
oneday['등락률'] = stock.GetDataValue(16, i)
oneday['거래량'] = stock.GetDataValue(17, i)
oneday['기관계'] = firm.GetDataValue(5, i) - firm.GetDataValue(1, i)
oneday['외국인'] = foreigner.GetDataValue(5, i) - foreigner.GetDataValue(1, i)
data7254.loc[len(data7254)] = oneday
内側のループは上記のように動作する。毎回、oneday
という空の辞書を作って値を受け取り、最後に data7254.loc[len(data7254)] = oneday
を使ってデータフレームの最後の位置に一つずつ入れている。
object.GetDataValue
は、特定の投資家のデータを取得するか全体のデータを取得するかによって、異なって使用される。stock
は全体のデータを取得し、firm
と foreigner
はそれぞれ機関と外国人のデータを取得したので、同じメソッドでも使い方が異なる。
- 全体データ
stock
- 14: 終値
- 16: 変動率
- 17: 取引量
- 個別データ
firm
,foreigner
- 5: 購入量
- 1: 売却量
ご覧の通り、取引量を求めるには、購入量から売却量を引く計算が必要だ。
全コード
from datetime import date, timedelta
import numpy as np
import time
import pandas as pd
days = 100
yesterday = int((date.today() - timedelta(days=1)).strftime("%Y%m%d"))
firstday = int((date.today() - timedelta(days=(days + 1))).strftime("%Y%m%d"))
import win32com.client
instCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
if instCpCybos.IsConnect:
print("Cybos Plus Connected...")
data7254 = None
data7254 = pd.DataFrame(columns=('종가', '등락률', '거래량', '기관계', '외국인'))
instCpStockCode = win32com.client.Dispatch("CpUtil.CpStockCode")
seegene = instCpStockCode.NameToCode("씨젠")
stock = win32com.client.Dispatch("CpSysDib.CpSvr7254")
stock.SetInputValue(0, seegene)
stock.SetInputValue(1, 6) # 기간선택구분 일별
stock.SetInputValue(2, firstday) # 시작일자
stock.SetInputValue(3, yesterday) # 끝일자
stock.SetInputValue(4, 0) # 매매비중구분 - 순매수
stock.SetInputValue(5, 0) # 투자자 전체
foreigner = win32com.client.Dispatch("CpSysDib.CpSvr7254")
foreigner.SetInputValue(0, seegene)
foreigner.SetInputValue(1, 6) # 기간선택구분 일별
foreigner.SetInputValue(2, firstday) # 시작일자
foreigner.SetInputValue(3, yesterday) # 끝일자
foreigner.SetInputValue(4, 0) # 매매비중구분 - 순매수
foreigner.SetInputValue(5, 2) # 투자자 외국인
firm = win32com.client.Dispatch("CpSysDib.CpSvr7254")
firm.SetInputValue(0, seegene)
firm.SetInputValue(1, 6) # 기간선택구분 일별
firm.SetInputValue(2, firstday) # 시작일자
firm.SetInputValue(3, yesterday) # 끝일자
firm.SetInputValue(4, 0) # 매매비중구분 - 순매수
firm.SetInputValue(5, 3) # 투자자 기관계
for j in range((days // 17) + 1):
time.sleep(0.1)
stock.BlockRequest()
foreigner.BlockRequest()
firm.BlockRequest()
numData = stock.GetHeaderValue(1)
for i in range(numData):
oneday = {}
oneday['종가'] = stock.GetDataValue(14, i)
oneday['등락률'] = stock.GetDataValue(16, i)
oneday['거래량'] = stock.GetDataValue(17, i)
oneday['기관계'] = firm.GetDataValue(5, i) - firm.GetDataValue(1, i)
oneday['외국인'] = foreigner.GetDataValue(5, i) - foreigner.GetDataValue(1, i)
data7254.loc[len(data7254)] = oneday
if stock.Continue != True:
break