dnse-sdk-openapi 1.4.0__tar.gz → 1.4.2__tar.gz

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.
Files changed (60) hide show
  1. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/PKG-INFO +2 -2
  2. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/README.md +1 -1
  3. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/client.py +27 -1
  4. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/models.py +32 -0
  5. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/PKG-INFO +2 -2
  6. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/SOURCES.txt +2 -0
  7. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/pyproject.toml +1 -1
  8. dnse_sdk_openapi-1.4.2/websocket-marketdata/estimated_market_index.py +53 -0
  9. dnse_sdk_openapi-1.4.2/websocket-trading/broker_order.py +53 -0
  10. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/broker-api/get_list_care_by.py +0 -0
  11. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/__init__.py +0 -0
  12. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/api/_version.py +0 -0
  13. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/api/client.py +0 -0
  14. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/api/common.py +0 -0
  15. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/_version.py +0 -0
  16. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/auth.py +0 -0
  17. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/connection.py +0 -0
  18. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/encoding.py +0 -0
  19. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/exceptions.py +0 -0
  20. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/py.typed +0 -0
  21. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/dependency_links.txt +0 -0
  22. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/top_level.txt +0 -0
  23. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_instruments.py +0 -0
  24. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_latest_quote.py +0 -0
  25. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_latest_trade.py +0 -0
  26. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_ohlc.py +0 -0
  27. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_quotes.py +0 -0
  28. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_security_definition.py +0 -0
  29. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_trades.py +0 -0
  30. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_working_dates.py +0 -0
  31. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/setup.cfg +0 -0
  32. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/cancel_order.py +0 -0
  33. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/close_position.py +0 -0
  34. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/create_trading_token.py +0 -0
  35. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_accounts.py +0 -0
  36. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_balances.py +0 -0
  37. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_close_price.py +0 -0
  38. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_corporate_action_history.py +0 -0
  39. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_execution_detail.py +0 -0
  40. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_loan_packages.py +0 -0
  41. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_order_detail.py +0 -0
  42. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_order_history.py +0 -0
  43. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_orders.py +0 -0
  44. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_position_by_id.py +0 -0
  45. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_positions.py +0 -0
  46. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_ppse.py +0 -0
  47. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/post_order.py +0 -0
  48. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/put_order.py +0 -0
  49. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/send_email_otp.py +0 -0
  50. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/expected_price.py +0 -0
  51. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/foreign_investor.py +0 -0
  52. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/market_index.py +0 -0
  53. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/ohlc.py +0 -0
  54. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/ohlc_closed.py +0 -0
  55. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/quote.py +0 -0
  56. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/sec_def.py +0 -0
  57. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/trade.py +0 -0
  58. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/trade_extra.py +0 -0
  59. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-trading/order.py +0 -0
  60. {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-trading/position.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dnse-sdk-openapi
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: DNSE OpenAPI SDK
5
5
  Description-Content-Type: text/markdown
6
6
 
@@ -34,7 +34,7 @@ and investment applications.
34
34
  #### Install from PyPI
35
35
 
36
36
  ```console
37
- pip install openapi-sdk
37
+ pip install openapi-sdk
38
38
  ```
39
39
 
40
40
  Upgrade:
@@ -28,7 +28,7 @@ and investment applications.
28
28
  #### Install from PyPI
29
29
 
30
30
  ```console
31
- pip install openapi-sdk
31
+ pip install openapi-sdk
32
32
  ```
33
33
 
34
34
  Upgrade:
@@ -25,7 +25,7 @@ from .exceptions import (
25
25
  ConnectionClosed,
26
26
  )
27
27
  from .models import Trade, Quote, Ohlc, Order, AccountUpdate, ExpectedPrice, SecurityDefinition, TradeExtra, \
28
- MarketIndex, ForeignInvestor, Position
28
+ MarketIndex, ForeignInvestor, Position, EstimatedMarketIndex
29
29
 
30
30
  logger = logging.getLogger(__name__)
31
31
  logger.setLevel(logging.INFO)
@@ -51,6 +51,7 @@ _MSG_TYPE_MAP = {
51
51
  "dp": ("position_event", Position, "position"),
52
52
  "ep": ("position_event", Position, "position"),
53
53
  "mi": ("market_index", MarketIndex, None),
54
+ "emi": ("estimated_market_index", EstimatedMarketIndex, "marketIndex"),
54
55
  "a": ("account", AccountUpdate, None),
55
56
  "f": ("foreign", ForeignInvestor, None),
56
57
  }
@@ -269,6 +270,19 @@ class TradingClient:
269
270
  if on_order_event:
270
271
  self.on("order_event", on_order_event)
271
272
 
273
+ async def subscribe_broker_order_event(
274
+ self,
275
+ investor_id: str,
276
+ market_type="STOCK",
277
+ on_order_event: Optional[Callable[[Order], None]] = None,
278
+ encoding="json"
279
+ ) -> None:
280
+ channel = f"order.broker.{market_type}.{investor_id}.{encoding}"
281
+ await self._subscribe_channel(channel, [])
282
+
283
+ if on_order_event:
284
+ self.on("order_event", on_order_event)
285
+
272
286
  async def subscribe_position_event(
273
287
  self, market_type="STOCK",
274
288
  on_position_event: Optional[Callable[[Position], None]] = None,
@@ -308,6 +322,18 @@ class TradingClient:
308
322
  if on_market_index:
309
323
  self.on("market_index", on_market_index)
310
324
 
325
+ async def subscribe_estimated_market_index(
326
+ self, estimated_market_index: str,
327
+ on_estimated_market_index: Optional[Callable[[EstimatedMarketIndex], None]] = None, encoding="json"
328
+ ) -> None:
329
+ channel = f"estimated_market_index.{estimated_market_index}.json"
330
+ if encoding == "msgpack":
331
+ channel = f"estimated_market_index.{estimated_market_index}.msgpack"
332
+ await self._subscribe_channel(channel, [])
333
+
334
+ if on_estimated_market_index:
335
+ self.on("estimated_market_index", on_estimated_market_index)
336
+
311
337
  async def subscribe_quotes(
312
338
  self, symbols: List[str], on_quote: Optional[Callable[[Quote], None]] = None, encoding="json", board_id=None
313
339
  ) -> None:
@@ -265,6 +265,38 @@ class MarketIndex:
265
265
  )
266
266
 
267
267
 
268
+ @dataclass
269
+ class EstimatedMarketIndex:
270
+ indexName: str
271
+ changedRatio: float
272
+ changedValue: float
273
+ fluctuationSteadinessIssueCount: float
274
+ fluctuationDownIssueCount: float
275
+ fluctuationUpIssueCount: float
276
+ valueIndexes: float
277
+ grossTradeAmount: float
278
+ totalVolumeTraded: float
279
+ time: Optional[str] = None
280
+
281
+ receivedAt: Optional[float] = field(default=None, repr=False)
282
+
283
+ @classmethod
284
+ def from_dict(cls, data: Dict[str, Any]) -> "EstimatedMarketIndex":
285
+ return cls(
286
+ indexName=data.get("indexName"),
287
+ changedRatio=data.get("changedRatio"),
288
+ changedValue=data.get("changedValue"),
289
+ fluctuationSteadinessIssueCount=data.get("fluctuationSteadinessIssueCount"),
290
+ fluctuationDownIssueCount=data.get("fluctuationDownIssueCount"),
291
+ fluctuationUpIssueCount=data.get("fluctuationUpIssueCount"),
292
+ valueIndexes=data.get("valueIndexes"),
293
+ grossTradeAmount=data.get("grossTradeAmount"),
294
+ totalVolumeTraded=data.get("totalVolumeTraded"),
295
+ receivedAt=data.get("_receivedAt"),
296
+ time=data.get("time"),
297
+ )
298
+
299
+
268
300
  @dataclass
269
301
  class ExpectedPrice:
270
302
  marketId: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dnse-sdk-openapi
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: DNSE OpenAPI SDK
5
5
  Description-Content-Type: text/markdown
6
6
 
@@ -34,7 +34,7 @@ and investment applications.
34
34
  #### Install from PyPI
35
35
 
36
36
  ```console
37
- pip install openapi-sdk
37
+ pip install openapi-sdk
38
38
  ```
39
39
 
40
40
  Upgrade:
@@ -43,6 +43,7 @@ trading-api/get_ppse.py
43
43
  trading-api/post_order.py
44
44
  trading-api/put_order.py
45
45
  trading-api/send_email_otp.py
46
+ websocket-marketdata/estimated_market_index.py
46
47
  websocket-marketdata/expected_price.py
47
48
  websocket-marketdata/foreign_investor.py
48
49
  websocket-marketdata/market_index.py
@@ -52,5 +53,6 @@ websocket-marketdata/quote.py
52
53
  websocket-marketdata/sec_def.py
53
54
  websocket-marketdata/trade.py
54
55
  websocket-marketdata/trade_extra.py
56
+ websocket-trading/broker_order.py
55
57
  websocket-trading/order.py
56
58
  websocket-trading/position.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dnse-sdk-openapi"
7
- version = "1.4.0"
7
+ version = "1.4.2"
8
8
  description = "DNSE OpenAPI SDK"
9
9
  readme = "README.md"
10
10
 
@@ -0,0 +1,53 @@
1
+ """
2
+ Market index subscription example.
3
+
4
+ Demonstrates:
5
+ - Subscribing to market index
6
+
7
+ This example shows how to receive real-time market index
8
+ """
9
+
10
+ import asyncio
11
+
12
+ from dnse import TradingClient
13
+ from datetime import datetime
14
+
15
+ from dnse.websocket.models import EstimatedMarketIndex
16
+
17
+
18
+ async def main():
19
+ # Initialize client
20
+ encoding = "json" # json or msgpack
21
+ client = TradingClient(
22
+ api_key="api-key",
23
+ api_secret="api-secret",
24
+ base_url="wss://ws-openapi.dnse.com.vn",
25
+ encoding=encoding,
26
+ )
27
+
28
+ def handle_estimated_market_index(data: EstimatedMarketIndex):
29
+ received_at = datetime.fromtimestamp(data.receivedAt).strftime("%H:%M:%S.%f")[:-3] if data.receivedAt else "N/A"
30
+ print(f"[{received_at}] Estimated market index: {data}")
31
+
32
+ # Connect to gateway
33
+ print("Connecting to WebSocket gateway...")
34
+ await client.connect()
35
+ print(f"Connected! Session ID: {client._session_id}\n")
36
+
37
+ print("Subscribing to estimated market index...")
38
+ await client.subscribe_estimated_market_index(estimated_market_index='VN30', on_estimated_market_index=handle_estimated_market_index, encoding=encoding)
39
+
40
+ print("\nReceiving estimated market index (will run for 1 hour)...\n")
41
+
42
+ # Run for 8H to collect data
43
+ # In a real application, you might run indefinitely or until a specific condition
44
+ await asyncio.sleep(8 * 60 * 60)
45
+
46
+ # Disconnect gracefully
47
+ print("\n\nDisconnecting...")
48
+ await client.disconnect()
49
+ print("Disconnected!")
50
+
51
+
52
+ if __name__ == "__main__":
53
+ asyncio.run(main())
@@ -0,0 +1,53 @@
1
+ """
2
+ Order event subscription example.
3
+
4
+ This example shows how to receive real-time broker order event for stock and derivative orders
5
+ """
6
+
7
+ import asyncio
8
+ from datetime import datetime
9
+
10
+ from dnse import TradingClient
11
+ from dnse.websocket.models import Order
12
+
13
+
14
+ async def main():
15
+ # Initialize client
16
+ encoding = "json" # json or msgpack
17
+ client = TradingClient(
18
+ api_key="api-key",
19
+ api_secret="api-secret",
20
+ base_url="wss://ws-openapi.dnse.com.vn",
21
+ encoding=encoding,
22
+ )
23
+
24
+ def handle_order(data: Order):
25
+ received_at = datetime.fromtimestamp(data.receivedAt).strftime("%H:%M:%S.%f")[:-3] if data.receivedAt else "N/A"
26
+ print(f"[{received_at}] Order: {data}")
27
+
28
+ # Connect to gateway
29
+ print("Connecting to WebSocket gateway...")
30
+ await client.connect()
31
+ print(f"Connected! Session ID: {client._session_id}\n")
32
+
33
+ print("Subscribing to order event")
34
+ # market_type: DERIVATIVE | STOCK
35
+ await client.subscribe_broker_order_event(
36
+ investor_id="your-customer-investor-id",
37
+ market_type="STOCK",
38
+ on_order_event=handle_order, encoding=encoding)
39
+
40
+ print("\nReceiving order event (will run for 8 hour)...\n")
41
+
42
+ # Run for 8H to collect data
43
+ # In a real application, you might run indefinitely or until a specific condition
44
+ await asyncio.sleep(8 * 60 * 60)
45
+
46
+ # Disconnect gracefully
47
+ print("\n\nDisconnecting...")
48
+ await client.disconnect()
49
+ print("Disconnected!")
50
+
51
+
52
+ if __name__ == "__main__":
53
+ asyncio.run(main())