httptrading 1.0.3__py3-none-any.whl → 1.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -82,6 +82,7 @@ class BaseBroker(ABC):
82
82
  direction: str,
83
83
  qty: int,
84
84
  price: float = None,
85
+ full_args: dict = None,
85
86
  **kwargs
86
87
  ) -> str:
87
88
  raise NotImplementedError
@@ -106,24 +106,24 @@ class Futu(SecuritiesBroker):
106
106
  @classmethod
107
107
  def code_to_contract(cls, code) -> Contract | None:
108
108
  region = ''
109
- ticker = ''
109
+ symbol = ''
110
110
  if m := re.match(r'^US\.(\S+)$', code):
111
111
  region = 'US'
112
- ticker = m.groups()[0]
112
+ symbol = m.groups()[0]
113
113
  if m := re.match(r'^HK\.(\d{5})$', code):
114
114
  region = 'HK'
115
- ticker = m.groups()[0]
115
+ symbol = m.groups()[0]
116
116
  if m := re.match(r'^SH\.(\d{6})$', code):
117
117
  region = 'CN'
118
- ticker = m.groups()[0]
118
+ symbol = m.groups()[0]
119
119
  if m := re.match(r'^SZ\.(\d{6})$', code):
120
120
  region = 'CN'
121
- ticker = m.groups()[0]
122
- if not region or not ticker:
121
+ symbol = m.groups()[0]
122
+ if not region or not symbol:
123
123
  return None
124
124
  return Contract(
125
125
  trade_type=TradeType.Securities,
126
- ticker=ticker,
126
+ symbol=symbol,
127
127
  region=region,
128
128
  )
129
129
 
@@ -131,16 +131,16 @@ class Futu(SecuritiesBroker):
131
131
  def contract_to_code(cls, contract: Contract) -> str | None:
132
132
  if contract.trade_type != TradeType.Securities:
133
133
  return None
134
- region, ticker = contract.region, contract.ticker
134
+ region, symbol = contract.region, contract.symbol
135
135
  code = None
136
- if region == 'CN' and re.match(r'^[56]\d{5}$', ticker):
137
- code = f'SH.{ticker}'
138
- elif region == 'CN' and re.match(r'^[013]\d{5}$', ticker):
139
- code = f'SZ.{ticker}'
140
- elif region == 'HK' and re.match(r'^\d{5}$', ticker):
141
- code = f'HK.{ticker}'
142
- elif region == 'US' and re.match(r'^\w+$', ticker):
143
- code = f'US.{ticker}'
136
+ if region == 'CN' and re.match(r'^[56]\d{5}$', symbol):
137
+ code = f'SH.{symbol}'
138
+ elif region == 'CN' and re.match(r'^[013]\d{5}$', symbol):
139
+ code = f'SZ.{symbol}'
140
+ elif region == 'HK' and re.match(r'^\d{5}$', symbol):
141
+ code = f'HK.{symbol}'
142
+ elif region == 'US' and re.match(r'^\w+$', symbol):
143
+ code = f'US.{symbol}'
144
144
  return code
145
145
 
146
146
  @classmethod
@@ -320,6 +320,7 @@ class Futu(SecuritiesBroker):
320
320
  direction: str,
321
321
  qty: int,
322
322
  price: float = None,
323
+ full_args: dict = None,
323
324
  **kwargs
324
325
  ) -> str:
325
326
  from futu import RET_OK, TrdSide, OrderType as FutuOrderType, TimeInForce as FutuTimeInForce, Session
@@ -398,6 +399,7 @@ class Futu(SecuritiesBroker):
398
399
  direction: str,
399
400
  qty: int,
400
401
  price: float = None,
402
+ full_args: dict = None,
401
403
  **kwargs
402
404
  ) -> str:
403
405
  return await self.call_sync(lambda : self._place_order(
@@ -408,6 +410,7 @@ class Futu(SecuritiesBroker):
408
410
  direction=direction,
409
411
  qty=qty,
410
412
  price=price,
413
+ full_args=full_args,
411
414
  **kwargs
412
415
  ))
413
416
 
@@ -62,21 +62,17 @@ class InteractiveBrokers(SecuritiesBroker):
62
62
  symbol = contract.symbol
63
63
  trade_type = TradeType.Securities
64
64
  region = ''
65
- ticker = ''
66
65
  if re.match(r'^[01356]\d{5}$', symbol):
67
66
  region = 'CN'
68
- ticker = symbol
69
67
  if re.match(r'^\d{5}$', symbol):
70
68
  region = 'HK'
71
- ticker = symbol
72
69
  if re.match(r'^\w{1,5}$', symbol):
73
70
  region = 'US'
74
- ticker = symbol
75
- if not region or not ticker:
71
+ if not region:
76
72
  return None
77
73
  return Contract(
78
74
  trade_type=trade_type,
79
- ticker=ticker,
75
+ symbol=symbol,
80
76
  region=region,
81
77
  )
82
78
 
@@ -86,7 +82,7 @@ class InteractiveBrokers(SecuritiesBroker):
86
82
  if contract in self._ib_contracts:
87
83
  return self._ib_contracts[contract]
88
84
  currency = self.contract_to_currency(contract)
89
- ib_contract = ib_insync.Stock(contract.ticker, 'SMART', currency=currency)
85
+ ib_contract = ib_insync.Stock(contract.symbol, 'SMART', currency=currency)
90
86
  client = self._client
91
87
  client.qualifyContracts(*[ib_contract, ])
92
88
  self._ib_contracts[contract] = ib_contract
@@ -205,6 +201,7 @@ class InteractiveBrokers(SecuritiesBroker):
205
201
  direction: str,
206
202
  qty: int,
207
203
  price: float = None,
204
+ full_args: dict = None,
208
205
  **kwargs
209
206
  ) -> str:
210
207
  import ib_insync
@@ -274,6 +271,7 @@ class InteractiveBrokers(SecuritiesBroker):
274
271
  direction: str,
275
272
  qty: int,
276
273
  price: float = None,
274
+ full_args: dict = None,
277
275
  **kwargs
278
276
  ) -> str:
279
277
  return await self.call_async(self._place_order(
@@ -284,6 +282,7 @@ class InteractiveBrokers(SecuritiesBroker):
284
282
  direction=direction,
285
283
  qty=qty,
286
284
  price=price,
285
+ full_args=full_args,
287
286
  **kwargs
288
287
  ))
289
288
 
@@ -188,24 +188,24 @@ class LongBridge(SecuritiesBroker):
188
188
  @classmethod
189
189
  def symbol_to_contract(cls, symbol: str) -> Contract | None:
190
190
  region = ''
191
- ticker = ''
191
+ contract_symbol = ''
192
192
  if m := re.match(r'^(\S+)\.US$', symbol):
193
193
  region = 'US'
194
- ticker = m.groups()[0]
194
+ contract_symbol = m.groups()[0]
195
195
  if m := re.match(r'^(\d{5})\.HK$', symbol):
196
196
  region = 'HK'
197
- ticker = m.groups()[0]
197
+ contract_symbol = m.groups()[0]
198
198
  if m := re.match(r'^(\d{6})\.SH$', symbol):
199
199
  region = 'CN'
200
- ticker = m.groups()[0]
200
+ contract_symbol = m.groups()[0]
201
201
  if m := re.match(r'^(\d{6})\.SZ$', symbol):
202
202
  region = 'CN'
203
- ticker = m.groups()[0]
204
- if not region or not ticker:
203
+ contract_symbol = m.groups()[0]
204
+ if not region or not contract_symbol:
205
205
  return None
206
206
  return Contract(
207
207
  trade_type=TradeType.Securities,
208
- ticker=ticker,
208
+ symbol=contract_symbol,
209
209
  region=region,
210
210
  )
211
211
 
@@ -213,16 +213,16 @@ class LongBridge(SecuritiesBroker):
213
213
  def contract_to_symbol(cls, contract: Contract) -> str:
214
214
  if contract.trade_type != TradeType.Securities:
215
215
  raise Exception(f'不能支持的交易品种{contract}映射为交易代码')
216
- region, ticker = contract.region, contract.ticker
216
+ region, symbol = contract.region, contract.symbol
217
217
  code = None
218
- if region == 'CN' and re.match(r'^[56]\d{5}$', ticker):
219
- code = f'{ticker}.SH'
220
- elif region == 'CN' and re.match(r'^[013]\d{5}$', ticker):
221
- code = f'{ticker}.SZ'
222
- elif region == 'HK' and re.match(r'^\d{5}$', ticker):
223
- code = f'{ticker}.HK'
224
- elif region == 'US' and re.match(r'^\w+$', ticker):
225
- code = f'{ticker}.US'
218
+ if region == 'CN' and re.match(r'^[56]\d{5}$', symbol):
219
+ code = f'{symbol}.SH'
220
+ elif region == 'CN' and re.match(r'^[013]\d{5}$', symbol):
221
+ code = f'{symbol}.SZ'
222
+ elif region == 'HK' and re.match(r'^\d{5}$', symbol):
223
+ code = f'{symbol}.HK'
224
+ elif region == 'US' and re.match(r'^\w+$', symbol):
225
+ code = f'{symbol}.US'
226
226
  if not code:
227
227
  raise Exception(f'不能映射{contract}为交易代码')
228
228
  return code
@@ -310,6 +310,7 @@ class LongBridge(SecuritiesBroker):
310
310
  direction: str,
311
311
  qty: int,
312
312
  price: float = None,
313
+ full_args: dict = None,
313
314
  **kwargs
314
315
  ) -> str:
315
316
  from longport.openapi import OrderType as LbOrderType, OrderSide, TimeInForceType, OutsideRTH
@@ -382,6 +383,7 @@ class LongBridge(SecuritiesBroker):
382
383
  direction: str,
383
384
  qty: int,
384
385
  price: float = None,
386
+ full_args: dict = None,
385
387
  **kwargs
386
388
  ) -> str:
387
389
  return await self.call_sync(lambda : self._place_order(
@@ -392,6 +394,7 @@ class LongBridge(SecuritiesBroker):
392
394
  direction=direction,
393
395
  qty=qty,
394
396
  price=price,
397
+ full_args=full_args,
395
398
  **kwargs
396
399
  ))
397
400
 
@@ -120,21 +120,17 @@ class Tiger(SecuritiesBroker):
120
120
  @classmethod
121
121
  def symbol_to_contract(cls, symbol) -> Contract | None:
122
122
  region = ''
123
- ticker = ''
124
123
  if re.match(r'^[01356]\d{5}$', symbol):
125
124
  region = 'CN'
126
- ticker = symbol
127
125
  if re.match(r'^\d{5}$', symbol):
128
126
  region = 'HK'
129
- ticker = symbol
130
127
  if re.match(r'^\w{1,5}$', symbol):
131
128
  region = 'US'
132
- ticker = symbol
133
- if not region or not ticker:
129
+ if not region:
134
130
  return None
135
131
  return Contract(
136
132
  trade_type=TradeType.Securities,
137
- ticker=ticker,
133
+ symbol=symbol,
138
134
  region=region,
139
135
  )
140
136
 
@@ -142,14 +138,14 @@ class Tiger(SecuritiesBroker):
142
138
  def contract_to_symbol(cls, contract: Contract) -> str | None:
143
139
  if contract.trade_type != TradeType.Securities:
144
140
  return None
145
- region, ticker = contract.region, contract.ticker
141
+ region, contract_symbol = contract.region, contract.symbol
146
142
  symbol = None
147
- if region == 'CN' and re.match(r'^[01356]\d{5}$', ticker):
148
- symbol = ticker
149
- elif region == 'HK' and re.match(r'^\d{5}$', ticker):
150
- symbol = ticker
151
- elif region == 'US' and re.match(r'^\w{1,5}$', ticker):
152
- symbol = ticker
143
+ if region == 'CN' and re.match(r'^[01356]\d{5}$', contract_symbol):
144
+ symbol = contract_symbol
145
+ elif region == 'HK' and re.match(r'^\d{5}$', contract_symbol):
146
+ symbol = contract_symbol
147
+ elif region == 'US' and re.match(r'^\w{1,5}$', contract_symbol):
148
+ symbol = contract_symbol
153
149
  return symbol
154
150
 
155
151
  def _positions(self):
@@ -281,6 +277,7 @@ class Tiger(SecuritiesBroker):
281
277
  direction: str,
282
278
  qty: int,
283
279
  price: float = None,
280
+ full_args: dict = None,
284
281
  **kwargs
285
282
  ) -> str:
286
283
  if contract.trade_type != TradeType.Securities:
@@ -360,6 +357,7 @@ class Tiger(SecuritiesBroker):
360
357
  direction: str,
361
358
  qty: int,
362
359
  price: float = None,
360
+ full_args: dict = None,
363
361
  **kwargs
364
362
  ) -> str:
365
363
  return await self.call_sync(lambda: self._place_order(
@@ -370,6 +368,7 @@ class Tiger(SecuritiesBroker):
370
368
  direction=direction,
371
369
  qty=qty,
372
370
  price=price,
371
+ full_args=full_args,
373
372
  **kwargs
374
373
  ))
375
374
 
@@ -31,11 +31,11 @@ class HttpTradingView(web.View):
31
31
  params: dict = await self.request.json() if from_json else self.request.query
32
32
  trade_type = TradeType[params.get('tradeType', '--')]
33
33
  region = params.get('region', '--')
34
- ticker = params.get('ticker', '--')
34
+ symbol = params.get('symbol', '--')
35
35
  contract = Contract(
36
36
  trade_type=trade_type,
37
37
  region=region,
38
- ticker=ticker,
38
+ symbol=symbol,
39
39
  )
40
40
  return contract
41
41
 
@@ -84,6 +84,7 @@ class PlaceOrderView(HttpTradingView):
84
84
  qty=qty,
85
85
  price=price,
86
86
  json=body_d,
87
+ full_args=body_d,
87
88
  )
88
89
  return self.response_api(broker, {
89
90
  'orderId': order_id,
@@ -162,28 +163,33 @@ class MarketStatusView(HttpTradingView):
162
163
  })
163
164
 
164
165
 
165
- @web.middleware
166
- async def auth_middleware(request: web.Request, handler):
167
- instance_id = request.match_info.get('instance_id', '')
168
- token = request.headers.get('HT-TOKEN', '')
169
- if not instance_id:
170
- raise web.HTTPNotFound
171
- if not token:
172
- raise web.HTTPNotFound
173
- if len(token) < 16 or len(token) > 64:
174
- raise web.HTTPNotFound
175
- for broker in HttpTradingView.brokers():
176
- if broker.instance_id != instance_id:
177
- continue
178
- if token not in broker.tokens:
166
+ def create_auth_middleware(token_header: str):
167
+ assert isinstance(token_header, str)
168
+ assert token_header
169
+
170
+ @web.middleware
171
+ async def _auth_middleware(request: web.Request, handler):
172
+ instance_id = request.match_info.get('instance_id', '')
173
+ token = request.headers.get(token_header, '')
174
+ if not instance_id:
175
+ raise web.HTTPNotFound
176
+ if not token:
177
+ raise web.HTTPNotFound
178
+ if len(token) < 16 or len(token) > 64:
179
179
  raise web.HTTPNotFound
180
- setattr(request, '__current_broker__', broker)
181
- break
182
- else:
183
- raise web.HTTPNotFound
184
- response: web.Response = await handler(request)
185
- delattr(request, '__current_broker__')
186
- return response
180
+ for broker in HttpTradingView.brokers():
181
+ if broker.instance_id != instance_id:
182
+ continue
183
+ if token not in broker.tokens:
184
+ raise web.HTTPNotFound
185
+ setattr(request, '__current_broker__', broker)
186
+ break
187
+ else:
188
+ raise web.HTTPNotFound
189
+ response: web.Response = await handler(request)
190
+ delattr(request, '__current_broker__')
191
+ return response
192
+ return _auth_middleware
187
193
 
188
194
 
189
195
  @web.middleware
@@ -218,6 +224,7 @@ def run(
218
224
  brokers: list[BaseBroker],
219
225
  std_apis: Callable[[], list[web.RouteDef]] = None,
220
226
  extend_apis: list[web.RouteDef] = None,
227
+ token_header: str = 'HT-TOKEN',
221
228
  **kwargs
222
229
  ) -> None:
223
230
  """
@@ -226,11 +233,12 @@ def run(
226
233
  @param brokers: 需要控制的交易通道对象列表
227
234
  @param std_apis: 如果需要替换默认提供的接口, 这里提供工厂函数的回调
228
235
  @param extend_apis: 如果需要增加自定义接口, 这里传入 RouteDef 列表
236
+ @param token_header: 定制 token 凭据的 header 键名
229
237
  @param kwargs: 其他的参数将传给 aiohttp.web.run_app 函数
230
238
  """
231
239
  app = web.Application(
232
240
  middlewares=[
233
- auth_middleware,
241
+ create_auth_middleware(token_header=token_header),
234
242
  exception_middleware,
235
243
  ],
236
244
  )
httptrading/model.py CHANGED
@@ -55,16 +55,16 @@ class Contract:
55
55
  """
56
56
  Contract 定义了交易品种的精确描述.
57
57
  根据交易种类, 区分为证券和加密货币;
58
- 根据 ticker 设置交易标的的代码;
58
+ 根据 symbol 设置交易标的的代码;
59
59
  对于支持多个市场的交易通道, 例如证券, 需要额外提供 region 加以区分标的的所属市场.
60
60
  """
61
61
  trade_type: TradeType
62
- ticker: str
62
+ symbol: str
63
63
  region: str
64
64
 
65
65
  @property
66
66
  def unique_pair(self):
67
- return self.trade_type, self.ticker, self.region,
67
+ return self.trade_type, self.symbol, self.region,
68
68
 
69
69
  def __hash__(self):
70
70
  return self.unique_pair.__hash__()
@@ -183,7 +183,7 @@ class JsonDefault:
183
183
  'type': 'contract',
184
184
  'tradeType': obj.trade_type.name,
185
185
  'region': obj.region,
186
- 'ticker': obj.ticker,
186
+ 'symbol': obj.symbol,
187
187
  }
188
188
  if isinstance(obj, Cash):
189
189
  return {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httptrading
3
- Version: 1.0.3
3
+ Version: 1.0.6
4
4
  Summary: 统一交易通道的接口服务
5
5
  Author-email: songwei <github@songwei.name>
6
6
  License: MIT
@@ -187,10 +187,10 @@ GET /httptrading/api/{instanceId}/market/quote
187
187
  | 参数 | 说明 | 举例 |
188
188
  |-----------|---------|--------------------|
189
189
  | tradeType | 说明标的的品种 | Securities: 证券 |
190
- | ticker | 代码 | QQQ, 00700, 000001 |
190
+ | symbol | 代码 | QQQ, 00700, 000001 |
191
191
  | region | 以国家区分代码 | US, HK, CN |
192
192
 
193
- 举例 ?tradeType=Securities&region=CN&ticker=000001 参数的结果:
193
+ 举例 ?tradeType=Securities&region=CN&symbol=000001 参数的结果:
194
194
  ```json lines
195
195
  {
196
196
  "type": "apiResponse",
@@ -205,7 +205,7 @@ GET /httptrading/api/{instanceId}/market/quote
205
205
  "type": "contract",
206
206
  "tradeType": "Securities",
207
207
  "region": "CN",
208
- "ticker": "000001"
208
+ "symbol": "000001"
209
209
  },
210
210
  "currency": "CNY", // 币种
211
211
  "isTradable": true, // 此时是否可交易, 比如受到停牌熔断影响
@@ -313,7 +313,7 @@ GET /httptrading/api/{instanceId}/position/state
313
313
  "type": "contract",
314
314
  "tradeType": "Securities",
315
315
  "region": "US",
316
- "ticker": "QQQ"
316
+ "symbol": "QQQ"
317
317
  },
318
318
  "unit": "Share",
319
319
  "currency": "USD",
@@ -333,7 +333,7 @@ POST /httptrading/api/{instanceId}/order/place
333
333
  | 参数 | 说明 | 举例 |
334
334
  |-------------|----------|--------------------------------------------------|
335
335
  | tradeType | 说明标的的品种 | Securities: 证券 |
336
- | ticker | 代码 | QQQ, 00700, 000001 |
336
+ | symbol | 代码 | QQQ, 00700, 000001 |
337
337
  | region | 以国家区分代码 | US, HK, CN |
338
338
  | price | 限价 | 市价单不填此项 |
339
339
  | qty | 订单数量, 整数 | |
@@ -346,7 +346,7 @@ POST /httptrading/api/{instanceId}/order/place
346
346
  ```json lines
347
347
  {
348
348
  "tradeType": "Securities",
349
- "ticker": "AAPL",
349
+ "symbol": "AAPL",
350
350
  "region": "US",
351
351
  "price": 200.00,
352
352
  "qty": 12,
@@ -369,7 +369,7 @@ POST /httptrading/api/{instanceId}/order/place
369
369
  "orderId": "69788888", // 订单号
370
370
  "args": { // 传递的参数
371
371
  "tradeType": "Securities",
372
- "ticker": "AAPL",
372
+ "symbol": "AAPL",
373
373
  "region": "US",
374
374
  "price": 200,
375
375
  "qty": 12,
@@ -0,0 +1,18 @@
1
+ httptrading/__init__.py,sha256=H2kepS94z3YQWMyvM7R3WVbP4iDYgwGssLcYG24dnPQ,306
2
+ httptrading/http_server.py,sha256=jj6mVhKly5C6fT1Ew6AMu4rG-7rlofs5FSvcCeIMJmk,9124
3
+ httptrading/model.py,sha256=2oWz3VIIMEiIEX6Jg4itBYdZtJbKEgTMzudvVk1cIJ8,7717
4
+ httptrading/broker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ httptrading/broker/base.py,sha256=P149UlFyy277y40qHPH9DdvbEy-j1x26QDllXV6XPMg,5664
6
+ httptrading/broker/futu_sec.py,sha256=ztK_vpKAs7qNIfNXcqv_FBWs4gvxoMdaWNjGfb7vodE,20081
7
+ httptrading/broker/interactive_brokers.py,sha256=Myl9dvPKRJ6EQ5nDFYzCLdkGc2k-wpzP6ISlImXkcaY,13218
8
+ httptrading/broker/longbridge.py,sha256=x_QqfiloCJ7bQl47zc6lXmApbRjA782LVOkdfqeYVpI,16282
9
+ httptrading/broker/tiger.py,sha256=tJpkZEayInOlxo2FSKVIHp7nXWBsVC4i6qrSsciNYeA,16226
10
+ httptrading/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ httptrading/tool/leaky_bucket.py,sha256=Bvab3Fkn16hhZ1-WLCFcPkbFH_bHHhQ9boLv8HrmGSE,2817
12
+ httptrading/tool/locate.py,sha256=vSIzd09FWKmckkgY3mWtFXQm2Z0VIKv4FCXHT44e61s,2748
13
+ httptrading/tool/time.py,sha256=7eVmZ_td72JLjsBRLjMOHklxltNbOxeN97uSLi7wvIA,2188
14
+ httptrading-1.0.6.dist-info/licenses/LICENSE,sha256=KfMSrfnpo-TOqpCTJqnbcZNl0w7ErxadsMQf8uas_tY,1093
15
+ httptrading-1.0.6.dist-info/METADATA,sha256=wtg2mMM7OJ4IsILR9IEt48Zn645wVyTITqkoC6sqWvs,17519
16
+ httptrading-1.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ httptrading-1.0.6.dist-info/top_level.txt,sha256=rsLGrGN6QubO9ILQRktwrWtxfGsGAmWUnQq7XksKu-4,12
18
+ httptrading-1.0.6.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- httptrading/__init__.py,sha256=H2kepS94z3YQWMyvM7R3WVbP4iDYgwGssLcYG24dnPQ,306
2
- httptrading/http_server.py,sha256=K2_KVZ5dU5UZilLtx51OYVRClrf_nTThIBVIDmU_v3k,8718
3
- httptrading/model.py,sha256=xa-psfYJuEzyR5aB776ErlX1CjhXDsAE2LuR6XI6h2I,7717
4
- httptrading/broker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- httptrading/broker/base.py,sha256=31oS32afiLG7aQa_x-6HwfDAAb2V67AFi3V497-7R0E,5627
6
- httptrading/broker/futu_sec.py,sha256=eYYBqx62w31tUBuMVhMkpTs5RWi7BMfYnywv1L-GTds,19973
7
- httptrading/broker/interactive_brokers.py,sha256=jyMNy2HZsLJiSJs77tZBI-XmICdOwcn1Rje4U9gwP-w,13232
8
- httptrading/broker/longbridge.py,sha256=whavvn4gC0K-iHy1cf4W0MjZxdG-t-JY1Gf9QeD5ioI,16111
9
- httptrading/broker/tiger.py,sha256=6z3DA888bcFf_r1_NraIAzODQrv_BCP0CnqyOddZDT8,16177
10
- httptrading/tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- httptrading/tool/leaky_bucket.py,sha256=Bvab3Fkn16hhZ1-WLCFcPkbFH_bHHhQ9boLv8HrmGSE,2817
12
- httptrading/tool/locate.py,sha256=vSIzd09FWKmckkgY3mWtFXQm2Z0VIKv4FCXHT44e61s,2748
13
- httptrading/tool/time.py,sha256=7eVmZ_td72JLjsBRLjMOHklxltNbOxeN97uSLi7wvIA,2188
14
- httptrading-1.0.3.dist-info/licenses/LICENSE,sha256=KfMSrfnpo-TOqpCTJqnbcZNl0w7ErxadsMQf8uas_tY,1093
15
- httptrading-1.0.3.dist-info/METADATA,sha256=mDEuve30H-9uTJ_CLI4NpOfoHeK99O2GrR3-Mzp-icY,17519
16
- httptrading-1.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- httptrading-1.0.3.dist-info/top_level.txt,sha256=rsLGrGN6QubO9ILQRktwrWtxfGsGAmWUnQq7XksKu-4,12
18
- httptrading-1.0.3.dist-info/RECORD,,