hyperquant 1.2__py3-none-any.whl → 1.21__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.
    
        hyperquant/broker/bitmart.py
    CHANGED
    
    | 
         @@ -30,6 +30,7 @@ class Bitmart: 
     | 
|
| 
       30 
30 
     | 
    
         
             
                    self.private_api = "https://derivatives.bitmart.com"
         
     | 
| 
       31 
31 
     | 
    
         
             
                    self.forward_api = f'{self.private_api}/gw-api/contract-tiger/forward'
         
     | 
| 
       32 
32 
     | 
    
         
             
                    self.ws_url = ws_url or "wss://contract-ws-v2.bitmart.com/v1/ifcontract/realTime"
         
     | 
| 
      
 33 
     | 
    
         
            +
                    self.api_ws_url = "wss://openapi-ws-v2.bitmart.com/api?protocol=1.1"
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
                    self.account_index = account_index
         
     | 
| 
       35 
36 
     | 
    
         
             
                    self.apis = apis
         
     | 
| 
         @@ -281,6 +282,7 @@ class Bitmart: 
     | 
|
| 
       281 
282 
     | 
    
         
             
                    *,
         
     | 
| 
       282 
283 
     | 
    
         
             
                    depth: str = "Depth",
         
     | 
| 
       283 
284 
     | 
    
         
             
                    depth_limit: int | None = None,
         
     | 
| 
      
 285 
     | 
    
         
            +
                    use_api_ws: bool = True,
         
     | 
| 
       284 
286 
     | 
    
         
             
                ) -> pybotters.ws.WebSocketApp:
         
     | 
| 
       285 
287 
     | 
    
         
             
                    """Subscribe order book channel(s)."""
         
     | 
| 
       286 
288 
     | 
    
         | 
| 
         @@ -289,37 +291,55 @@ class Bitmart: 
     | 
|
| 
       289 
291 
     | 
    
         | 
| 
       290 
292 
     | 
    
         
             
                    if not symbols:
         
     | 
| 
       291 
293 
     | 
    
         
             
                        raise ValueError("symbols must not be empty")
         
     | 
| 
       292 
     | 
    
         
            -
             
     | 
| 
       293 
     | 
    
         
            -
                    missing = [sym for sym in symbols if self.get_contract_id(sym) is None]
         
     | 
| 
       294 
     | 
    
         
            -
                    if missing:
         
     | 
| 
       295 
     | 
    
         
            -
                        await self.update("detail")
         
     | 
| 
       296 
     | 
    
         
            -
                        still_missing = [sym for sym in missing if self.get_contract_id(sym) is None]
         
     | 
| 
       297 
     | 
    
         
            -
                        if still_missing:
         
     | 
| 
       298 
     | 
    
         
            -
                            raise ValueError(f"Unknown symbols: {', '.join(still_missing)}")
         
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
294 
     | 
    
         
             
                    if depth_limit is not None:
         
     | 
| 
       301 
295 
     | 
    
         
             
                        self.store.book.limit = depth_limit
         
     | 
| 
      
 296 
     | 
    
         
            +
                    if not use_api_ws:
         
     | 
| 
      
 297 
     | 
    
         
            +
                        missing = [sym for sym in symbols if self.get_contract_id(sym) is None]
         
     | 
| 
      
 298 
     | 
    
         
            +
                        if missing:
         
     | 
| 
      
 299 
     | 
    
         
            +
                            await self.update("detail")
         
     | 
| 
      
 300 
     | 
    
         
            +
                            still_missing = [sym for sym in missing if self.get_contract_id(sym) is None]
         
     | 
| 
      
 301 
     | 
    
         
            +
                            if still_missing:
         
     | 
| 
      
 302 
     | 
    
         
            +
                                raise ValueError(f"Unknown symbols: {', '.join(still_missing)}")
         
     | 
| 
       302 
303 
     | 
    
         | 
| 
       303 
     | 
    
         
            -
                    channels: list[str] = []
         
     | 
| 
       304 
     | 
    
         
            -
                    for symbol in symbols:
         
     | 
| 
       305 
     | 
    
         
            -
                        contract_id = self.get_contract_id(symbol)
         
     | 
| 
       306 
     | 
    
         
            -
                        if contract_id is None:
         
     | 
| 
       307 
     | 
    
         
            -
                            continue
         
     | 
| 
       308 
     | 
    
         
            -
                        self.store.book.id_to_symbol[str(contract_id)] = symbol
         
     | 
| 
       309 
     | 
    
         
            -
                        channels.append(f"{depth}:{contract_id}")
         
     | 
| 
       310 
304 
     | 
    
         | 
| 
       311 
     | 
    
         
            -
                    if not channels:
         
     | 
| 
       312 
     | 
    
         
            -
                        raise ValueError("No channels resolved for subscription")
         
     | 
| 
       313 
305 
     | 
    
         | 
| 
       314 
     | 
    
         
            -
             
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
      
 306 
     | 
    
         
            +
                        channels: list[str] = []
         
     | 
| 
      
 307 
     | 
    
         
            +
                        for symbol in symbols:
         
     | 
| 
      
 308 
     | 
    
         
            +
                            contract_id = self.get_contract_id(symbol)
         
     | 
| 
      
 309 
     | 
    
         
            +
                            if contract_id is None:
         
     | 
| 
      
 310 
     | 
    
         
            +
                                continue
         
     | 
| 
      
 311 
     | 
    
         
            +
                            self.store.book.id_to_symbol[str(contract_id)] = symbol
         
     | 
| 
      
 312 
     | 
    
         
            +
                            channels.append(f"{depth}:{contract_id}")
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
      
 314 
     | 
    
         
            +
                        if not channels:
         
     | 
| 
      
 315 
     | 
    
         
            +
                            raise ValueError("No channels resolved for subscription")
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
                        payload = {"action": "subscribe", "args": channels}
         
     | 
| 
      
 318 
     | 
    
         
            +
                        # print(payload)
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                        ws_app = self.client.ws_connect(
         
     | 
| 
      
 321 
     | 
    
         
            +
                            self.api_ws_url,
         
     | 
| 
      
 322 
     | 
    
         
            +
                            send_json=payload,
         
     | 
| 
      
 323 
     | 
    
         
            +
                            hdlr_json=self.store.onmessage,
         
     | 
| 
      
 324 
     | 
    
         
            +
                        )
         
     | 
| 
      
 325 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 326 
     | 
    
         
            +
                        channels: list[str] = []
         
     | 
| 
      
 327 
     | 
    
         
            +
                        for symbol in symbols:
         
     | 
| 
      
 328 
     | 
    
         
            +
                            channels.append(f"futures/depthAll5:{symbol}@100ms")
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
                        if not channels:
         
     | 
| 
      
 331 
     | 
    
         
            +
                            raise ValueError("No channels resolved for subscription")
         
     | 
| 
      
 332 
     | 
    
         
            +
             
     | 
| 
      
 333 
     | 
    
         
            +
                        payload = {"action": "subscribe", "args": channels}
         
     | 
| 
      
 334 
     | 
    
         
            +
                        # print(payload)
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                        ws_app = self.client.ws_connect(
         
     | 
| 
      
 337 
     | 
    
         
            +
                            self.api_ws_url,
         
     | 
| 
      
 338 
     | 
    
         
            +
                            send_json=payload,
         
     | 
| 
      
 339 
     | 
    
         
            +
                            hdlr_json=self.store.onmessage,
         
     | 
| 
      
 340 
     | 
    
         
            +
                            autoping=False,
         
     | 
| 
      
 341 
     | 
    
         
            +
                        )
         
     | 
| 
       316 
342 
     | 
    
         | 
| 
       317 
     | 
    
         
            -
                    ws_app = self.client.ws_connect(
         
     | 
| 
       318 
     | 
    
         
            -
                        self.ws_url,
         
     | 
| 
       319 
     | 
    
         
            -
                        send_json=payload,
         
     | 
| 
       320 
     | 
    
         
            -
                        hdlr_json=self.store.onmessage,
         
     | 
| 
       321 
     | 
    
         
            -
                        autoping=False,
         
     | 
| 
       322 
     | 
    
         
            -
                    )
         
     | 
| 
       323 
343 
     | 
    
         
             
                    await ws_app._event.wait()
         
     | 
| 
       324 
344 
     | 
    
         
             
                    return ws_app
         
     | 
| 
       325 
345 
     | 
    
         | 
| 
         @@ -62,6 +62,7 @@ class Book(DataStore): 
     | 
|
| 
       62 
62 
     | 
    
         
             
                def _on_message(self, msg: dict[str, Any]) -> None:
         
     | 
| 
       63 
63 
     | 
    
         
             
                    data = msg.get("data")
         
     | 
| 
       64 
64 
     | 
    
         
             
                    group = msg.get("group")
         
     | 
| 
      
 65 
     | 
    
         
            +
                    ms_t = msg.get("ms_t")
         
     | 
| 
       65 
66 
     | 
    
         
             
                    if not isinstance(data, dict) or not isinstance(group, str):
         
     | 
| 
       66 
67 
     | 
    
         
             
                        return
         
     | 
| 
       67 
68 
     | 
    
         | 
| 
         @@ -94,7 +95,57 @@ class Book(DataStore): 
     | 
|
| 
       94 
95 
     | 
    
         
             
                        for entry in depths
         
     | 
| 
       95 
96 
     | 
    
         
             
                    ])
         
     | 
| 
       96 
97 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
                    self._last_update =  
     | 
| 
      
 98 
     | 
    
         
            +
                    self._last_update = ms_t
         
     | 
| 
      
 99 
     | 
    
         
            +
                
         
     | 
| 
      
 100 
     | 
    
         
            +
                def _on_message_api(self, msg: dict[str, Any]) -> None:
         
     | 
| 
      
 101 
     | 
    
         
            +
                    # {
         
     | 
| 
      
 102 
     | 
    
         
            +
                    #     "data": {
         
     | 
| 
      
 103 
     | 
    
         
            +
                    #         "symbol": "BTCUSDT",
         
     | 
| 
      
 104 
     | 
    
         
            +
                    #         "asks": [
         
     | 
| 
      
 105 
     | 
    
         
            +
                    #             {
         
     | 
| 
      
 106 
     | 
    
         
            +
                    #                 "price": "70294.4",
         
     | 
| 
      
 107 
     | 
    
         
            +
                    #                 "vol": "455"
         
     | 
| 
      
 108 
     | 
    
         
            +
                    #             }
         
     | 
| 
      
 109 
     | 
    
         
            +
                    #         ],
         
     | 
| 
      
 110 
     | 
    
         
            +
                    #         "bids": [
         
     | 
| 
      
 111 
     | 
    
         
            +
                    #             {
         
     | 
| 
      
 112 
     | 
    
         
            +
                    #                 "price": "70293.9",
         
     | 
| 
      
 113 
     | 
    
         
            +
                    #                 "vol": "1856"
         
     | 
| 
      
 114 
     | 
    
         
            +
                    #             }
         
     | 
| 
      
 115 
     | 
    
         
            +
                    #         ],
         
     | 
| 
      
 116 
     | 
    
         
            +
                    #         "ms_t": 1730399750402
         
     | 
| 
      
 117 
     | 
    
         
            +
                    #     },
         
     | 
| 
      
 118 
     | 
    
         
            +
                    #     "group": "futures/depthAll20:BTCUSDT@200ms"
         
     | 
| 
      
 119 
     | 
    
         
            +
                    # }
         
     | 
| 
      
 120 
     | 
    
         
            +
                    data = msg.get("data")
         
     | 
| 
      
 121 
     | 
    
         
            +
                    if not isinstance(data, dict):
         
     | 
| 
      
 122 
     | 
    
         
            +
                        return
         
     | 
| 
      
 123 
     | 
    
         
            +
                    symbol = data.get("symbol")
         
     | 
| 
      
 124 
     | 
    
         
            +
                    asks = data.get("asks") or []
         
     | 
| 
      
 125 
     | 
    
         
            +
                    bids = data.get("bids") or []
         
     | 
| 
      
 126 
     | 
    
         
            +
                    if self.limit:
         
     | 
| 
      
 127 
     | 
    
         
            +
                        asks = asks[: self.limit]
         
     | 
| 
      
 128 
     | 
    
         
            +
                        bids = bids[: self.limit]
         
     | 
| 
      
 129 
     | 
    
         
            +
                        
         
     | 
| 
      
 130 
     | 
    
         
            +
                    self._find_and_delete({'s': symbol})
         
     | 
| 
      
 131 
     | 
    
         
            +
                    self._update([
         
     | 
| 
      
 132 
     | 
    
         
            +
                        self._make_entry(
         
     | 
| 
      
 133 
     | 
    
         
            +
                            symbol,
         
     | 
| 
      
 134 
     | 
    
         
            +
                            "a",
         
     | 
| 
      
 135 
     | 
    
         
            +
                            entry.get("price", '0'),
         
     | 
| 
      
 136 
     | 
    
         
            +
                            entry.get("vol", '0'),
         
     | 
| 
      
 137 
     | 
    
         
            +
                        )
         
     | 
| 
      
 138 
     | 
    
         
            +
                        for entry in asks
         
     | 
| 
      
 139 
     | 
    
         
            +
                    ])
         
     | 
| 
      
 140 
     | 
    
         
            +
                    self._update([
         
     | 
| 
      
 141 
     | 
    
         
            +
                        self._make_entry(
         
     | 
| 
      
 142 
     | 
    
         
            +
                            symbol,
         
     | 
| 
      
 143 
     | 
    
         
            +
                            "b",
         
     | 
| 
      
 144 
     | 
    
         
            +
                            entry.get("price", '0'),
         
     | 
| 
      
 145 
     | 
    
         
            +
                            entry.get("vol", '0'),
         
     | 
| 
      
 146 
     | 
    
         
            +
                        )
         
     | 
| 
      
 147 
     | 
    
         
            +
                        for entry in bids
         
     | 
| 
      
 148 
     | 
    
         
            +
                    ])
         
     | 
| 
       98 
149 
     | 
    
         | 
| 
       99 
150 
     | 
    
         
             
                def sorted(self, query: Item | None = None, limit: int | None = None) -> dict[str, list[Item]]:
         
     | 
| 
       100 
151 
     | 
    
         
             
                    return self._sorted(
         
     | 
| 
         @@ -278,8 +329,12 @@ class BitmartDataStore(DataStoreCollection): 
     | 
|
| 
       278 
329 
     | 
    
         
             
                def onmessage(self, msg: Item, ws: ClientWebSocketResponse | None = None) -> None:
         
     | 
| 
       279 
330 
     | 
    
         
             
                    if isinstance(msg, dict):
         
     | 
| 
       280 
331 
     | 
    
         
             
                        group = msg.get("group")
         
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
      
 332 
     | 
    
         
            +
             
     | 
| 
      
 333 
     | 
    
         
            +
                        if isinstance(group, str):
         
     | 
| 
      
 334 
     | 
    
         
            +
                            if group.startswith("futures/depth"):
         
     | 
| 
      
 335 
     | 
    
         
            +
                                self.book._on_message_api(msg)
         
     | 
| 
      
 336 
     | 
    
         
            +
                            if group.startswith("Depth"):
         
     | 
| 
      
 337 
     | 
    
         
            +
                                self.book._on_message(msg)
         
     | 
| 
       283 
338 
     | 
    
         | 
| 
       284 
339 
     | 
    
         
             
                @property
         
     | 
| 
       285 
340 
     | 
    
         
             
                def book(self) -> Book:
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Metadata-Version: 2.4
         
     | 
| 
       2 
2 
     | 
    
         
             
            Name: hyperquant
         
     | 
| 
       3 
     | 
    
         
            -
            Version: 1. 
     | 
| 
      
 3 
     | 
    
         
            +
            Version: 1.21
         
     | 
| 
       4 
4 
     | 
    
         
             
            Summary: A minimal yet hyper-efficient backtesting framework for quantitative trading
         
     | 
| 
       5 
5 
     | 
    
         
             
            Project-URL: Homepage, https://github.com/yourusername/hyperquant
         
     | 
| 
       6 
6 
     | 
    
         
             
            Project-URL: Issues, https://github.com/yourusername/hyperquant/issues
         
     | 
| 
         @@ -6,7 +6,7 @@ hyperquant/logkit.py,sha256=nUo7nx5eONvK39GOhWwS41zNRL756P2J7-5xGzwXnTY,8462 
     | 
|
| 
       6 
6 
     | 
    
         
             
            hyperquant/notikit.py,sha256=x5yAZ_tAvLQRXcRbcg-VabCaN45LUhvlTZnUqkIqfAA,3596
         
     | 
| 
       7 
7 
     | 
    
         
             
            hyperquant/broker/auth.py,sha256=C8B5-x8Qcaeafm4ZwPCVFR7GRURmHC3CE4_vdg00Qgw,12139
         
     | 
| 
       8 
8 
     | 
    
         
             
            hyperquant/broker/bitget.py,sha256=X_S0LKZ7FZAEb6oEMr1vdGP1fondzK74BhmNTpRDSEA,9488
         
     | 
| 
       9 
     | 
    
         
            -
            hyperquant/broker/bitmart.py,sha256= 
     | 
| 
      
 9 
     | 
    
         
            +
            hyperquant/broker/bitmart.py,sha256=2Yd_Jzn0XYzl3rYN1rmNuwy7Wy74T3bBQ-ue7RvIbMU,22206
         
     | 
| 
       10 
10 
     | 
    
         
             
            hyperquant/broker/coinup.py,sha256=eOr8BTRXiTb5tCU2FDmvBdXXgqiwVmCbP5pdeA1ORJ8,20390
         
     | 
| 
       11 
11 
     | 
    
         
             
            hyperquant/broker/coinw.py,sha256=SnJU0vASh77rfcpMGWaIfTblQSjQk3vjlW_4juYdbcs,17214
         
     | 
| 
       12 
12 
     | 
    
         
             
            hyperquant/broker/edgex.py,sha256=TqUO2KRPLN_UaxvtLL6HnA9dAQXC1sGxOfqTHd6W5k8,18378
         
     | 
| 
         @@ -20,7 +20,7 @@ hyperquant/broker/lib/hpstore.py,sha256=LnLK2zmnwVvhEbLzYI-jz_SfYpO1Dv2u2cJaRAb8 
     | 
|
| 
       20 
20 
     | 
    
         
             
            hyperquant/broker/lib/hyper_types.py,sha256=HqjjzjUekldjEeVn6hxiWA8nevAViC2xHADOzDz9qyw,991
         
     | 
| 
       21 
21 
     | 
    
         
             
            hyperquant/broker/lib/util.py,sha256=iMU1qF0CHj5zzlIMEQGwjz-qtEVosEe7slXOCuB7Rcw,566
         
     | 
| 
       22 
22 
     | 
    
         
             
            hyperquant/broker/models/bitget.py,sha256=0RwDY75KrJb-c-oYoMxbqxWfsILe-n_Npojz4UFUq7c,11389
         
     | 
| 
       23 
     | 
    
         
            -
            hyperquant/broker/models/bitmart.py,sha256= 
     | 
| 
      
 23 
     | 
    
         
            +
            hyperquant/broker/models/bitmart.py,sha256=hPxSFLmsJif9wm4nTln5G_zCbsoRnM1BF9fnfciZIHo,22061
         
     | 
| 
       24 
24 
     | 
    
         
             
            hyperquant/broker/models/coinup.py,sha256=X_ngB2_sgTOdfAZqTyeWvCN03j-0_inZ6ugZKW6hR7k,11173
         
     | 
| 
       25 
25 
     | 
    
         
             
            hyperquant/broker/models/coinw.py,sha256=LvLMVP7i-qkkTK1ubw8eBkMK2RQmFoKPxdKqmC4IToY,22157
         
     | 
| 
       26 
26 
     | 
    
         
             
            hyperquant/broker/models/edgex.py,sha256=vPAkceal44cjTYKQ_0BoNAskOpmkno_Yo1KxgMLPc6Y,33954
         
     | 
| 
         @@ -32,6 +32,6 @@ hyperquant/datavison/_util.py,sha256=92qk4vO856RqycO0YqEIHJlEg-W9XKapDVqAMxe6rbw 
     | 
|
| 
       32 
32 
     | 
    
         
             
            hyperquant/datavison/binance.py,sha256=3yNKTqvt_vUQcxzeX4ocMsI5k6Q6gLZrvgXxAEad6Kc,5001
         
     | 
| 
       33 
33 
     | 
    
         
             
            hyperquant/datavison/coinglass.py,sha256=PEjdjISP9QUKD_xzXNzhJ9WFDTlkBrRQlVL-5pxD5mo,10482
         
     | 
| 
       34 
34 
     | 
    
         
             
            hyperquant/datavison/okx.py,sha256=yg8WrdQ7wgWHNAInIgsWPM47N3Wkfr253169IPAycAY,6898
         
     | 
| 
       35 
     | 
    
         
            -
            hyperquant-1. 
     | 
| 
       36 
     | 
    
         
            -
            hyperquant-1. 
     | 
| 
       37 
     | 
    
         
            -
            hyperquant-1. 
     | 
| 
      
 35 
     | 
    
         
            +
            hyperquant-1.21.dist-info/METADATA,sha256=1ZJFW9uGSQFzXQTBy74LLbaay4lUmc_pTOzSOugj_nU,4409
         
     | 
| 
      
 36 
     | 
    
         
            +
            hyperquant-1.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
         
     | 
| 
      
 37 
     | 
    
         
            +
            hyperquant-1.21.dist-info/RECORD,,
         
     | 
| 
         
            File without changes
         
     |