2019年7月10日 星期三

SKQuoteLib_RequestFutureTradeInfo 出現 LP_c_short error



今日測試  SKQuoteLib_RequestFutureTradeInfo(0, 'TX00'),出現如下 error


---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)
 in ()
      1 import ctypes
----> 2 skQ.SKQuoteLib_RequestFutureTradeInfo(50, 'TX12')

ArgumentError: argument 1: : expected LP_c_short instance instead of int


看起來參數的型態不對,LP_c_short << 這個看起來很像 ctypes 會遇到的東西,所以我用 ctypes 試試看,轉換型別一下

import ctypes
skQ.SKQuoteLib_RequestFutureTradeInfo(ctypes.c_short(0), 'TX00')

恩  成功了!!!

2019年7月5日 星期五

tick data 轉換成 k Bar

轉換tick資料成 k bar,做個記錄
有筆 tick csv 資料如下
TX00Ticks.csv
Name,nPtr,nDate,nTimehms,nTimemillismicros,nBid,nAsk,nClose,nQty
TX00,119,20190624,150000,17000,10621.0,10623.0,10622.0,36
TX00,120,20190624,150000,38000,10621.0,10622.0,10621.0,2
TX00,121,20190624,150000,167000,10620.0,10622.0,10622.0,1
TX00,122,20190624,150000,199000,10620.0,10621.0,10620.0,1
TX00,123,20190624,150000,205000,10620.0,10621.0,10620.0,1
TX00,124,20190624,150000,304000,10620.0,10621.0,10620.0,1
TX00,125,20190624,150000,321000,10620.0,10621.0,10621.0,2

pandas
要對一排一排的 row 做處理的話,apply 要設定 axis=1

ref: pandas apply 的使用
http://jonathansoma.com/lede/foundations/classes/pandas%20columns%20and%20functions/apply-a-function-to-every-row-in-a-pandas-dataframe/

#斬大寫得更簡單!! https://ithelp.ithome.com.tw/articles/10223693



 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
import pandas as pd
from datetime import datetime

tick=pd.read_csv('TX00Ticks.csv')

#將三個column 的時間 轉成文字合併後,再用 datetime 轉成 datetime格式
def toDatetime(row):    
    t=str(row['nDate']) + ' ' + str(row['nTimehms']).zfill(6) + ' ' + str(row['nTimemillismicros'])
    return datetime.strptime(t, '%Y%m%d %H%M%S %f')

tick.index=tick.apply(toDatetime, axis=1)

tx1k=pd.DataFrame()
# 開 高 低 收 量
# T 是分鐘, 5分K就用 5T
tx1k['Open']=tick['nClose'].resample('T', label='right').first()
tx1k['High']=tick['nClose'].resample('T', label='right').max()
tx1k['Low']=tick['nClose'].resample('T', label='right').min()
tx1k['Close']=tick['nClose'].resample('T', label='right').last()
tx1k['Volume']=tick['nQty'].resample('T', label='right').sum()

2019年7月3日 星期三

群益API 更新至 2.13.17, Login 時錯誤訊息 "SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST"

群益API 更新至 2.13.17,這版本 Login 時會要求要先看過公告的訊息
否則會出現錯誤訊息 "SK_WARNING_REGISTER_REPLYLIB_ONREPLYMESSAGE_FIRST".

API文件寫說:

SKCenterLib初使化檢查是否接收SKReplyLib_OnReplyMessage公告訊息並回傳指定值VARIANT_TRUE,方可登入。

SKReplyLib_OnReplyMessage 文件又寫說,當 sConfirmCode 回傳 VARIANT_TRUE (0xFFFF),表示你看過公告了。官方沒附範例還真難理解要怎麼實做,一陣摸索後,寫了一個目前可以運作的版本。這更新真是擾民啊,可能要設計個介面讓人讀取公告後按確認,才能進行登入吧,我把它寫死了,固定回傳 0xFFFF ,也就是 VARIANT_TRUE



from comtypes.client import GetModule, CreateObject, GetEvents
GetModule(r'C:\SKCOM\CapitalAPI_2.13.17\x64\SKCOM.dll')
import comtypes.gen.SKCOMLib as sk
#建立COM物件
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)
#Configuration
ID=''
PW=''
#建立事件類別
class skQ_events:
    def OnConnection(self, nKind, nCode):
        if nCode == 0 :
            if nKind == 3001 :  print("連線中, nkind= ", nKind)
            elif nKind == 3003: print("連線成功, nkind= ", nKind)
class skR_events:
    def OnReplyMessage(self, bstrUserID, bstrMessage, sConfirmCode=0xFFFF):
        #根據API 手冊,login 前會先檢查這個 callback, 
        #要返回 VARIANT_TRUE 給 server,  表示看過公告了,我預設返回值是 0xFFFF
        print('OnReplyMessage', bstrUserID, bstrMessage)
        return sConfirmCode       
#Event sink, 事件實體  
EventQ=skQ_events()
EventR=skR_events()
#make connection to event sink
ConnQ = GetEvents(skQ, EventQ)
ConnR = GetEvents(skR, EventR)
print("Login,", skC.SKCenterLib_GetReturnCodeMessage(skC.SKCenterLib_Login(ID, PW)))

2019年6月14日 星期五

GetFutureRight example

示範一下 GetFutureRight 最簡版本

import time, pythoncom, sys
import comtypes.client as cc
#import skcom package
import comtypes.gen.SKCOMLib as sk
#Create com objects
skC = cc.CreateObject(sk.SKCenterLib, interface=sk.ISKCenterLib)
skO = cc.CreateObject(sk.SKOrderLib,interface=sk.ISKOrderLib)
#Order event handlers
class skO_events:
    def __init__(self):
        #TXAccount
        self.TXAcc=''
    def OnFutureRights(self, bstrData):
        print(bstrData)        
    def OnAccount(self, LogInID, AccountData):
        if AccountData.split(',')[0]=='TF':
            self.TXAcc= AccountData.split(',')[1]+ AccountData.split(',')[3]
            print('TXAcc', ID, self.TXAcc)

#implant event instances
EventO=skO_events()
#connect event to com object
EventO_conn=cc.GetEvents(skO,EventO)

#輸入身分證與密碼
ID=''
PW=''

#Login
nCode=skC.SKCenterLib_Login(ID,PW)
print('Login', skC.SKCenterLib_GetReturnCodeMessage(nCode))
#初始 Order 物件
nCode=skO.SKOrderLib_Initialize()
print("Initialize ", skC.SKCenterLib_GetReturnCodeMessage(nCode))
#Get User TF Account
nCode=skO.GetUserAccount()
print("GetUserAccount ", skC.SKCenterLib_GetReturnCodeMessage(nCode))
#GetFutureRights, 不能呼叫太頻繁,不然會出現 SK_ERROR_QUERY_IN_PROCESSING
nCode=skO.GetFutureRights(ID, EventO.TXAcc ,1)
print("GetFutureRights ", skC.SKCenterLib_GetReturnCodeMessage(nCode))

#每秒推一次 event, 推5秒
for i in range(5):
    pythoncom.PumpWaitingMessages()
    time.sleep(1)
#exit
sys.exit(0)