2017年8月10日 星期四

最近發現 comtypes create 群益API COM objects 不用找 clsid

剛剛發現 comtypes  create 群益API COM objects 不用找 clsid,直接如下方所示,即可 CreateObject,

skC=cc.CreateObject(sk.SKCenterLib,interface=sk.ISKCenterLib)
skQ=cc.CreateObject(sk.SKQuoteLib,interface=sk.ISKQuoteLib)
skR=cc.CreateObject(sk.SKReplyLib,interface=sk.ISKReplyLib)

以此類推,這樣就不用找clsid

目前用起來好像跟之前一樣,還沒出什麼問題,先醬

2017年8月2日 星期三

群益api in python 取得歷史kline報價

今天來用群益API取得歷史報價,群益API可以取得從上市櫃開始到今日的所有日K歷史報價,有了歷史報價就可以做很多樣回測。一分K歷史報價目前可以取得約 60000 根的資料,且幾秒鐘內就可以取回來,相當便利喔!

到目前2021年,kline 改變了不少,目前定位為 "歷史kline",只能取得當日以前的kline,若要取得當日kline,需要自己收集 tick 資料,自己組成 kline
可以參考:
  1. 群益api 使用python 取得 tick 報價
  2. tick data 轉換成 k Bar

################SKCOMAPI 2.13.17 以上版本適用##################
# 本範例要用 jupyter 來跑, 如果要在console 下跑,要加pythoncom來處理eventloop
# Eventloop 參考這幾篇的用法,或是像群益官方範例建立GUI方式產生

# skcomapi 2.13.23 以上適用
from comtypes.client import GetModule, CreateObject, GetEvents
# 將sckcom轉成python package
# GetModule 只要執行一次就好,除非有更新API,再參考官網範例,清除comtypes.gen 
# 下的檔案,再重新呼叫 GetModule 包裝
GetModule('C:\\skcom\\CapitalAPI_2.13.23\\x64\\SKCOM.dll')
import comtypes.gen.SKCOMLib as sk
import pythoncom
#config #ID and Password ID = "" PW = "" #request stock stockName='TSEA' #建立物件,避免重複 createObject #登錄物件 if 'skC' not in globals(): skC=CreateObject(sk.SKCenterLib, interface=sk.ISKCenterLib) #報價物件 if 'skQ' not in globals(): skQ=CreateObject(sk.SKQuoteLib, interface=sk.ISKQuoteLib) #回報物件 if 'skR' not in globals(): skR=CreateObject(sk.SKReplyLib , interface=sk.ISKReplyLib) #建立事件類別 class skR_events: def OnReplyMessage(self, bstrUserID, bstrMessage, sConfirmCode=0xFFFF): print('OnReplyMessage', bstrMessage) return sConfirmCode class skQ_events: def __init__(self): self.KlineData = [] def OnConnection(self, nKind, nCode): if nKind == 3003: print("skQ連線成功, nkind= ", nKind) nCode=skQ.SKQuoteLib_RequestKLine(stockName, sKLineType=4, sOutType=1) else: print('please check, nCode, nKind=', nCode, nKind) def OnNotifyKLineData(self, bstrStockNo, bstrData): self.KlineData.append([bstrStockNo] + bstrData.split(',')) #Event sink, 事件實體 EventR=skR_events() EventQ=skQ_events() #make connection to event sink ConnR = GetEvents(skR, EventR) ConnQ = GetEvents(skQ, EventQ) print('load module and event handler') #########在新 cell 執行 ############ # magic function to get event loop, 只有jupyter 可以用,
# console 介面要用 pythoncom.PumpWaitingMessages(1)
%matplotlib auto
 
#登入,連線報價主機
nCode=skC.SKCenterLib_Login(ID, PW)
print("Login,", skC.SKCenterLib_GetReturnCodeMessage(nCode))
 
#Enter quote server
nCode=skQ.SKQuoteLib_EnterMonitor()
print('SKQuoteLib_EnterMonitor()', skC.SKCenterLib_GetReturnCodeMessage(nCode))


######以下為 2.13.17以下版本 年久失修僅供參考#################################
#群益api in python 取得歷史報價
import pythoncom, time, os
import comtypes.client as cc
cc.GetModule(r'C:\SKCOM\x86\SKCOM.dll')
import comtypes.gen.SKCOMLib as sk
#建立COM物件
skC=cc.CreateObject(sk.SKCenterLib, interface=sk.ISKCenterLib)
skQ=cc.CreateObject(sk.SKQuoteLib, interface=sk.ISKQuoteLib)

#Some Configuration
ID='身分證'
PW='密碼'

#顯示 event 事件, t 秒內,每隔一秒,檢查有沒有 event 發生
def pumpwait(t=1):
    for i in range(t):
        time.sleep(1)
        pythoncom.PumpWaitingMessages()

#建立事件類別
class skQ_events:
    def __init__(self):
        self.KlineData=[]
    def OnConnection(self, nKind, nCode):
        if nCode == 0 :
            if nKind == 3001 :
                print("連線中, nkind= ", nKind)
            elif nKind == 3003:
                print("連線成功, nkind= ", nKind)
    def OnNotifyKLineData(self, bstrStockNo, bstrData):
        self.KlineData.append(bstrData.split(','))
                    
#Event sink, 事件實體  
EventQ=skQ_events()
#make connection to event sink
ConnectionQ = cc.GetEvents(skQ, EventQ)        

#登入,連線報價主機
nCode=skC.SKCenterLib_Login(ID, PW)
print("Login,", skC.SKCenterLib_GetReturnCodeMessage(nCode))
nCode=skQ.SKQuoteLib_EnterMonitor()
print("EnterMonitor,", skC.SKCenterLib_GetReturnCodeMessage(nCode))

#讀取加權日k歷史報價
#bstrStockNo 放股票代碼
#sKLineType,0 = 1分鐘線, 3 =日線288天, 4 =完整日線, 5 =週線, 6 =月線。
#sOutType, 0=舊版輸出格式, 1=新版輸出格式。新版格式一分日期與分時資料是各自一個欄位
#將data 佔存至  EventQ.KlineData
EventQ.KlineData=[]
#請求歷史報價,參數可能有出入,請自行參考最新官方 API 文件
nCode=skQ.SKQuoteLib_RequestKLine('TSEA',, sKLineType=4, sOutType=1)
#data 輸出
EventQ.KlineData[0:2]
#取1分k歷史報價
EventQ.KlineData=[]
tic=time.time()
nCode=skQ.SKQuoteLib_RequestKLine('TSEA', sKLineType=0, sOutType=1)
toc=time.time()
print('取得', len(EventQ.KlineData),  '筆1分k報價, 花費', round(toc-tic,2), '秒')