logo

CYBOS Plusで機関及び外国人の取引量を取り込む方法 📂データ確保

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

20210725151736274

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

20210725153928000

注意深い外側のループについて説明する必要がある。なぜかは分からないが、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 は全体のデータを取得し、firmforeigner はそれぞれ機関と外国人のデータを取得したので、同じメソッドでも使い方が異なる。

  • 全体データ 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