COCO研究院

 找回密碼
 註冊
搜索
查看: 15609|回復: 18

[其他程式語言] 請問有沒有大大是用Python串元大的API呢?

[複製鏈接]
發表於 19-2-8 16:58 | 顯示全部樓層 |閱讀模式
本帖最後由 Prochihua 於 19-2-8 17:44 編輯

最近趁著年假惡補了一下python

但是不想用元大提供的SmartAPI

想直接用Python呼叫API來使用

但是爬了幾天的文,沒看到完整範例可以參考的

目前比較有用的

http://hlfutures.blogspot.com/2016/08/api-in-python_8.html

根據裏面的提示加上爬文的結果

勉強拼出來一個可以執行的東西@@

  1. import win32com.client.CLSIDToClass, pythoncom,pywintypes
  2. import win32com.client.util
  3. import win32event
  4. import time

  5. defaultNamedOptArg=pythoncom.Empty
  6. defaultNamedNotOptArg=pythoncom.Empty
  7. defaultUnnamedArg=pythoncom.Empty

  8. class EventHandlers:

  9.     def __init__(self) :
  10.         #self.event = win32event.CreateEvent(None, 0, 0, None)
  11.         print "Init"

  12.     def OnLogonS(self, TLinkStatus=defaultNamedNotOptArg, AccList=defaultNamedNotOptArg, Casq=defaultNamedNotOptArg, Cast=defaultNamedNotOptArg):
  13.         print "OnLogonS"

  14.     def OnUserDefinsFuncResult(self, RowCount=defaultNamedNotOptArg, Results=defaultNamedNotOptArg, WorkID=defaultNamedNotOptArg):
  15.         print "OnUserDefinsFuncResult"


  16. yuanta=win32com.client.DispatchWithEvents("Yuanta.YuantaOrdCtrl.1",EventHandlers)

  17. yuanta.SetFutOrdConnection("ID","PW","api.yuantafutures.com.tw","80")


  18. yuanta.SendOrderF("01","0","F00","1234567","","","B","MXFB9","7900","1","","L","R","","")



  19. pythoncom.PumpWaitingMessages()
複製代碼

執行的結果

元大的API的確有被呼叫

這點可以從程式的回饋:print "Init" 得知

也可以看API的log檔:
20190208 14:13:28.448 YuantaOrd 1.6.1.3 for ActiveX control
20190208 14:13:28.448 Create
20190208 14:13:28.448 SetFutOrdConnection(ID,pw,api.yuantafutures.com.tw,80)
20190208 14:13:28.464 return: 3


表示有成功登入

但是正常後面會有:
20190208 14:47:38.702 OnLogonS(2,2-F00-1234567--王小明;2-P00-1234567--王小明,CN=身分證字號 Yuanta
OU=YUANTA,0)


不過我湊出來的這個沒有
且沒有執行到print "OnLogonS"也是可以得知

不曉得問題出在那裏,有大大可以提示一下嗎?




發表於 19-3-5 12:13 | 顯示全部樓層
你好,元大期貨api 我有試出一個版本

kwedr.blogspot.com/2018/11/api-with-python_29.htm

權限無所貼連結 抱歉

評分

參與人數 1金錢 +2 收起 理由
heavenweaver + 2 感謝分享

查看全部評分

回復 支持 2 反對 0

使用道具 舉報

 樓主| 發表於 19-2-12 22:28 | 顯示全部樓層
謝謝heavenweaver大大

當初看元大的說明PDF的時候沒注意,看成3是登入成功

又看到API的log上面也寫回傳值是3,就一直錯下去了@@


我後來是在OnLogonS那邊設一個全域變數

有呼叫到這個event的時候,表示已經登入成功了

然後把這個全域變數更改

然後用一個while迴圈,每隔一秒執行一次
pythoncom.PumpWaitingMessages()
直到那個全域變數被改變

def OnLogonS(self, TLinkStatus, AccList, Casq, Cast):
        print (TLinkStatus)
        global logined
        logined=1
        return;


logined=0

while logined==0:
        time.sleep(1)
        pythoncom.PumpWaitingMessages()

評分

參與人數 1金錢 +2 收起 理由
heavenweaver + 2 按一個讚

查看全部評分

回復 支持 1 反對 0

使用道具 舉報

發表於 19-2-9 00:51 | 顯示全部樓層
我使用Python 37-32版本,用你的程式跑出來的結果,都很正常呀!
20190209 00:38:03.590 YuantaOrd 1.6.1.3 for ActiveX control
20190209 00:38:03.590 Create
20190209 00:43:13.737 YuantaOrd 1.6.1.3 for ActiveX control
20190209 00:43:13.737 Create
20190209 00:43:13.737 SetFutOrdConnection(A123456789,pw,api.yuantafutures.com.tw,80)
20190209 00:43:13.753 return: 3
20190209 00:43:14.237 OnLogonS(4,2-P00-1234567--王小明,CN=TWA123456789 Yuanta
OU=YUANTA,2)
 樓主| 發表於 19-2-9 12:00 | 顯示全部樓層
本帖最後由 Prochihua 於 19-2-9 12:45 編輯

謝謝heavenweaver大大的測試

我之前是用Python 2.7

早上把2.7移除,安裝了3.7和pywin32

修改了一下print之後再執行

結果還是一樣@@

看來不是Python的版本問題

目前不曉得問題出在那裏@@
可以請問一下heavenweaver大大

yuanta.SendOrderF("01","0","F00","1234567","","","B","MXFB9","7900","1","","L","R","","")


這行您執行後,log檔裏面是顯示什麼嗎?


我這裏是顯示:

20190209 11:06:55.261 SendOrderF(01,0,F00,1234567,,,B,MXFB9,7900,1,,L,R,,)
20190209 11:06:55.261 return: |80000001|尚未登入(3)!



發表於 19-2-9 12:42 | 顯示全部樓層
我的憑證過期,所以顯示憑證無效,申請後重新連線,若正常會顯示正確的憑證代碼。
# -*- coding: UTF-8 -*-
#from win32com.client import CoClassBaseClass
import win32com.client.CLSIDToClass, pythoncom,pywintypes
import win32com.client.util
import win32event
import time

defaultNamedOptArg=pythoncom.Empty
defaultNamedNotOptArg=pythoncom.Empty
defaultUnnamedArg=pythoncom.Empty

class EventHandlers:
    def __init__(self) :
        self.event = win32event.CreateEvent(None, 0, 0, None)
        #print ("Init")
        return;

    def OnLogonS(self, TLinkStatus=defaultNamedNotOptArg, AccList=defaultNamedNotOptArg, Casq=defaultNamedNotOptArg, Cast=defaultNamedNotOptArg):
        win32event.SetEvent(self.event)
        #print ("OnLogonS")
        return;

    def OnUserDefinsFuncResult(self, RowCount=defaultNamedNotOptArg, Results=defaultNamedNotOptArg, WorkID=defaultNamedNotOptArg):
        win32event.SetEvent(self.event)
        #print "OnUserDefinsFuncResult"
        return;

yuanta=win32com.client.DispatchWithEvents("Yuanta.YuantaOrdCtrl.1",EventHandlers)
yuanta.SetFutOrdConnection("id","pw","api.yuantafutures.com.tw","80")
#yuanta.SendOrderF("01","0","F00","1234567","","","B","MXFB9","7900","1","","L","R","","")
pythoncom.PumpWaitingMessages()
------------------------------------------------------
20190209 12:31:52.086 YuantaOrd 1.6.1.3 for ActiveX control
20190209 12:31:52.086 Create
20190209 12:31:52.086 SetFutOrdConnection(A123456789,pw,api.yuantafutures.com.tw,80)
20190209 12:31:52.101 return: 3
20190209 12:31:52.554 OnLogonS(2,2-P0X-1234567--王小明,SN=9999AA9A,0)
 樓主| 發表於 19-2-9 12:59 | 顯示全部樓層
能否請問一下heavenweaver大大

您的作業系統是什麼版本嗎?

我找了另一台沒有安裝過python的電腦

重新安裝了python跟pywin32和元大的API

結果是一樣沒有OnLoginS的回饋

兩台電腦都是Win7 64bit的
發表於 19-2-9 13:30 | 顯示全部樓層
Prochihua 發表於 19-2-9 12:59
能否請問一下heavenweaver大大

您的作業系統是什麼版本嗎?

我的作業系統是Win10專業版,64位元。
會與作業系統有關嗎?

我照著說明用pip安裝pywin32時,顯示我的系統已安裝過了。
但是我想要 "system wide" features,所以又下了執行pywin32_postinstall.py的指令。
-----------------------------------------------
Installing via PIP
Note that PIP support is experimental.
You can install pywin32 via pip:
pip install pywin32

Note that if you want to use pywin32 for "system wide" features, such as registering COM objects or implementing Windows Services, then you must run the following command from an elevated command prompt:

python Scripts/pywin32_postinstall.py -install



 樓主| 發表於 19-2-9 14:47 | 顯示全部樓層
heavenweaver 發表於 19-2-9 13:30
我的作業系統是Win10專業版,64位元。
會與作業系統有關嗎?
我的作業系統是Win10專業版,64位元。
會與作業系統有關嗎?

我照著說明用pip安裝pywin32時,顯示我的系統已安裝過了。
但是我想要 "system wide" features,所以又下了執行pywin32_postinstall.py的指令。
不確定吶
我本來猜可能是32位元的系統跟64位元的系統的差別

不過兩個都是64位元

既然沒有頭緒,只好從有可能的開始下手

先把能排除的因素排除@@

由於要先備份一些東西才能重新安裝系統

看看有沒有其他大大也試試看並提供結果讓我們參考^^
 樓主| 發表於 19-2-9 15:43 | 顯示全部樓層
由於備份資料要花比較長的時間

所以就找了一台Win10 32bit的系統來試

由於試的時候沒有注意,程式碼裏面沒有寫入身份證字號和密碼

而是用ID跟PW

結果跑出來的結果:

20190209 15:40:34.894 YuantaOrd 1.6.1.3 for ActiveX control
20190209 15:40:34.894 Create
20190209 15:40:34.909 SetFutOrdConnection(id,pw,api.yuantafutures.com.tw,80)
20190209 15:40:34.918 return: 3
20190209 15:40:34.918 SendOrderF(01,0,F00,1234567,,,B,MXFB9,7900,1,,L,R,,)
20190209 15:40:34.918 return: |80000001|尚未登入(3)!

錯誤的帳號密碼,一樣是回傳 3 @@
當然,改回正確的帳號密碼之後,一樣是失敗的@@
 樓主| 發表於 19-2-9 19:55 | 顯示全部樓層
也試過更換win32com

原先是透過下載pywin32-221.win32-py3.7.exe 安裝

所以先移除它

然後執行pip install pypiwin32 安裝完成再執行

一樣的結果,還是失敗@@
 樓主| 發表於 19-2-10 22:13 | 顯示全部樓層
本帖最後由 Prochihua 於 19-2-10 22:17 編輯

終於找到問題出在那裏了,不是作業系統的問題

OnLogonS不是沒有反應

而是比較慢出來,而我之前只執行了一次pythoncom.PumpWaitingMessages()

OnLogonS還沒有來得及回應,程式就結束了@@

我每隔一秒執行一次pythoncom.PumpWaitingMessages()

兩秒多 OnLogonS才有回覆登入成功

(另一台電腦要三秒多)

然後再執行SendOrderF()就可以看到EasyWin上面有下單紀錄了

提供給Python+元大API的朋友參考

不過這個方法好像不適合元大的行情API

一呼叫就報錯@@

 樓主| 發表於 19-2-10 22:28 | 顯示全部樓層
另外

用win32com中的makepy.py產生的在gen_py中的參考檔

裏面有events的參數,那個不用像我最前面的那樣照抄
  1. class YuantaOrderEvent:
  2.     def __init__(self) :
  3.         #self.event = win32event.CreateEvent(None, 0, 0, None)
  4.         #print ("Init")
  5.         return;

  6.     def OnLogonS(self, TLinkStatus,AccList,Casq,Cast):
  7.         #win32event.SetEvent(self.event)
  8.         print (TLinkStatus)
  9.         print (AccList)
  10.         print (Casq)
  11.         print (Cast)
  12.         return;

  13.     def OnUserDefinsFuncResult(self, RowCount=defaultNamedNotOptArg, Results=defaultNamedNotOptArg, WorkID=defaultNamedNotOptArg):
  14.         #win32event.SetEvent(self.event)
  15.         #print "OnUserDefinsFuncResult"
  16.         return;
複製代碼


win32event的那些都可以不用

像OnLogonS那段那樣就可以取得事件回傳的資料
發表於 19-2-10 22:56 | 顯示全部樓層
元大的這套不支援 linux不然我還是習慣用linux的pytohn
發表於 19-2-12 11:23 | 顯示全部樓層
本帖最後由 heavenweaver 於 19-2-12 11:25 編輯
Prochihua 發表於 19-2-10 22:28
另外

用win32com中的makepy.py產生的在gen_py中的參考檔

線路連線中,當然要等到登入成功,才能下單。

   def OnLogonS(self, TLinkStatus=defaultNamedNotOptArg, AccList=defaultNamedNotOptArg, Casq=defaultNamedNotOptArg, Cast=defaultNamedNotOptArg):
        win32event.SetEvent(self.event)
        print("連線狀況=", TLinkStatus," 分行帳號=", AccList ,"  憑證號碼", Casq, " 憑證狀態",Cast)
        #print "OnLogonS"
        return;
...

iTLinkStatus = yuanta.SetFutOrdConnection("UID","UPW","api.yuantafutures.com.tw","80")
print ("連線狀況 TLinkStatus = ", iTLinkStatus)

通常連線狀況 TLinkStatus = 3,  代表:線路連線中

1 , lsConnected :LinkReady
2 , lsLogonOK: 登入成功
3 , lsConnecting :線路連線中
4 , lsCAError: 無效憑證
5 , lsPassError:密碼錯誤

既然是線路連線中,就要while loop稍等一下,

end_time = time.process_time() + 3
while time.process_time() < end_time:
        pythoncom.PumpWaitingMessages()

然後再進行下單指令

yuanta.SendOrderF("01","0","F00","1234567","","","B","MXFB9","10000","1","","L","R","","")

發表於 19-2-12 22:46 | 顯示全部樓層
Prochihua 發表於 19-2-12 22:28
謝謝heavenweaver大大

當初看元大的說明PDF的時候沒注意,看成3是登入成功

謝謝您起的頭,在此之前,還真的沒試過用Python串元大的API,也還不知道win32com 的makepy可以像OLE/COM Viewer一樣,產生類似IDL的py scripts。透過您的整合與範例,順便讓我進入win32com的學習領域,真是感激呀!

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

手機版|Archiver|站長信箱|廣告洽詢|COCO研究院

GMT+8, 24-10-31 16:17

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回復 返回頂部 返回列表
理財討論網站 |