1+ # -*- coding: utf-8 -*-
2+ __author__ = 'Chunyou<[email protected] >' 3+
4+ from .comm import *
5+
6+
7+ class AbstractXApi (object ):
8+ is_connected = False
9+ user_login_field = None
10+ _lib_path = None
11+ _callbacks = []
12+ _is_market = True
13+ _xapi = None
14+ debug = False
15+
16+ def __init__ (self , xapi_lib_path , lib_path , is_market = True ):
17+ """
18+ create api from the lib_path
19+ :param lib_path:
20+ :return:
21+ """
22+ self ._lib_path = lib_path
23+ self ._is_market = is_market
24+ if xapi_lib_path :
25+ self ._xapi = CDLL (xapi_lib_path )
26+
27+ def init (self ):
28+ """
29+ load the lib
30+ :return:
31+ """
32+ pass
33+
34+ def get_last_error (self ):
35+ pass
36+
37+ def get_api_type (self ):
38+ return Nono
39+
40+ def get_api_version (self ):
41+ return "0.1"
42+
43+ def get_api_name (self ):
44+ return 'AbstractXApi'
45+
46+ def set_callbacks (self , callbacks ):
47+ if not isinstance (callbacks , list ):
48+ callbacks = [callbacks ]
49+ self ._callbacks = callbacks
50+
51+ def connect (self , path , server_info , user_info , count ):
52+ """
53+ Connect to the server.
54+ :param path:
55+ :param server_info:
56+ :param user_info:
57+ :param count:
58+ :return:
59+ """
60+ pass
61+
62+ def disconnect (self ):
63+ pass
64+
65+ def subscribe (self , instrument_ids , exchange_id = b'' ):
66+ """
67+ Subscribe market data for the given instruments.
68+ :param instrument_ids: [string], list of instrument ids.
69+ :param exchange_id: string, exchange id
70+ """
71+ pass
72+
73+ def unsubscribe (self , instrument_ids , exchange_id = b'' ):
74+ """
75+ Un-subscribe market data for the given instruments.
76+ :param instrument_ids: [string], list of instrument ids.
77+ :param exchange_id: string, exchange id
78+ """
79+ pass
80+
81+ def subscribe_quote (self , instrument_ids , exchange_id = b'' ):
82+ """
83+ Subscribe market data for the given instruments.
84+ :param instrument_ids: [string], list of instrument ids.
85+ :param exchange_id: string, exchange id
86+ """
87+ pass
88+
89+ def unsubscribe_quote (self , instrument_ids , exchange_id = b'' ):
90+ """
91+ Un-subscribe market data for the given instruments.
92+ :param instrument_ids: [string], list of instrument ids.
93+ :param exchange_id: string, exchange id
94+ """
95+ pass
96+
97+ def req_qry_instrument (self , instrument_id , exchange_id ):
98+ """
99+ get instrument info
100+ :param instrument_id: string
101+ :param exchange_id: string, exchange id
102+ :return:
103+ """
104+ pass
105+
106+ def req_qry_investor_position (self , instrument_id , exchange_id ):
107+ """
108+ get investor position
109+ :param instrument_id: string
110+ :param exchange_id: string
111+ :return:
112+ """
113+ pass
114+
115+ def req_qry_trading_account (self ):
116+ """
117+ get trading account info
118+ :return:
119+ """
120+ pass
121+
122+ def send_order (self , p_order , p_in_out , count ):
123+ """
124+ create a new order
125+ :param p_order:
126+ :param p_in_out:
127+ :param count:
128+ :return:
129+ """
130+ pass
131+
132+ def cancel_order (self , p_in , p_out , count ):
133+ """
134+ cancel an order
135+ :param p_in:
136+ :param p_out:
137+ :param count:
138+ :return:
139+ """
140+ pass
141+
142+ def send_quote (self , p_quote , p_ask_out , p_bid_out , count ):
143+ """
144+ create a new quote
145+ :param p_quote:
146+ :param p_ask_out:
147+ :param p_bid_out:
148+ :param count:
149+ :return:
150+ """
151+ pass
152+
153+ def cancel_quote (self , p_in , p_out , count ):
154+ """
155+ cancel a quote
156+ :param p_in:
157+ :param p_out:
158+ :param count:
159+ :return:
160+ """
161+ pass
162+
163+ def _on_response (self , response_type , p_api1 , p_api2 , double1 , double2 , ptr1 , size1 , ptr2 , size2 , ptr3 , size3 ):
164+ """
165+ callback from the queue
166+ :param response_type:
167+ :param p_api1:
168+ :param p_api2:
169+ :param double1:
170+ :param double2:
171+ :param ptr1:
172+ :param size1:
173+ :param ptr2:
174+ :param size2:
175+ :param ptr3:
176+ :param size3:
177+ :return:
178+ """
179+ if self .debug :
180+ print "Response: " , ord (response_type )
181+ if response_type == OnConnectionStatus .value :
182+ self ._on_connect_status (p_api2 , chr (int (double1 )), ptr1 , size1 )
183+ elif self ._callbacks :
184+ for callback in self ._callbacks :
185+ if response_type == OnRtnDepthMarketData .value :
186+ obj = cast (ptr1 , POINTER (DepthMarketDataField )).contents
187+ if self ._is_market :
188+ callback .on_market_rtn_depth_market_data (p_api2 , obj )
189+ elif response_type == OnRspQryInstrument .value :
190+ obj = cast (ptr1 , POINTER (InstrumentField )).contents
191+ callback .on_trading_rsp_qry_instrument (p_api2 , obj , bool (double1 ))
192+ elif response_type == OnRspQryTradingAccount .value :
193+ obj = cast (ptr1 , POINTER (AccountField )).contents
194+ callback .on_trading_rsp_qry_trading_account (p_api2 , obj , bool (double1 ))
195+ elif response_type == OnRspQryInvestorPosition .value :
196+ obj = cast (ptr1 , POINTER (PositionField )).contents
197+ callback .on_trading_rsp_qry_investor_position (p_api2 , obj , bool (double1 ))
198+ elif response_type == OnRspQrySettlementInfo .value :
199+ obj = cast (ptr1 , POINTER (SettlementInfoField )).contents
200+ callback .on_trading_rsp_qry_settlement_info (p_api2 , obj , bool (double1 ))
201+ elif response_type == OnRtnOrder .value :
202+ obj = cast (ptr1 , POINTER (OrderField )).contents
203+ callback .on_trading_rtn_order (p_api2 , obj )
204+ elif response_type == OnRtnTrade .value :
205+ obj = cast (ptr1 , POINTER (TradeField )).contents
206+ callback .on_trading_rtn_trade (p_api2 , obj )
207+ elif response_type == OnRtnQuote .value :
208+ obj = cast (ptr1 , POINTER (QuoteField )).contents
209+ callback .on_trading_rtn_quote (p_api2 , obj )
210+ elif response_type == OnRtnQuoteRequest .value :
211+ obj = cast (ptr1 , POINTER (QuoteRequestField )).contents
212+ callback .on_trading_rtn_quote_request (p_api2 , obj )
213+ elif response_type == OnRspQryHistoricalTicks .value :
214+ obj = cast (ptr1 , POINTER (TickField )).contents
215+ obj2 = cast (ptr2 , POINTER (HistoricalDataRequestField )).contents
216+ callback .on_trading_rsp_qry_historical_ticks (p_api2 , obj , obj2 , bool (double1 ))
217+ elif response_type == OnRspQryHistoricalBars .value :
218+ obj = cast (ptr1 , POINTER (BarField )).contents
219+ obj2 = cast (ptr2 , POINTER (HistoricalDataRequestField )).contents
220+ callback .on_trading_rsp_qry_historical_bars (p_api2 , obj , obj2 , bool (double1 ))
221+ elif response_type == OnRspQryInvestor .value :
222+ obj = cast (ptr1 , POINTER (InvestorField )).contents
223+ callback .on_trading_rsp_qry_investor (p_api2 , obj )
224+ elif response_type == OnFilterSubscribe .value :
225+ instrument = c_char_p (ptr1 ).value
226+ callback .on_trading_filter_subscribe (p_api2 , ExchangeType (double1 ), size1 , size2 , size3 , instrument )
227+ elif response_type == OnRtnError .value :
228+ obj = cast (ptr1 , POINTER (ErrorField )).contents
229+ if self ._is_market :
230+ callback .on_market_rsp_error (p_api2 , obj , bool (double1 ))
231+ else :
232+ callback .on_trading_rsp_error (p_api2 , obj , bool (double1 ))
233+
234+ def _on_connect_status (self , p_api , status , p_user_login_field , size ):
235+ """
236+ callback on connect status
237+ :param p_api: int
238+ :param status:
239+ :param p_user_login_field: POINT of RspUserLoginField
240+ :return:
241+ """
242+ # 连接状态更新
243+ self .is_connected = Done .value == status
244+
245+ obj = RspUserLoginField ()
246+
247+ if status in [Logined .value , Disconnected .value , Doing .value ] and size > 0 :
248+ obj = cast (p_user_login_field , POINTER (RspUserLoginField )).contents
249+ self .user_login_field = obj
250+
251+ if self ._callbacks :
252+ for callback in self ._callbacks :
253+ if self ._is_market :
254+ callback .on_market_connected (p_api , obj , status )
255+ else :
256+ callback .on_trading_connected (p_api , obj , status )
257+
258+ def invoke_log (self , func_name , ** kwargs ):
259+ for callback in self ._callbacks :
260+ if getattr (callback , func_name , None ):
261+ getattr (callback , func_name )(kwargs )
262+
263+ def make_response (self , response_type , p_api1 = None , p_api2 = None , double1 = 0 , double2 = 0 , ptr1 = None , size1 = 0 , ptr2 = None , size2 = 0 , ptr3 = None , size3 = 0 ):
264+ """
265+ Make a response manually, useful in backtesting class
266+ :param response_type:
267+ :param p_api1:
268+ :param p_api2:
269+ :param double1:
270+ :param double2:
271+ :param ptr1:
272+ :param size1:
273+ :param ptr2:
274+ :param size2:
275+ :param ptr3:
276+ :param size3:
277+ :return:
278+ """
279+ if p_api1 :
280+ p_api1 = id (p_api1 )
281+ if p_api2 :
282+ p_api2 = id (p_api2 )
283+ if ptr1 :
284+ ptr1 = byref (ptr1 )
285+ if size1 == 0 :
286+ size1 = 1
287+ if ptr2 :
288+ ptr2 = byref (ptr2 )
289+ if size2 == 0 :
290+ size2 = 1
291+ if ptr3 :
292+ ptr3 = byref (ptr3 )
293+ if size3 == 0 :
294+ size3 = 1
295+ return self ._on_response (response_type .value , p_api1 , p_api2 , double1 , double2 , ptr1 , size1 , ptr2 , size2 , ptr3 , size3 )
0 commit comments