How to Import Institutional and Foreign Trade Volume with CYBOS Plus
Guide1
CpSysDib.CpSvr7254
is used to check the status of investment by party on a daily-period basis, net purchase-trading proportion, and amount-value on a daily basis. Let’s learn how to use it with a Python example that fetches data by investor type for Seegene Inc. If you’re not familiar with the CYBOS API, refer to the following guide first.
Highlights
>>> 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
As of around 3 PM on July 25, 2021, it was confirmed that the closing price, fluctuation rate, trading volume, institutions, and net purchase volume of foreigners were successfully fetched.
Explanation
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=('종가', '등락률', '거래량', '기관계', '외국인'))
The data from 100 days ago until yesterday is fetched, and an empty pandas
dataframe has been created to record the data.
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
We need to explain the unusual outer loop. For an unknown reason, an object dispatched by CpSysDib.CpSvr7254
can only query up to a maximum of 17 days regardless of the designated date, and every time a new data request is made, it fetches the next set of data like a pure Python iterator.
- By using
range((days // 17) + 1)
, the outer loop runs just once more than the quotient of the total days divided by 17, and each time, it fetches the next 17 days of data withBlockRequest()
. According to this, the length of data will always be 17, however, it might not be towards the end. Therefore, we precisely inquire the number of daily data vianumData = stock.GetHeaderValue(1)
. stock.Continue
: A property to avoid a boundary error, true if there is more data left and false if it’s the last. In fact, the above code runs precisely with a doublefor
loop, so there should be no chance for error, but checks like this are needed if used withwhile True
, for instance.
This process is referred to as ‘Continuous Processing’ in the official help, so let’s remember it as such.
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
The inner loop works as described above. Every time, an empty dictionary named oneday
is created to fetch values, and finally, data7254.loc[len(data7254)] = oneday
is used to add one by one to the last slot of the dataframe.
object.GetDataValue
is used differently depending on whether fetching specific investor data or overall data. stock
fetched the overall data, while firm
and foreigner
fetched the data for institutions and foreigners, respectively, hence the same method looks different in usage.
- Overall data
stock
- 14: Closing price
- 16: Fluctuation rate
- 17: Trading volume
- Individual data
firm
,foreigner
- 5: Purchase volume
- 1: Sale volume
As seen, to calculate the trading volume, it is necessary to subtract the sale volume from the purchase volume.
Complete Code
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