dnse-sdk-openapi 1.4.2__tar.gz → 1.4.4__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.2 → dnse_sdk_openapi-1.4.4}/PKG-INFO +1 -1
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/api/client.py +36 -2
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/client.py +30 -1
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/models.py +135 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse_sdk_openapi.egg-info/PKG-INFO +1 -1
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse_sdk_openapi.egg-info/SOURCES.txt +5 -0
- dnse_sdk_openapi-1.4.4/marketdata-api/get_foreign_trading.py +22 -0
- dnse_sdk_openapi-1.4.4/marketdata-api/get_lastest_session.py +22 -0
- dnse_sdk_openapi-1.4.4/marketdata-api/get_trading_session.py +22 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/pyproject.toml +1 -1
- dnse_sdk_openapi-1.4.4/websocket-marketdata/session.py +54 -0
- dnse_sdk_openapi-1.4.4/websocket-trading/broker_position.py +53 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/README.md +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/broker-api/get_list_care_by.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/__init__.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/api/_version.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/api/common.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/_version.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/auth.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/connection.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/encoding.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/exceptions.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse/websocket/py.typed +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse_sdk_openapi.egg-info/dependency_links.txt +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/dnse_sdk_openapi.egg-info/top_level.txt +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_instruments.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_latest_quote.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_latest_trade.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_ohlc.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_quotes.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_security_definition.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_trades.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/marketdata-api/get_working_dates.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/setup.cfg +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/cancel_order.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/close_position.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/create_trading_token.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_accounts.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_balances.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_close_price.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_corporate_action_history.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_execution_detail.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_loan_packages.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_order_detail.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_order_history.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_orders.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_position_by_id.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_positions.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/get_ppse.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/post_order.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/put_order.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/trading-api/send_email_otp.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/estimated_market_index.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/expected_price.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/foreign_investor.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/market_index.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/ohlc.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/ohlc_closed.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/quote.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/sec_def.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/trade.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/trade_extra.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-trading/broker_order.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-trading/order.py +0 -0
- {dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-trading/position.py +0 -0
|
@@ -31,8 +31,8 @@ class DNSEClient:
|
|
|
31
31
|
maxsize=10, # Số connections tối đa mỗi pool
|
|
32
32
|
block=False, # Không block khi pool đầy
|
|
33
33
|
timeout=urllib3.Timeout(connect=30.0, read=60.0),
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
cert_reqs = 'CERT_NONE', # Không yêu cầu certificate
|
|
35
|
+
assert_hostname = False # Không kiểm tra hostname
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
def get_accounts(self, dry_run=False):
|
|
@@ -231,6 +231,27 @@ class DNSEClient:
|
|
|
231
231
|
dry_run=dry_run,
|
|
232
232
|
)
|
|
233
233
|
|
|
234
|
+
def get_foreign_trading(self, symbol, board_id=None, from_date=None, to_date=None, limit=None, order = None, next_page_token=None, dry_run=False):
|
|
235
|
+
query = {}
|
|
236
|
+
if board_id is not None:
|
|
237
|
+
query["boardId"] = board_id
|
|
238
|
+
if from_date is not None:
|
|
239
|
+
query["from"] = from_date
|
|
240
|
+
if to_date is not None:
|
|
241
|
+
query["to"] = to_date
|
|
242
|
+
if limit is not None:
|
|
243
|
+
query["limit"] = limit
|
|
244
|
+
if order is not None:
|
|
245
|
+
query["order"] = order
|
|
246
|
+
if next_page_token is not None:
|
|
247
|
+
query["nextPageToken"] = next_page_token
|
|
248
|
+
return self._request(
|
|
249
|
+
"GET",
|
|
250
|
+
f"/price/{symbol}/foreign-trading",
|
|
251
|
+
query=query if query else None,
|
|
252
|
+
dry_run=dry_run,
|
|
253
|
+
)
|
|
254
|
+
|
|
234
255
|
def get_instruments(self, symbol=None, market_id=None, security_group_id=None, index_name=None, limit=None, page=None, dry_run=False):
|
|
235
256
|
query = {}
|
|
236
257
|
if symbol is not None:
|
|
@@ -299,6 +320,19 @@ class DNSEClient:
|
|
|
299
320
|
dry_run=dry_run,
|
|
300
321
|
)
|
|
301
322
|
|
|
323
|
+
def get_lastest_session(self, tsc_prod_grp_id=None, board_id=None, dry_run=False):
|
|
324
|
+
query = {}
|
|
325
|
+
if tsc_prod_grp_id is not None:
|
|
326
|
+
query["tscProdGrpId"] = tsc_prod_grp_id
|
|
327
|
+
if board_id is not None:
|
|
328
|
+
query["boardId"] = board_id
|
|
329
|
+
return self._request(
|
|
330
|
+
"GET",
|
|
331
|
+
f"/market/trading-session",
|
|
332
|
+
query=query if query else None,
|
|
333
|
+
dry_run=dry_run,
|
|
334
|
+
)
|
|
335
|
+
|
|
302
336
|
def post_order(self, market_type, payload, trading_token, order_category="NORMAL", dry_run=False):
|
|
303
337
|
headers = {"trading-token": trading_token}
|
|
304
338
|
query = {"marketType": market_type}
|
|
@@ -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, EstimatedMarketIndex
|
|
28
|
+
MarketIndex, ForeignInvestor, Position, EstimatedMarketIndex, Session
|
|
29
29
|
|
|
30
30
|
logger = logging.getLogger(__name__)
|
|
31
31
|
logger.setLevel(logging.INFO)
|
|
@@ -54,6 +54,7 @@ _MSG_TYPE_MAP = {
|
|
|
54
54
|
"emi": ("estimated_market_index", EstimatedMarketIndex, "marketIndex"),
|
|
55
55
|
"a": ("account", AccountUpdate, None),
|
|
56
56
|
"f": ("foreign", ForeignInvestor, None),
|
|
57
|
+
"s": ("session", Session, None),
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
|
|
@@ -294,6 +295,19 @@ class TradingClient:
|
|
|
294
295
|
if on_position_event:
|
|
295
296
|
self.on("position_event", on_position_event)
|
|
296
297
|
|
|
298
|
+
async def subscribe_broker_position_event(
|
|
299
|
+
self,
|
|
300
|
+
investor_id: str,
|
|
301
|
+
market_type="STOCK",
|
|
302
|
+
on_position_event: Optional[Callable[[Position], None]] = None,
|
|
303
|
+
encoding="json"
|
|
304
|
+
) -> None:
|
|
305
|
+
channel = f"position.broker.{market_type}.{investor_id}.{encoding}"
|
|
306
|
+
await self._subscribe_channel(channel, [])
|
|
307
|
+
|
|
308
|
+
if on_position_event:
|
|
309
|
+
self.on("position_event", on_position_event)
|
|
310
|
+
|
|
297
311
|
async def subscribe_sec_def(
|
|
298
312
|
self, symbols: List[str], on_sec_def: Optional[Callable[[SecurityDefinition], None]] = None,
|
|
299
313
|
encoding="json", board_id=None
|
|
@@ -384,6 +398,21 @@ class TradingClient:
|
|
|
384
398
|
if on_ohlc:
|
|
385
399
|
self.on("ohlc", on_ohlc)
|
|
386
400
|
|
|
401
|
+
async def subscribe_session(
|
|
402
|
+
self,
|
|
403
|
+
product_group_id: str,
|
|
404
|
+
board_id: str = "*",
|
|
405
|
+
on_session: Optional[Callable[[Session], None]] = None, encoding="json"
|
|
406
|
+
) -> None:
|
|
407
|
+
channel = f"session.{product_group_id}.{board_id}.json"
|
|
408
|
+
|
|
409
|
+
if encoding == "msgpack":
|
|
410
|
+
channel = f"session.{product_group_id}.{board_id}.msgpack"
|
|
411
|
+
await self._subscribe_channel(channel, [])
|
|
412
|
+
|
|
413
|
+
if on_session:
|
|
414
|
+
self.on("session", on_session)
|
|
415
|
+
|
|
387
416
|
async def subscribe_ohlc_closed(
|
|
388
417
|
self,
|
|
389
418
|
symbols: List[str],
|
|
@@ -568,6 +568,141 @@ class Ohlc:
|
|
|
568
568
|
)
|
|
569
569
|
|
|
570
570
|
|
|
571
|
+
@dataclass
|
|
572
|
+
class Session:
|
|
573
|
+
marketId: str
|
|
574
|
+
boardId: str
|
|
575
|
+
eventId: str
|
|
576
|
+
tradingSessionId: int
|
|
577
|
+
tscProdGrpId: str
|
|
578
|
+
receivedAt: Optional[float] = field(default=None, repr=False)
|
|
579
|
+
|
|
580
|
+
@classmethod
|
|
581
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Session":
|
|
582
|
+
return cls(
|
|
583
|
+
marketId=data.get("marketId", ""),
|
|
584
|
+
boardId=data.get("boardId", ""),
|
|
585
|
+
eventId=data.get("eventId", ""),
|
|
586
|
+
tradingSessionId=data.get("tradingSessionId", 0),
|
|
587
|
+
tscProdGrpId=data.get("tscProdGrpId", ""),
|
|
588
|
+
receivedAt=data.get("_receivedAt")
|
|
589
|
+
)
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
@dataclass
|
|
593
|
+
class Order:
|
|
594
|
+
id: str
|
|
595
|
+
side: str
|
|
596
|
+
accountNo: str
|
|
597
|
+
symbol: str
|
|
598
|
+
|
|
599
|
+
price: float
|
|
600
|
+
priceSecure: float
|
|
601
|
+
averagePrice: float
|
|
602
|
+
|
|
603
|
+
quantity: int
|
|
604
|
+
fillQuantity: int
|
|
605
|
+
canceledQuantity: int
|
|
606
|
+
leaveQuantity: int
|
|
607
|
+
|
|
608
|
+
orderType: str
|
|
609
|
+
orderStatus: str
|
|
610
|
+
|
|
611
|
+
loanPackageId: int
|
|
612
|
+
marketType: str
|
|
613
|
+
|
|
614
|
+
transDate: str
|
|
615
|
+
createdDate: str
|
|
616
|
+
modifiedDate: str
|
|
617
|
+
|
|
618
|
+
@classmethod
|
|
619
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Order":
|
|
620
|
+
return cls(
|
|
621
|
+
id=data.get("id"),
|
|
622
|
+
side=data.get("side"),
|
|
623
|
+
accountNo=data.get("accountNo") or data.get("account_no"),
|
|
624
|
+
symbol=data.get("symbol") or data.get("s"),
|
|
625
|
+
|
|
626
|
+
price=float(data.get("price", 0.0)),
|
|
627
|
+
priceSecure=float(data.get("priceSecure", 0.0)),
|
|
628
|
+
averagePrice=float(data.get("averagePrice", 0.0)),
|
|
629
|
+
|
|
630
|
+
quantity=int(data.get("quantity", 0)),
|
|
631
|
+
fillQuantity=int(data.get("fillQuantity", 0)),
|
|
632
|
+
canceledQuantity=int(data.get("canceledQuantity", 0)),
|
|
633
|
+
leaveQuantity=int(data.get("leaveQuantity", 0)),
|
|
634
|
+
|
|
635
|
+
orderType=data.get("orderType"),
|
|
636
|
+
orderStatus=data.get("orderStatus"),
|
|
637
|
+
|
|
638
|
+
loanPackageId=int(data.get("loanPackageId", 0)),
|
|
639
|
+
marketType=data.get("marketType"),
|
|
640
|
+
|
|
641
|
+
transDate=data.get("transDate"),
|
|
642
|
+
createdDate=data.get("createdDate"),
|
|
643
|
+
modifiedDate=data.get("modifiedDate"),
|
|
644
|
+
)
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
@dataclass
|
|
648
|
+
class Session:
|
|
649
|
+
marketId: str
|
|
650
|
+
boardId: str
|
|
651
|
+
eventId: str
|
|
652
|
+
tradingSessionId: int
|
|
653
|
+
tscProdGrpId: str
|
|
654
|
+
time: Optional[str] = None
|
|
655
|
+
receivedAt: Optional[float] = field(default=None, repr=False)
|
|
656
|
+
|
|
657
|
+
@classmethod
|
|
658
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Session":
|
|
659
|
+
return cls(
|
|
660
|
+
marketId=data.get("marketId", ""),
|
|
661
|
+
boardId=data.get("boardId", ""),
|
|
662
|
+
eventId=data.get("eventId", ""),
|
|
663
|
+
tradingSessionId=data.get("tradingSessionId", 0),
|
|
664
|
+
tscProdGrpId=data.get("tscProdGrpId", ""),
|
|
665
|
+
time=parse_timestamp(data.get("sendingTime")),
|
|
666
|
+
receivedAt=data.get("_receivedAt"),
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
@dataclass
|
|
671
|
+
class Position:
|
|
672
|
+
symbol: str
|
|
673
|
+
quantity: int
|
|
674
|
+
averagePrice: Decimal
|
|
675
|
+
marketValue: Decimal
|
|
676
|
+
costBasis: Decimal
|
|
677
|
+
unrealizedPl: Decimal
|
|
678
|
+
unrealizedPlPercent: Decimal
|
|
679
|
+
timestamp: datetime
|
|
680
|
+
|
|
681
|
+
@classmethod
|
|
682
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Position":
|
|
683
|
+
"""Parse position from message data.
|
|
684
|
+
|
|
685
|
+
Args:
|
|
686
|
+
data: Raw message dict with either abbreviated or full field names
|
|
687
|
+
|
|
688
|
+
Returns:
|
|
689
|
+
Position instance
|
|
690
|
+
|
|
691
|
+
Example:
|
|
692
|
+
>>> Position.from_dict({"S": "AAPL", "q": 100, "ap": "150.00", ...})
|
|
693
|
+
"""
|
|
694
|
+
return cls(
|
|
695
|
+
symbol=data.get("symbol"),
|
|
696
|
+
quantity=data.get("quantity"),
|
|
697
|
+
averagePrice=Decimal(str(data.get("averagePrice"))),
|
|
698
|
+
marketValue=Decimal(str(data.get("marketValue"))),
|
|
699
|
+
costBasis=Decimal(str(data.get("costBasis"))),
|
|
700
|
+
unrealizedPl=Decimal(str(data.get("unrealizedPl"))),
|
|
701
|
+
unrealizedPlPercent=Decimal(str(data.get("unrealizedPlPercent"))),
|
|
702
|
+
timestamp=datetime.fromtimestamp((data.get("timestamp")) / 1000),
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
|
|
571
706
|
@dataclass
|
|
572
707
|
class AccountUpdate:
|
|
573
708
|
cash: Decimal
|
|
@@ -17,13 +17,16 @@ dnse_sdk_openapi.egg-info/PKG-INFO
|
|
|
17
17
|
dnse_sdk_openapi.egg-info/SOURCES.txt
|
|
18
18
|
dnse_sdk_openapi.egg-info/dependency_links.txt
|
|
19
19
|
dnse_sdk_openapi.egg-info/top_level.txt
|
|
20
|
+
marketdata-api/get_foreign_trading.py
|
|
20
21
|
marketdata-api/get_instruments.py
|
|
22
|
+
marketdata-api/get_lastest_session.py
|
|
21
23
|
marketdata-api/get_latest_quote.py
|
|
22
24
|
marketdata-api/get_latest_trade.py
|
|
23
25
|
marketdata-api/get_ohlc.py
|
|
24
26
|
marketdata-api/get_quotes.py
|
|
25
27
|
marketdata-api/get_security_definition.py
|
|
26
28
|
marketdata-api/get_trades.py
|
|
29
|
+
marketdata-api/get_trading_session.py
|
|
27
30
|
marketdata-api/get_working_dates.py
|
|
28
31
|
trading-api/cancel_order.py
|
|
29
32
|
trading-api/close_position.py
|
|
@@ -51,8 +54,10 @@ websocket-marketdata/ohlc.py
|
|
|
51
54
|
websocket-marketdata/ohlc_closed.py
|
|
52
55
|
websocket-marketdata/quote.py
|
|
53
56
|
websocket-marketdata/sec_def.py
|
|
57
|
+
websocket-marketdata/session.py
|
|
54
58
|
websocket-marketdata/trade.py
|
|
55
59
|
websocket-marketdata/trade_extra.py
|
|
56
60
|
websocket-trading/broker_order.py
|
|
61
|
+
websocket-trading/broker_position.py
|
|
57
62
|
websocket-trading/order.py
|
|
58
63
|
websocket-trading/position.py
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
|
6
|
+
|
|
7
|
+
from dnse import DNSEClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
client = DNSEClient(
|
|
12
|
+
api_key="replace-with-api-key",
|
|
13
|
+
api_secret="replace-with-api-secret",
|
|
14
|
+
base_url="https://openapi.dnse.com.vn",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
status, body = client.get_foreign_trading(symbol="SSI", board_id="G1", from_date=1781037427, to_date=1781062643, limit = 100, order = "DESC", next_page_token=None, dry_run=False)
|
|
18
|
+
print(status, body)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
|
6
|
+
|
|
7
|
+
from dnse import DNSEClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
client = DNSEClient(
|
|
12
|
+
api_key="replace-with-api-key",
|
|
13
|
+
api_secret="replace-with-api-secret",
|
|
14
|
+
base_url="https://openapi.dnse.com.vn",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
status, body = client.get_lastest_session(tsc_prod_grp_id="FIO", board_id="G1", dry_run=False)
|
|
18
|
+
print(status, body)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
|
6
|
+
|
|
7
|
+
from dnse import DNSEClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
client = DNSEClient(
|
|
12
|
+
api_key="replace-with-api-key",
|
|
13
|
+
api_secret="replace-with-api-secret",
|
|
14
|
+
base_url="https://openapi.dnse.com.vn",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
status, body = client.get_trading_session(tsc_prod_grp_id="FBX", board_id="", dry_run=False)
|
|
18
|
+
print(status, body)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Demonstrates:
|
|
3
|
+
- Subscribing to session data
|
|
4
|
+
|
|
5
|
+
This example shows how to receive real-time session data
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
|
|
13
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
|
14
|
+
|
|
15
|
+
from dnse import TradingClient
|
|
16
|
+
from dnse.websocket.models import Session
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def main():
|
|
20
|
+
# Initialize client
|
|
21
|
+
encoding = "msgpack" # json or msgpack
|
|
22
|
+
client = TradingClient(
|
|
23
|
+
api_key="api-key",
|
|
24
|
+
api_secret="api-secret",
|
|
25
|
+
base_url="wss://ws-openapi.dnse.com.vn",
|
|
26
|
+
encoding=encoding,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def handle_session(session: Session):
|
|
30
|
+
received_at = datetime.fromtimestamp(session.receivedAt).strftime("%H:%M:%S.%f")[:-3] if session.receivedAt else "N/A"
|
|
31
|
+
print(f"[{received_at}] Session: {session}")
|
|
32
|
+
|
|
33
|
+
# Connect to gateway
|
|
34
|
+
print("Connecting to WebSocket gateway...")
|
|
35
|
+
await client.connect()
|
|
36
|
+
print(f"Connected! Session ID: {client._session_id}\n")
|
|
37
|
+
|
|
38
|
+
print("Subscribing to session data...")
|
|
39
|
+
await client.subscribe_session(product_group_id="STX", board_id = "G1", on_session=handle_session, encoding=encoding)
|
|
40
|
+
|
|
41
|
+
print("\nReceiving session data (will run for 1 hour)...\n")
|
|
42
|
+
|
|
43
|
+
# Run for 8H to collect data
|
|
44
|
+
# In a real application, you might run indefinitely or until a specific condition
|
|
45
|
+
await asyncio.sleep(8 * 60 * 60)
|
|
46
|
+
|
|
47
|
+
# Disconnect gracefully
|
|
48
|
+
print("\n\nDisconnecting...")
|
|
49
|
+
await client.disconnect()
|
|
50
|
+
print("Disconnected!")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Position event subscription example.
|
|
3
|
+
|
|
4
|
+
This example shows how to receive real-time customer's position events of broker for stock and derivative
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
from dnse import TradingClient
|
|
11
|
+
from dnse.websocket.models import Position
|
|
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_position(data: Position):
|
|
25
|
+
received_at = datetime.fromtimestamp(data.receivedAt).strftime("%H:%M:%S.%f")[:-3] if data.receivedAt else "N/A"
|
|
26
|
+
print(f"[{received_at}] Position: {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 position event")
|
|
34
|
+
# market_type: DERIVATIVE | STOCK
|
|
35
|
+
await client.subscribe_broker_position_event(
|
|
36
|
+
investor_id="your-customer-investor-id",
|
|
37
|
+
market_type="STOCK",
|
|
38
|
+
on_position_event=handle_position, encoding=encoding)
|
|
39
|
+
|
|
40
|
+
print("\nReceiving position 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.2 → dnse_sdk_openapi-1.4.4}/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.2 → dnse_sdk_openapi-1.4.4}/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
|
{dnse_sdk_openapi-1.4.2 → dnse_sdk_openapi-1.4.4}/websocket-marketdata/estimated_market_index.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
|