Python交易API使用手冊
Python交易API流程說明
API驗證流程
STEP1
請先下載API元件,並使用您的程式登入元富API,登入測試環境。
STEP2
ROD下單、改單、刪單(依照數位API網站線上驗證下單內容,於您的程式進行委託下單)。
STEP3
IOC下單(依照數位API網站線上驗證下單內容,於您的程式進行委託下單)。
STEP4
FOK下單(依照數位API網站線上驗證下單內容,於您的程式進行委託下單)。
STEP5
下單完成後,於數位API網站線上驗證頁面輸入委託書號。
STEP6
以上3.4.5步驟均填入委託書號後,於數位API網站線上驗證頁面點選"驗證"。
STEP7
驗證成功後及驗證完成,須待人員審核,請稍待審核流程,方能開通權限。
關聯網站
Python交易API範例程式說明
1. 系統需求
-
Python 3.6以上版本
-
交易python package
-
須先以系統管理員身分執行路徑:MasterFutTradePy\RegOcx.bat,進行api元件註冊(檔案路徑不可存在中文)
2. 環境準備
1
安裝交易API package:
32位元(x86):pip install MasterTradePy-X.X.X-py3-none-win32.whl
64位元(x64):pip install MasterTradePy-X.X.X-py3-none-win_amd64.whl
※X.X.X為版號,請依據下載內容版號調整
2
建議可先參考執行Sample內容,確認執行下單交易內容後,再依此文件說明進行API開發
3. 執行Sample
1
取得驗證(第一次需驗證)
參數說明:
python sample.py {使用者名稱} {密碼} {是否連測試(True/False)} {是否單一帳號通過強制登入(True/False)} {是否連接競賽主機(True/False)}
參數範例:python sample.py N123456789 1234 True True False |
---|
根據取得結果在線上驗證回填結果,驗證成功後才可以開始使用
正式下單參數範例:python sample.py N123456789 1234 |
---|
2
選1
範例如圖
下單
3
選2
範例如圖
減量
4
選3
範例如圖
改價
5
選4
範例如圖
取消
6
選5, 取得所有下單資料
回補
7
選6、7
範例如圖
查庫存,查庫存(盤後)
8
選8、9
範例如圖
查保證金,查保證金(盤後)
9
選10
範例如圖
保證金組合試算
10
選11
範例如圖
全拆平組
4. 回報狀態事件
4.1 OnSystemEvent
系統狀態事件回報 |
---|
def MasterFutTrade_OnSystemEvent(self, aMsg):
print(f'OnSystemEvent:\n{aMsg}')
4.2 OnAnnouncementEvent
期貨公告 |
---|
def MasterFutTradeAPI_OnAnnouncementEvent(self, aMsg):
print(f'OnAnnouncementEvent:\n{aMsg}')
4.3 OnConnEvent
期貨交易連線狀態 |
---|
def MasterFutTradeAPI_OnAnnouncementEvent(self, aMsg):
print(f'OnAnnouncementEvent:\n{aMsg}')
4.4 OnRecoverEvent
期貨交易回補 |
---|
def MasterFutTradeAPI_OnRecoverEvent(self, sender, aIsFinished, aErrMsg):
if aIsFinished:
print('期貨交易回補完成')
else:
print(f'期貨交易回補失敗!({aErrMsg})')
4.5 OnResultReportEvent
期貨交易即時結果回報 |
---|
def MasterFutTradeAPI_OnResultReportEvent(self, aReportData):
print('TReportData:')
sb = f"{aReportData.OrderStatus}|" #2:委託成功, 6:刪單成功, 71:部分成交, 72:完全成交, 11:錯誤單
sb += f"{aReportData.OrderID}|" #單號
sb += f"{aReportData.AccNo7}|" #交易帳號
sb += f"{int(aReportData.Market)}|" #0:期貨/1:選擇權
sb += f"{aReportData.Symbol}|" #商品代碼
sb += f"{aReportData.Month}|" #交割月份
sb += f"{int(aReportData.CallPut)}|" #0:期貨/1:Call/2:Put
sb += f"{aReportData.StrikeP}|" #履約價
sb += f"{int(aReportData.BSType)}|" #0:None/1:買/2:賣
sb += f"{int(aReportData.PositionEffect)}|"
#0:Open/1:Close/2:Rolled/3:DayTradeOpen/4:Auto/5:AutoToday/7:ForceClose/10:TAIFEXAuto
sb += f"{aReportData.UserDefine}|" #自定資料
sb += f"{aReportData.SegMkt}|" #盤別
sb += f"{int(aReportData.PriType)}|" #0:None/1:Market/2:Limit/3:otMarketWithProtection/4:Stop/5:5topLimit
sb += f"{int(aReportData.TimeInForce)}|" #0:None/1:ROD/2:IOC/3:FOK/8:TFXQ
sb += f"{aReportData.Message}|" #訊息or錯誤訊息
sb += f"{aReportData.OriginalQty}|" #原委託數量 新單的委託數量
sb += f"{aReportData.OrderQty}|" #委託口數
sb += f"{aReportData.OrderPrice}|" #委託價
sb += f"{aReportData.OrderTime}|" #時間HHmmssfff
sb += f"{aReportData.DealPrice}|" #成交價格(均價)
sb += f"{aReportData.CumQty}|" #已成交數量
sb += f"{aReportData.DealTime}|" #成交時間HHmmssfff
sb += f"{aReportData.DelQty}|" #刪單數量
sb += f"{aReportData.SumDealAmt}" #成交總金額
print(sb)
4.6 OnGWQryConnEvent
GW查詢連線狀態 |
---|
def MasterFutTradeAPI_OnGWQryConnEvent(self, sender, aIsConn):
if aIsConn:
print("GW查詢連線 已連線")
self.event.set()
else:
print("GW查詢連線 未連線")
4.7 OnGWQryResFailEvent
GW查詢結果-失敗 |
---|
def MasterFutTradeAPI_OnGWQryResFailEvent(self, sender, aAccNo7, aQryKind, aErrMsg):
if aQryKind == MLApi_Fut_GWQrySSO.TQryKind.BALANCE: #查庫存
print(f'查詢庫存失敗!({aErrMsg})')
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.BALANCE_C: #查庫存(盤後盤)
print(f'查詢庫存(盤後盤)失敗!({aErrMsg})')
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.MARGIN_TOT: #查保證金
print(f'查保證金失敗!({aErrMsg})')
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.MARGIN_TOT_After: #查保證金(盤後盤)
print(f'查保證金(盤後盤)失敗!({aErrMsg})')
elif aQryKind ==MLApi_Fut_GWQrySSO.TQryKind.ComQueryB: #保證金組合試算結果
print(f'保證金組合試算失敗!({aErrMsg})')
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.ComBestB: #執行全拆平組結果
print(f'執行全拆平組結果失敗!({aErrMsg})')
4.8 OnGWQryResSuccEvent
GW查詢結果-成功 |
---|
def MasterFutTradeAPI_OnGWQryResSuccEvent(self, sender, aAccNo7, aQryKind, aResList):
if aQryKind == MLApi_Fut_GWQrySSO.TQryKind.BALANCE or aQryKind == MLApi_Fut_GWQrySSO.TQryKind.BALANCE_C:
for aRes in aResList:
sb = f"原碼商品:{aRes.原碼商品}|"
sb += f"BSType:{aRes.BSType}|"
sb += f"庫存口數:{aRes.庫存口數}|"
sb += f"庫存均價:{aRes.庫存均價}|"
sb += f"今日成交買口數:{aRes.今日成交買口數}|"
sb += f"今日買均價:{aRes.今日買均價}|"
sb += f"今日成交賣口數:{aRes.今日成交賣口數}|"
sb += f"今日賣均價:{aRes.今日賣均價}|"
sb += f"今日平倉損益:{aRes.今日平倉損益}|"
sb += f"MktType:{int(aRes.MktType)}|" #0:None/1:期貨/2:選擇權/4:複式
#腳1
sb += f"商品代碼:{aRes.商品代碼}|"
sb += f"交割月:{aRes.交割月}|"
sb += f"履約價:{aRes.履約價}|"
sb += f"CallPut:{aRes.CallPut}|"
#腳2
sb += f"商品代碼2:{aRes.商品代碼2}|"
sb += f"交割月2:{aRes.交割月2}|"
sb += f"履約價2:{aRes.履約價2}|"
sb += f"CallPut2:{aRes.CallPut2}"
# print(sb)
print(aRes)
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.MARGIN_TOT or aQryKind == MLApi_Fut_GWQrySSO.TQryKind.MARGIN_TOT_After:
aRes = aResList
sb = f"客戶名稱:{aRes.客戶名稱}|"
sb = f"風險指標:{aRes.風險指標}|"
sb += f"權益數A:{aRes.權益數A}|"
sb += f"存提:{aRes.存提}|"
sb += f"超額or追繳保證金:{aRes.超額or追繳保證金}|"
sb += f"本日期貨平倉損益淨額:{aRes.本日期貨平倉損益淨額}|"
sb += f"原始保證金:{aRes.原始保證金}|"
sb += f"維持保證金:{aRes.維持保證金}|"
sb += f"未沖銷期貨浮動損益:{aRes.未沖銷期貨浮動損益}|"
sb += f"本日餘額:{aRes.本日餘額}|"
sb += f"今日存款:{aRes.今日存款}|"
sb += f"今日提款:{aRes.今日提款}|"
sb += f"權利金收入與支出:{aRes.權利金收入與支出}|"
sb += f"未沖銷買方選擇權市值B:{aRes.未沖銷買方選擇權市值B}|"
sb += f"未沖銷賣方選擇權市值C:{aRes.未沖銷賣方選擇權市值C}|"
sb += f"前日餘額:{aRes.前日餘額}|"
sb += f"昨權益總值:{aRes.昨權益總值}|"
sb += f"權益總值:{aRes.權益總值}|"
sb += f"總維持率:{aRes.總維持率}|"
sb += f"有價證券抵繳總額:{aRes.有價證券抵繳總額}|"
sb += f"有價證券可用餘額:{aRes.有價證券可用餘額}|"
sb += f"可動用保證金:{aRes.可動用保證金}|"
sb += f"加收保證金:{aRes.加收保證金}|"
sb += f"手續費:{aRes.手續費}|"
sb += f"期交稅:{aRes.期交稅}|"
sb += f"到期履約損益:{aRes.到期履約損益}"
print(sb)
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.ComQueryB: #保證金組合試算結果
for aRes in aResList:
sb = f"AccNo7:{aRes.AccNo7}|"
sb += f"OrgString1:{aRes.OrgString1}|"
sb += f"OrgString2:{aRes.OrgString2}|"
sb += f"Symbol1:{aRes.Symbol1}|"
sb += f"Symbol2:{aRes.Symbol2}|"
sb += f"CallPut1:{aRes.CallPut1}|"
sb += f"CallPut2:{aRes.CallPut2}|"
sb += f"Date1:{aRes.Date1}|"
sb += f"Date2:{aRes.Date2}|"
sb += f"StrikePrice1:{aRes.StrikePrice1}|"
sb += f"StrikePrice2:{aRes.StrikePrice2}|"
sb += f"BuySell1:{aRes.BuySell1}|"
sb += f"BuySell2:{aRes.BuySell2}|"
sb += f"Qty:{aRes.Qty}|"
sb += f"SingleMargin:{aRes.SingleMargin}|"
sb += f"ComboMargin:{aRes.ComboMargin}|"
print(sb)
elif aQryKind == MLApi_Fut_GWQrySSO.TQryKind.ComBestB:
print(aResList)
Python交易API實作使用說明
1. 連線connect
ms.connect(user, password)
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
username | Input | str | 使用者ID |
password | Input | str | 使用者密碼 |
2. 下單
newObj = SubNewOrderMessage()
newObj.AccountFlag = "1" #投資人身份碼(註:預帶1=國內自然人)
if input("選擇權(O)/期貨(任意輸入): ") == 'O': #市場別(期貨、選擇權)
newObj.Market = SpeedyAPI.MarketEnum.mOptions
else:
newObj.Market = SpeedyAPI.MarketEnum.mFutures
newObj.Side = SpeedyAPI.SideEnum.sBuy#買賣別(買:SpeedyAPI.SideEnum.sBuy/賣:SpeedyAPI.SideEnum.sSell)
newObj.Symbol = input("商品代號: ") #商品委託代碼
newObj.OrderQty = int(input("買口數: ")) #委託口數
newObj.Price = Double.Parse(input("買價: "))#委託價(註:若有小數點,小數位數要補滿8碼, 以免double精準度不夠)
newObj.OrderType = SpeedyAPI.OrderTypeEnum.otLimit #限市價
newObj.TimeInForce = SpeedyAPI.TimeInForceEnum.tifROD #ROD、IOC、FOR
newObj.PositionEffect = SpeedyAPI.PositionEffectEnum.peClose; #新平倉
newObj.TradingSessionID = SpeedyAPI.TradingSessionIDEnum.tsAuto
if newObj.Market == SpeedyAPI.MarketEnum.mOptions:
if input('C:Call/P:Put') == 'C':
newObj.EventTypeEnum = SpeedyAPI.EventTypeEnum.evtCall #Call、Put
elif input('C:Call/P:Put') == 'P':
newObj.EventTypeEnum = SpeedyAPI.EventTypeEnum.evtPut
newObj.StrikePrice = Double.Parse(input("履約價: ")) #履約價
spyObj = MSpeedyAPI.GetNewOrderMessage(newObj) #Speedy 新單元件
self.show_accno()
acc_index = int(input("選擇帳號: "))
result, sMsg = self.fMasterFutTradeAPI.SendNewOrder(spyObj, self.aAccList[acc_index], "USER_KEY_ORDER", "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
AccountFlag | Input | str | 投資人身份碼(註:預帶1=國內自然人) |
Market | Input | Enum | mFutures:期貨mOptions:選擇權 |
Side | Input | Enum | sBuy:買sSell:賣 |
Symbol | Input | str | 商品委託代碼(TXFC1、TXO17000C1) |
OrderQty | Input | Int | 委託口數 |
Price | Input | double | 委託價 |
OrderType | Input | Enum | otMarket:市價
otLimit:限價 otMarketWithProtection:一定範圍市價 |
TimeInForce | Input | Enum | tifROD:ROD
tifIOC:IOC tifFOK:FOK |
PositionEffect | Input | Enum | peOpen:新倉
peClose:平倉 peAuto:自動 |
TradingSessionID | Input | Enum | 請填:TradingSessionIDEnum.tsAuto |
EventTypeEnum | Output | Enum | evtCall:Call
evtPut:Put (選擇權商品者須填) |
StrikePrice | Input | double | 履約價(選擇權商品者須填, EX:17600) |
3. 改量
chgObj = SubReplaceOrderMessage() #Speedy 改單元件-減量
chgObj.OrderID = input("委託單號: ") #單號
chgObj.Symbol = input("商品代號: ") #原委託單的交易所委託代碼(EX:TXFF1)
chgObj.Side = SpeedyAPI.SideEnum.sBuy #買賣別
if input("選擇權(O)/期貨(任意輸入): ") == 'O':
chgObj.Market = SpeedyAPI.MarketEnum.mOptions
else:
chgObj.Market = SpeedyAPI.MarketEnum.mFutures
chgObj.OrderQty = int(input("減去口數: ")) #欲減口數
chgObj.OrderType = SpeedyAPI.OrderTypeEnum.otLimit #限市價
chgObj.TimeInForce = SpeedyAPI.TimeInForceEnum.tifROD #ROD、IOC、FOK
self.show_accno()
acc_index = int(input("選擇帳號: "))
spyObj = MSpeedyAPI.GetReplaceOrderMessage(chgObj)
result, sMsg = self.fMasterFutTradeAPI.SendChgOrder(spyObj, self.aAccList[acc_index], "USER_KEY_REPLACE", "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
OrderID | Input | str | 委託單號 |
Symbol | Input | str | 商品委託代碼(TXFC1、TXO17000C1) |
Side | Input | Enum | sBuy:買
sSell:賣 |
Market | Input | Enum | mFutures:期貨
mOptions:選擇權 |
OrderType | Input | Enum | otMarket:市價
otLimit:限價 otMarketWithProtection:一定範圍市價 |
TimeInForce | Input | Enum | tifROD:ROD
tifIOC:IOC tifFOK:FOK |
TimeInForce | Input | Int | 減量口數 |
4. 改價
chgObj = SubReplaceOrderMessage() #Speedy 改單元件-減量
chgObj.OrderID = input("委託單號: ") #單號
chgObj.Symbol = input("商品代號: ") #原委託單的交易所委託代碼(EX:TXFF1)
chgObj.Side = SpeedyAPI.SideEnum.sBuy #買賣別
if input("選擇權(O)/期貨(任意輸入): ") == 'O':
chgObj.Market = SpeedyAPI.MarketEnum.mOptions
else:
chgObj.Market = SpeedyAPI.MarketEnum.mFutures
chgObj.Price = Double.Parse(input("買價: ")) #價格
chgObj.OrderType = SpeedyAPI.OrderTypeEnum.otLimit #限市價
chgObj.TimeInForce = SpeedyAPI.TimeInForceEnum.tifROD #ROD、IOC、FOR
self.show_accno()
acc_index = int(input("選擇帳號: "))
spyObj = MSpeedyAPI.GetReplaceOrderMessage(chgObj)
result, sMsg = self.fMasterFutTradeAPI.SendChgOrder(spyObj, self.aAccList[acc_index], "USER_KEY_REPLACE", "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
OrderID | Input | str | 委託單號 |
Symbol | Input | str | 商品委託代碼(TXFC1、TXO17000C1) |
Side | Input | Enum | sBuy:買
sSell:賣 |
Market | Input | Enum | mFutures:期貨
mOptions:選擇權 |
OrderType | Input | Enum | otMarket:市價
otLimit:限價 otMarketWithProtection:一定範圍市價 |
TimeInForce | Input | Enum | tifROD:ROD
tifIOC:IOC tifFOK:FOK |
TimeInForce | Input | Int | 減量口數 |
5. 刪單
delObj = SubCancelOrderMessage()
delObj.OrderID = input("委託單號: ") #單號
delObj.Symbol = input("商品代號: ") #原委託單的交易所委託代碼(EX:TXFF1)
delObj.Side = SpeedyAPI.SideEnum.sBuy #買賣別
if input("選擇權(O)/期貨(任意輸入): ") == 'O': #市場別(0=期貨 1=選擇權)
delObj.Market = SpeedyAPI.MarketEnum.mOptions
else:
delObj.Market = SpeedyAPI.MarketEnum.mFutures
self.show_accno()
acc_index = int(input("選擇帳號: "))
spyObj = MSpeedyAPI.GetCancelOrderMessage(delObj)
result, sMsg = self.fMasterFutTradeAPI.SendDelOrder(spyObj, self.aAccList[acc_index], "USER_KEY_CALCEL", "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
OrderID | Input | str | 委託單號 |
Symbol | Input | str | 商品委託代碼(TXFC1、TXO17000C1) |
Side | Input | Enum | sBuy:買
sSell:賣 |
Market | Input | Enum | mFutures:期貨
mOptions:選擇權 |
6. 查詢庫存
result, sErrMsg = self.fMasterFutTradeAPI.SendGWQry(MLApi_Fut_GWQrySSO.TQryKind.BALANCE,
self.aAccList[acc_index].AccNo7, "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
aQryKind | Input | Enum | 請填入「TQryKind.BALANCE |
AccNo7 | Input | str | 七碼交易帳號 |
ErrMsg | Input | str | 錯誤訊息 |
7. 查詢庫存(盤後盤)
result, sErrMsg = self.fMasterFutTradeAPI.SendGWQry(MLApi_Fut_GWQrySSO.TQryKind.BALANCE_C,
self.aAccList[acc_index].AccNo7, "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
QryKind | Input | Enum | 請填入「TQryKind.BALANCE_C |
AccNo7 | Input | str | 七碼交易帳號 |
ErrMsg | Input | str | 錯誤訊息 |
8. 查保證金
result, sErrMsg = self.fMasterFutTradeAPI.SendGWQry(MLApi_Fut_GWQrySSO.TQryKind.MARGIN_TOT,
self.aAccList[acc_index].AccNo7, "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
QryKind | Input | Enum | 請填入「TQryKind.MARGIN_TOT |
AccNo7 | Input | str | 七碼交易帳號 |
ErrMsg | Input | str | 錯誤訊息 |
9. 查保證金(盤後盤)
result, sErrMsg = self.fMasterFutTradeAPI.SendGWQry(MLApi_Fut_GWQrySSO.TQryKind.MARGIN_TOT_After,
self.aAccList[acc_index].AccNo7, "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
QryKind | Input | Enum | 請填入「TQryKind.MARGIN_TOT_After」 |
AccNo7 | Input | str | 七碼交易帳號 |
ErrMsg | Input | str | 錯誤訊息 |
10. 保證金組合試算
result, sErrMsg = self.fMasterFutTradeAPI.SendGWQry_ComBest(MLApi_Fut_GWQrySSO.TQryKind.ComQueryB,
self.aAccList[acc_index].AccNo7, skind, "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
TQryKind | Input | Enum | 請填入「TQryKind.ComQueryB |
AccNo7 | Input | str | 七碼交易帳號 |
Kind | Input | str | Y=只有選擇權組單;N=可組非期交所全部組單 |
11. 全拆平組
result, sErrMsg = self.fMasterFutTradeAPI.SendGWQry_ComBest(MLApi_Fut_GWQrySSO.TQryKind.ComBestB,
self.aAccList[acc_index].AccNo7, skind, "")
參數 | In/Out | 類別 | 說明 |
---|---|---|---|
TQryKind | Input | Enum | 請填入「TQryKind. ComBestB」 |
AccNo7 | Input | str | 七碼交易帳號 |
Kind | Input | str | Y=只有選擇權組單;N=可組非期交所全部組單 |