|
21 | 21 | } |
22 | 22 | QUOTE_KEYS_MAPPINGS = {field.value: field.name for field in QuoteChangeKey} # like {'askPrice': 'ask_price'} |
23 | 23 | QUOTE_KEYS_MAPPINGS.update(HOUR_TRADING_QUOTE_KEYS_MAPPINGS) |
| 24 | +PRICE_FIELDS = {'open', 'high', 'low', 'close', 'prev_close', 'ask_price', 'bid_price', 'latest_price'} |
24 | 25 |
|
25 | 26 | ASSET_KEYS_MAPPINGS = {'buyingPower': 'buying_power', 'cashBalance': 'cash', |
26 | 27 | 'grossPositionValue': 'gross_position_value', |
27 | 28 | 'netLiquidation': 'net_liquidation', 'equityWithLoan': 'equity_with_loan', |
28 | 29 | 'initMarginReq': 'initial_margin_requirement', |
29 | 30 | 'maintMarginReq': 'maintenance_margin_requirement', |
30 | 31 | 'availableFunds': 'available_funds', 'excessLiquidity': 'excess_liquidity', |
31 | | - 'dayTradesRemaining': 'day_trades_remaining', 'currency': 'currency'} |
| 32 | + 'dayTradesRemaining': 'day_trades_remaining', 'currency': 'currency', 'segment': 'segment'} |
32 | 33 |
|
33 | 34 | POSITION_KEYS_MAPPINGS = {'averageCost': 'average_cost', 'position': 'quantity', 'latestPrice': 'market_price', |
34 | 35 | 'marketValue': 'market_value', 'orderType': 'order_type', 'realizedPnl': 'realized_pnl', |
35 | 36 | 'unrealizedPnl': 'unrealized_pnl', 'secType': 'sec_type', 'localSymbol': 'local_symbol', |
36 | 37 | 'originSymbol': 'origin_symbol', 'contractId': 'contract_id', 'symbol': 'symbol', |
37 | | - 'currency': 'currency', 'strike': 'strike', 'expiry': 'expiry', 'right': 'right'} |
| 38 | + 'currency': 'currency', 'strike': 'strike', 'expiry': 'expiry', 'right': 'right', |
| 39 | + 'segment': 'segment'} |
38 | 40 |
|
39 | 41 | ORDER_KEYS_MAPPINGS = {'parentId': 'parent_id', 'orderId': 'order_id', 'orderType': 'order_type', |
40 | 42 | 'limitPrice': 'limit_price', 'auxPrice': 'aux_price', 'avgFillPrice': 'avg_fill_price', |
41 | 43 | 'totalQuantity': 'quantity', 'filledQuantity': 'filled', 'lastFillPrice': 'last_fill_price', |
42 | | - 'realizedPnl': 'realized_pnl', 'secType': 'sec_type', |
| 44 | + 'realizedPnl': 'realized_pnl', 'secType': 'sec_type', 'symbol': 'symbol', |
43 | 45 | 'remark': 'reason', 'localSymbol': 'local_symbol', 'originSymbol': 'origin_symbol', |
44 | 46 | 'outsideRth': 'outside_rth', 'timeInForce': 'time_in_force', 'openTime': 'order_time', |
45 | 47 | 'latestTime': 'trade_time', 'contractId': 'contract_id', 'trailStopPrice': 'trail_stop_price', |
46 | 48 | 'trailingPercent': 'trailing_percent', 'percentOffset': 'percent_offset', 'action': 'action', |
47 | | - 'status': 'status', 'currency': 'currency', 'remaining': 'remaining', 'id': 'id'} |
| 49 | + 'status': 'status', 'currency': 'currency', 'remaining': 'remaining', 'id': 'id', |
| 50 | + 'segment': 'segment'} |
48 | 51 |
|
49 | 52 | if sys.platform == 'linux' or sys.platform == 'linux2': |
50 | 53 | KEEPALIVE = True |
51 | 54 | else: |
52 | 55 | KEEPALIVE = False |
53 | 56 |
|
54 | 57 |
|
55 | | -class PushClient(object): |
| 58 | +class PushClient(stomp.ConnectionListener): |
56 | 59 | def __init__(self, host, port, use_ssl=True, connection_timeout=120, auto_reconnect=True, |
57 | 60 | heartbeats=(30 * 1000, 30 * 1000)): |
58 | 61 | """ |
@@ -155,12 +158,34 @@ def on_message(self, headers, body): |
155 | 158 | hour_trading = True |
156 | 159 | if 'symbol' in data: |
157 | 160 | symbol = data.get('symbol') |
| 161 | + offset = data.get('offset', 0) |
158 | 162 | items = [] |
159 | | - for key, value in data.items(): |
160 | | - if (key == 'latestTime' or key == 'hourTradingLatestTime') and isinstance(value, six.string_types): |
161 | | - continue |
162 | | - if key in QUOTE_KEYS_MAPPINGS: |
163 | | - items.append((QUOTE_KEYS_MAPPINGS.get(key), value)) |
| 163 | + # 期货行情推送的价格都乘了 10 的 offset 次方变成了整数, 需要除回去变为正常单位的价格 |
| 164 | + if offset: |
| 165 | + for key, value in data.items(): |
| 166 | + if (key == 'latestTime' or key == 'hourTradingLatestTime') and \ |
| 167 | + isinstance(value, six.string_types): |
| 168 | + continue |
| 169 | + if key in QUOTE_KEYS_MAPPINGS: |
| 170 | + key = QUOTE_KEYS_MAPPINGS.get(key) |
| 171 | + if key in PRICE_FIELDS: |
| 172 | + value /= 10 ** offset |
| 173 | + elif key == 'minute': |
| 174 | + minute_item = dict() |
| 175 | + for m_key, m_value in value.items(): |
| 176 | + if m_key in {'p', 'h', 'l'}: |
| 177 | + m_value /= 10 ** offset |
| 178 | + minute_item[m_key] = m_value |
| 179 | + value = minute_item |
| 180 | + items.append((key, value)) |
| 181 | + else: |
| 182 | + for key, value in data.items(): |
| 183 | + if (key == 'latestTime' or key == 'hourTradingLatestTime') and \ |
| 184 | + isinstance(value, six.string_types): |
| 185 | + continue |
| 186 | + if key in QUOTE_KEYS_MAPPINGS: |
| 187 | + key = QUOTE_KEYS_MAPPINGS.get(key) |
| 188 | + items.append((key, value)) |
164 | 189 | if items: |
165 | 190 | self.quote_changed(symbol, items, hour_trading) |
166 | 191 | elif response_type == str(ResponseType.SUBSCRIBE_ASSET.value): |
|
0 commit comments