到目前2021年,kline 改變了不少,目前定位為 "歷史kline",只能取得當日以前的kline,若要取得當日kline,需要自己收集 tick 資料,自己組成 kline
可以參考:
################SKCOMAPI 2.13.17 以上版本適用##################
# 本範例要用 jupyter 來跑, 如果要在console 下跑,要加pythoncom來處理eventloop
# 本範例要用 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 skimport 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), '秒')
您好,感謝您的分享
回覆刪除想請教為何call getKline()之後
不用執行pythoncom.PumpWaitingMessages()
OnNotifyKLineData()也會被呼叫呢?
其實我也不知道耶,我也有這個疑問,不過確實呼叫getKline()後就可以經由OnNotifyKlineData()取得歷史報價,所以我就沒有細探了。你有試過我上面的方式得到歷史報價了嗎?
回覆刪除有喔,剛好在卡解COM structure物件的時候發現你的文章,覺得幸運 btw我也有在ML trading群裡
刪除最近看到山豆兒的文章,用pythonnet接群益報價,感覺很不錯,但我還沒研究,推薦給你看看他的做法
刪除https://kwedr.blogspot.tw/2017/07/api-python-pythonnet.html
加了你的line了,文,可以一起研究嗎
刪除這個line群,找不到, 我想加入一起討論
刪除被人放翻群機器人了,誰那麼無聊啊 ,我的天啊
刪除想加line群+1
刪除剛要從頭開始學python還請前輩多指教
賴被人放機器人把每個成員都踢掉了,不想再弄賴群了,改到FB社團好了,但目前沒有人氣就是了
刪除https://www.facebook.com/groups/1805224676441902/
好棒..總算有人用PYTHON連進群益...........好感謝您..可以加我嗎..
回覆刪除請問一下
回覆刪除在連結EnterMonitor後會透過OnConnection回傳連線狀態會慢幾秒
但是我是直接跑整個程式碼,變成他回傳會跑在我其他程式碼後,造成跳error
剛剛拜讀大大的程式碼後發現有加上"pumpwait"
這個是用來等資料回傳後再繼續跑我後續的程式碼嗎?!
你要等一等,等收到 OnConnection 回傳 3003 代碼後再開始跑其他程式碼,主要會影響的應該是需要登入報價伺服器的方法 像是SKQuoteLib_RequestStocks/ ticks 等。
刪除另外, 另外登錄報價伺服器前不要跑 skR.SKReplyLib_ConnectByID(),好像會無法讓 OnConnection 回傳 3003,這個要再測試我印像有點模糊了,至少可以先只跑EnterMonitor看看
感謝大大的回覆
刪除對~~我先跑EnterMoniter後他會先回傳0,然後OnConn會先回傳3001過一會再回傳3003
現在就是在思考如何等他回覆3003後在繼續後面的call data。因為我用timesleep(30),結果發現還是一樣等我程式跳error後才出現3003。感覺像室等我程式碼跑完才會回覆
我會再繼續找答案的。
感謝您
可以參考官方範例唷,在Onconnection裡寫個判斷式,如果出現3003,就呼叫你執行的function
刪除Onconnection():
if code==3003:
do_something()
喔喔喔~~
刪除好的~~感謝你
我參考以上寫法,
回覆刪除會出現"u'SK_ERROR_INITIALIZE_FAIL' "
請問一下有人遇到同樣問題嗎?
謝謝大家
看起來不像是 code 問題,你看看報價篇或 tick篇的你可以跑嗎? 你有沒有簽署API使用申請書之類的? 帳號密碼有對嗎?
刪除Eason非常感謝你的回覆, 我有簽署API使用,並對帳號跟密碼,然後再跑即時報價 出現Login, SK_ERROR_INITIALIZE_FAIL
刪除ConnectByID, SK_ERROR_LOGIN_FIRST
EnterMonitor, SK_ERROR_PERMISSION_TIMEOUT
我該如何找出問題點,感謝你的幫忙
我是用Anaconda2 and Anaconda3 的Spyder跑這程式,是否因為環境不同而有所影響
刪除我知道很多人都可以跑這程式,只是我試過很多方法,不知道自己哪一個環節出了問題 :)
刪除skcom.dll有照說明文件安裝嗎?skcom 與python位元版本有無一致,32/64bit, 作業系統用的是?
刪除comtypes 版本1.13以上?
還不行的話,到Fintech.py FB社團問問,看其他版友知不知道
Eason 真的很感謝你這麼晚了還幫忙細心解答,我現在重新照說明文件安裝,若成功的話,我會上來寫我成功了 :) 你真的很棒
刪除Eason感謝你,我拿另外一台電腦重新安裝已經可以動作了~ 謝謝你的幫忙:)
刪除你原本是用 XP 嗎? 還有 API 版本用太舊嗎?? 昨天拿舊電腦測試,發現API版本太舊,有出現你這個錯誤訊息!!
刪除Eason 我兩台都是Win 10 64位元, 一台是ThinkPad i5有異常,一台是ASUS i7這台是安裝正常,感謝你樂於分享你的程式給其他人,讓很多人受惠,有機會你可以開課~我願意付學費去跟你學習唷 :)
刪除請教一下,如果單純想用 Python 連結群益API 股票下單可行嗎?
回覆刪除最基本的功能而已:下單委買(賣)、查詢帳號庫存。謝謝
可行,使用上沒什麼問題,了解如何使用 comtypes 取用群益API後,剩下的就是看 API 文件的說明來操做了
刪除非常謝謝。你好神
刪除請問一下,我讀tick資料的時後發現由於tick太過頻繁
回覆刪除假設總共設定100筆股票資訊,但tick更新的只會更新前面50筆
有什麼方法可以解決嗎?
群益tick報價好像最多只有50檔,要再多要去另外申請的樣子,這可能要問營業員。如果你只是要收集tick資料,我目前是在盤後到 14:30 前,一檔一檔重新登錄,藉由 OnNotifyHistoryTicks 回補資料的方式取得,可你拿到當天所有ticks資料。
回覆刪除謝謝~~難怪我怎麼弄都拿不到資料~~QQ
刪除感謝,已經測試成功
回覆刪除想請教一下
def pumpwait(t=1):
for i in range(t):
time.sleep(1)
pythoncom.PumpWaitingMessages()
pumpwait(8) 是做何用?
這下面是我自己的理解,我太不懂這底層實際的運作。PumpWaitingMessages 是用來推出 event,讓收到的 event 可以被 event handler 處理, pumpwait 是我自己定義的function, 希望可以每秒叫一次 pumpWaitingMessages, 讓 event 能被處理,共持續8秒鐘。這只是我用來除錯用的,如果用 while loop 很難除錯
刪除你好, 請問出現這個錯誤該如何解決?
回覆刪除skC=cc.CreateObject(sk.SKCenterLib, interface=sk.ISKCenterLib)
OSError: [WinError -2147221164] 類別未登錄
很久沒遇到這樣的錯誤了,忘記怎麼發生的,好像沒有很難處理。你有正確安裝群益API嗎? 要用管理員權限安裝 API, API 跟 python 的位元版本要一致,然後重開機或重啟python IDE,有機會可以正常使用
刪除成功了,我API和python 位元版本不一致,剛剛重新調整後就可以執行了
刪除Eason 非常謝謝你!
您好
回覆刪除參考您的程式在登入的時候會出現SKReplyLib_OnReplyMessage
想請問這個問題該如何解決?
你是不是用2.13.17 的版本? 這個我也第一次遇到... 還不知道怎麼解
刪除我找到解法了,試試看
刪除login-skwarningregisterreplyl
請問 使用 SKCOMAPI 2.13.17 以上版本適用 程式 ,用 jupyter 來跑登入正常.
回覆刪除在 CapitalAPI_2.13.23 版本環境下
使用以下程式取得 分k資料
EventQ.KlineData=[]
nCode=skQ.SKQuoteLib_RequestKLine('TSEA', sKLineType=0, sOutType=1)
print('取得', len(EventQ.KlineData), '筆1分k報價')
螢幕可以看到,取得的資料,大概跑1-2分鐘.
最後顯示取得0筆1分k報價 , print(EventQ.KlineData)是空的,無法存入df中
請問該如何解決? 謝謝!
我偷懶只用印的,OnNotify裡面要另外處理,像是加 append 去處理,目前版本已調整,你再試試看。另外我最近用jupyterlab 處理 eventloop 好像機制有變,我用 %matplotlib auto 去處理 event ,很容易出問題,但我猜你是第一個的原因,
刪除新的skcomapi 2.13.23 以上適用,可以正確將k線放到EventQ.KlineData中,謝謝!
刪除不過新版程式中
import comtypes.gen.SKCOMLib as sk
.....
print('load module and event handler')
這段碼重複兩次,是故意的嗎?
痾不是故意的啦,不小心重複貼了
刪除