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.
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/PKG-INFO +2 -2
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/README.md +1 -1
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/client.py +27 -1
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/models.py +32 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/PKG-INFO +2 -2
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/SOURCES.txt +2 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/pyproject.toml +1 -1
- dnse_sdk_openapi-1.4.2/websocket-marketdata/estimated_market_index.py +53 -0
- dnse_sdk_openapi-1.4.2/websocket-trading/broker_order.py +53 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/broker-api/get_list_care_by.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/__init__.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/api/_version.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/api/client.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/api/common.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/_version.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/auth.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/connection.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/encoding.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/exceptions.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse/websocket/py.typed +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/dependency_links.txt +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/top_level.txt +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_instruments.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_latest_quote.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_latest_trade.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_ohlc.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_quotes.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_security_definition.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_trades.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/marketdata-api/get_working_dates.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/setup.cfg +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/cancel_order.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/close_position.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/create_trading_token.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_accounts.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_balances.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_close_price.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_corporate_action_history.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_execution_detail.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_loan_packages.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_order_detail.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_order_history.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_orders.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_position_by_id.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_positions.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_ppse.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/post_order.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/put_order.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/send_email_otp.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/expected_price.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/foreign_investor.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/market_index.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/ohlc.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/ohlc_closed.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/quote.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/sec_def.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/trade.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-marketdata/trade_extra.py +0 -0
- {dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/websocket-trading/order.py +0 -0
- {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.
|
|
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:
|
|
@@ -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.
|
|
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
|
|
@@ -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())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/dnse_sdk_openapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dnse_sdk_openapi-1.4.0 → dnse_sdk_openapi-1.4.2}/trading-api/get_corporate_action_history.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|