# coding=utf-8 # __author__ == ypochien at gmail.com import json import os import struct from collections import namedtuple from ctypes import * from ctypes.wintypes import * t4_dir = os.path.dirname(__file__) api = windll.LoadLibrary(t4_dir + "/t4.dll") # API Part i. init_t4 = api.init_t4 init_t4.restype = c_char_p init_t4.argtypes = [c_char_p, c_char_p, c_char_p, ] add_acc_ca = api.add_acc_ca add_acc_ca.restype = c_char_p add_acc_ca.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] verify_ca_pass = api.verify_ca_pass verify_ca_pass.restype = c_char_p verify_ca_pass.argtypes = [c_char_p, c_char_p] # API Part ii. stock_order = api.stock_order stock_order.restype = c_char_p stock_order.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] stock_cancel = api.stock_cancel stock_cancel.restype = c_char_p stock_cancel.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] future_order = api.future_order future_order.restype = c_char_p future_order.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] future_cancel = api.future_cancel future_cancel.restype = c_char_p future_cancel.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] future_change = api.future_change future_change.restype = c_char_p future_change.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] option_order = api.option_order option_order.restype = c_char_p option_order.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] option_cancel = api.option_cancel option_cancel.restype = c_char_p option_cancel.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] ffuture_order = api.ffuture_order ffuture_order.restype = c_char_p ffuture_order.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] ffuture_cancel = api.ffuture_cancel ffuture_cancel.restype = c_char_p ffuture_cancel.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p] # API part iii. get_response = api.get_response get_response.restype = c_char_p get_response.argtypes = [] ff_get_response = api.ff_get_response ff_get_response.restype = c_char_p ff_get_response.argtypes = [] fo_unsettled_qty = api.fo_unsettled_qry fo_unsettled_qty.restype = c_char_p fo_unsettled_qty.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, ] fo_order_qry = api.fo_order_qry fo_order_qry.restype = c_char_p fo_order_qry.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, ] fo_order_qry2 = api.fo_order_qry2 fo_order_qry2.restype = c_char_p fo_order_qry2.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, ] ff_get_info = api.ff_get_info ff_get_info.restype = c_char_p ff_get_info.argtypes = [c_char_p, c_char_p, ] stock_balance_qry = api.stock_balance_qry stock_balance_qry.restype = c_char_p stock_balance_qry.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, ] stock_balance_sum = api.stock_balance_sum stock_balance_sum.restype = c_char_p stock_balance_sum.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, ] stock_balance_detail = api.stock_balance_detail stock_balance_detail.restype = c_char_p stock_balance_detail.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, ] ff_get_positions = api.ff_get_positions ff_get_positions.restype = c_char_p ff_get_positions.argtypes = [c_char_p, c_char_p, ] ff_order_qry = api.ff_order_qry ff_order_qry.restype = c_char_p ff_order_qry.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p, ] fo_get_day_info = api.fo_get_day_info fo_get_day_info.restype = c_char_p fo_get_day_info.argtypes = [c_char_p, c_char_p, ] fo_get_hist_info = api.fo_get_hist_info fo_get_hist_info.restype = c_char_p fo_get_hist_info.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p, ] # API Part iv. get_response_log = api.get_response_log get_response_log.restype = c_char_p get_response_log.argtypes = [] check_response_buffer = api.check_response_buffer check_response_buffer.restype = c_int check_response_buffer.argtypes = [] timer_response_log = api.timer_response_log timer_response_log.restype = c_char_p timer_response_log.argtypes = [] get_response_evt = api.get_response_evt get_response_evt.restype = HANDLE get_response_evt.argtypes = [] fifo_response = api.fifo_response fifo_response.restype = c_int fifo_response.argtypes = [] # API part v. change_echo = api.change_echo change_echo.restype = c_char_p change_echo.argtypes = [] log_out = api.log_out log_out.restype = c_int log_out.argtypes = [] show_version = api.show_version show_version.restype = c_char_p show_version.argtypes = [] show_list = api.show_list show_list.restype = c_char_p show_list.argtypes = [] show_list2 = api.show_list2 show_list2.restype = c_char_p show_list2.argtypes = [] show_ip = api.show_ip show_ip.restype = c_char_p show_ip.argtypes = [] do_register = api.do_register do_register.restype = c_int do_register.argtypes = [c_int] def decorate_to_utf8(func): """只要參數是str就要to cp950給t4.dll 只要回傳值是bytes就要to utf8給 Api caller""" def func_wrapper(*args): new_args = list(args) for idx, arg in enumerate(args): if isinstance(arg, str): new_args[idx] = args[idx].encode('utf-8') res = func(*new_args) if isinstance(res, bytes): return str(res, 'cp950') else: return res return func_wrapper def convert_stock_bytes_to_dict(stock_order_res_bytes): """委託回報為bytes。所以先轉為有結構的NameTuple,但每個item得從bytes to utf8""" stock_record_field = 'trade_type,account,code_id,ord_price,ord_qty,ord_seq,ord_date,effective_date,' \ 'ord_time,ord_no,ord_soruce,org_ord_seq,ord_bs,ord_type,market_id,price_type,ord_status,Msg' StockOrderRecord = namedtuple('StockOrderRecord', stock_record_field) stock_order_res_format = '2s15s6s6s3s6s8s8s6s5s3s6s1s2s1s1s2s60s' if len(stock_order_res_bytes) != struct.calcsize(stock_order_res_format): return stock_order_res_bytes stock_order_res = StockOrderRecord._make(struct.unpack_from(stock_order_res_format, stock_order_res_bytes)) stock_order_res_lst = [str(item, 'cp950') for item in stock_order_res] return StockOrderRecord(*stock_order_res_lst)._asdict() def convert_future_bytes_to_dict(future_order_res_bytes): future_record_field = 'trade_type,account,market_id,code_id,f_callput,ord_bs,ord_price,price_type,ord_qty,' \ 'ord_no,ord_seq,ord_type,oct_type,f_mttype,f_composit,c_futopt,c_code,c_callput,' \ 'c_buysell,c_price,c_quantity,ord_date,preord_date,ord_time,type,err_code,msg' FutureOrderRecord = namedtuple('FutureOrderRecord', future_record_field) future_order_res_format = '2s15s1s10s1s1s12s3s4s6s6s3s1s1s2s1s10s1s1s12s4s8s8s6s1s4s60s' if len(future_order_res_bytes) != struct.calcsize(future_order_res_format): return future_order_res_bytes future_order_res = FutureOrderRecord._make(struct.unpack_from(future_order_res_format, future_order_res_bytes)) future_order_res_lst = [str(item, 'cp950') for item in future_order_res] return FutureOrderRecord(*future_order_res_lst)._asdict() class T4(object): @classmethod @decorate_to_utf8 def init_t4(cls, *args): return init_t4(*args) @classmethod @decorate_to_utf8 def show_ip(cls, *args): return show_ip(*args) @classmethod @decorate_to_utf8 def show_version(cls): return show_version() @classmethod @decorate_to_utf8 def do_register(cls, reg): return do_register(reg) @classmethod @decorate_to_utf8 def add_acc_ca(cls, branch, account, account_id, ca_path, ca_password): return add_acc_ca(branch, account, account_id, ca_path, ca_password) @classmethod @decorate_to_utf8 def show_list(cls): return show_list() @classmethod @decorate_to_utf8 def show_list2(cls): return show_list2() @classmethod @decorate_to_utf8 def init_t4(cls, *args): return init_t4(*args) @classmethod @decorate_to_utf8 def add_acc_ca(cls, *args): return add_acc_ca(*args) @classmethod @decorate_to_utf8 def verify_ca_pass(cls, *args): return verify_ca_pass(*args) @classmethod @decorate_to_utf8 def stock_order(cls, *args): return convert_stock_bytes_to_dict(stock_order(*args)) @classmethod @decorate_to_utf8 def stock_cancel(cls, *args): return convert_stock_bytes_to_dict(stock_cancel(*args)) @classmethod @decorate_to_utf8 def future_order(cls, *args): return convert_future_bytes_to_dict(future_order(*args)) @classmethod @decorate_to_utf8 def future_cancel(cls, *args): return future_cancel(*args) @classmethod @decorate_to_utf8 def future_change(cls, *args): return future_change(*args) @classmethod @decorate_to_utf8 def option_order(cls, *args): return option_order(*args) @classmethod @decorate_to_utf8 def option_cancel(cls, *args): return option_cancel(*args) @classmethod @decorate_to_utf8 def ffuture_order(cls, *args): return ffuture_order(*args) @classmethod @decorate_to_utf8 def ffuture_cancel(cls, *args): return ffuture_cancel(*args) @classmethod @decorate_to_utf8 def get_response(cls, *args): return get_response(*args) @classmethod @decorate_to_utf8 def ff_get_response(cls, *args): return ff_get_response(*args) @classmethod @decorate_to_utf8 def fo_unsettled_qty(cls, *args): return fo_unsettled_qty(*args) @classmethod @decorate_to_utf8 def fo_order_qry(cls, *args): return fo_order_qry(*args) @classmethod @decorate_to_utf8 def fo_order_qry2(cls, *args): return fo_order_qry2(*args) @classmethod @decorate_to_utf8 def ff_get_info(cls, *args): return ff_get_info(*args) @classmethod @decorate_to_utf8 def stock_balance_qry(cls, *args): return stock_balance_qry(*args) @classmethod @decorate_to_utf8 def stock_balance_sum(cls, *args): return stock_balance_sum(*args) @classmethod @decorate_to_utf8 def stock_balance_detail(cls, *args): return stock_balance_detail(*args) @classmethod @decorate_to_utf8 def ff_get_positions(cls, *args): return ff_get_positions(*args) @classmethod @decorate_to_utf8 def ff_order_qry(cls, *args): return ff_order_qry(*args) @classmethod @decorate_to_utf8 def fo_get_day_info(cls, *args): return fo_get_day_info(*args) @classmethod @decorate_to_utf8 def fo_get_hist_info(cls, *args): return fo_get_hist_info(*args) @classmethod @decorate_to_utf8 def get_response_log(cls, *args): return get_response_log(*args) @classmethod @decorate_to_utf8 def check_response_buffer(cls, *args): return check_response_buffer(*args) @classmethod @decorate_to_utf8 def timer_response_log(cls, *args): return timer_response_log(*args) @classmethod @decorate_to_utf8 def get_response_evt(cls, *args): return get_response_evt(*args) @classmethod @decorate_to_utf8 def fifo_response(cls, *args): return fifo_response(*args) @classmethod @decorate_to_utf8 def change_echo(cls, *args): return change_echo(*args) @classmethod @decorate_to_utf8 def log_out(cls, *args): return log_out(*args) if __name__ == '__main__': with open('../OrderAPI.json') as fd_json: UserInfo = json.load(fd_json) msg = T4.init_t4(UserInfo['UserId'], UserInfo['Password'], '') print(msg) print(T4.show_version()) print(T4.show_ip()) print(T4.show_list()) print(T4.do_register(1)) print(T4.show_list2())