logo

How to Import Institutional and Foreign Trade Volume with CYBOS Plus 📂Data Set

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

20210725151736274

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

20210725153928000

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 with BlockRequest(). 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 via numData = 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 double for loop, so there should be no chance for error, but checks like this are needed if used with while 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