kitecli 0.3.1__tar.gz → 0.4.0__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.
- {kitecli-0.3.1 → kitecli-0.4.0}/PKG-INFO +1 -1
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/api_client.py +82 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/base_manager.py +8 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/charges.py +3 -3
- kitecli-0.4.0/cli/display.py +773 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/executor.py +96 -1
- kitecli-0.4.0/cli/greeks.py +334 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/indicators.py +6 -3
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/kite_manager.py +186 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/kotak_manager.py +131 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/live_session.py +1837 -159
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/main.py +60 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/nli.py +1 -1
- kitecli-0.4.0/cli/parser.py +511 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/recorder.py +449 -7
- {kitecli-0.3.1 → kitecli-0.4.0}/kitecli.egg-info/PKG-INFO +1 -1
- {kitecli-0.3.1 → kitecli-0.4.0}/kitecli.egg-info/SOURCES.txt +3 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/pyproject.toml +1 -1
- kitecli-0.4.0/tests/test_command_matrix.py +401 -0
- kitecli-0.4.0/tests/test_conditional_orders.py +515 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/tests/test_multi_broker.py +126 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/tests/test_parser.py +121 -0
- kitecli-0.4.0/tests/test_scheduled_orders.py +394 -0
- kitecli-0.4.0/tests/test_ui.py +397 -0
- kitecli-0.3.1/cli/display.py +0 -389
- kitecli-0.3.1/cli/greeks.py +0 -160
- kitecli-0.3.1/cli/parser.py +0 -181
- kitecli-0.3.1/tests/test_ui.py +0 -153
- {kitecli-0.3.1 → kitecli-0.4.0}/README.md +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/__init__.py +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/advisor.py +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/config.py +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/cli/telegram_bot.py +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/kitecli.egg-info/dependency_links.txt +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/kitecli.egg-info/entry_points.txt +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/kitecli.egg-info/requires.txt +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/kitecli.egg-info/top_level.txt +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/setup.cfg +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/tests/test_nli.py +0 -0
- {kitecli-0.3.1 → kitecli-0.4.0}/tests/test_telegram.py +0 -0
|
@@ -537,6 +537,73 @@ class KCLIClient:
|
|
|
537
537
|
|
|
538
538
|
return {"accounts": results}
|
|
539
539
|
|
|
540
|
+
def get_holdings(self, api_keys: list[str] | None = None) -> dict:
|
|
541
|
+
"""Fetch stock/equity holdings for specified accounts in parallel."""
|
|
542
|
+
keys = api_keys or [a.get("api_key") for a in self._accounts if a.get("api_key")]
|
|
543
|
+
|
|
544
|
+
def fetch_one(api_key):
|
|
545
|
+
mgr = _manager_for(api_key)
|
|
546
|
+
info = mgr.get_account_info(api_key)
|
|
547
|
+
broker = getattr(mgr, "broker_name", "zerodha")
|
|
548
|
+
if not info.get("authenticated"):
|
|
549
|
+
return {
|
|
550
|
+
"name": info.get("name", api_key),
|
|
551
|
+
"api_key": api_key,
|
|
552
|
+
"broker": broker,
|
|
553
|
+
"holdings": [],
|
|
554
|
+
"total_investment": 0.0,
|
|
555
|
+
"total_current_value": 0.0,
|
|
556
|
+
"total_pnl": 0.0,
|
|
557
|
+
"total_day_change": 0.0,
|
|
558
|
+
"status": "unauthenticated",
|
|
559
|
+
}
|
|
560
|
+
try:
|
|
561
|
+
holdings = mgr.get_holdings(api_key)
|
|
562
|
+
tot_inv = sum(h.get("investment_value", 0.0) for h in holdings)
|
|
563
|
+
tot_cur = sum(h.get("current_value", 0.0) for h in holdings)
|
|
564
|
+
tot_pnl = tot_cur - tot_inv
|
|
565
|
+
tot_day = sum(h.get("day_change", 0.0) for h in holdings)
|
|
566
|
+
return {
|
|
567
|
+
"name": info.get("name", api_key),
|
|
568
|
+
"api_key": api_key,
|
|
569
|
+
"broker": broker,
|
|
570
|
+
"holdings": holdings,
|
|
571
|
+
"total_investment": tot_inv,
|
|
572
|
+
"total_current_value": tot_cur,
|
|
573
|
+
"total_pnl": tot_pnl,
|
|
574
|
+
"total_day_change": tot_day,
|
|
575
|
+
"status": "success",
|
|
576
|
+
}
|
|
577
|
+
except Exception as exc:
|
|
578
|
+
return {
|
|
579
|
+
"name": info.get("name", api_key),
|
|
580
|
+
"api_key": api_key,
|
|
581
|
+
"broker": broker,
|
|
582
|
+
"holdings": [],
|
|
583
|
+
"total_investment": 0.0,
|
|
584
|
+
"total_current_value": 0.0,
|
|
585
|
+
"total_pnl": 0.0,
|
|
586
|
+
"total_day_change": 0.0,
|
|
587
|
+
"status": f"error: {exc}",
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
with ThreadPoolExecutor(max_workers=max(1, len(keys))) as executor:
|
|
591
|
+
results = list(executor.map(fetch_one, keys))
|
|
592
|
+
|
|
593
|
+
grand_inv = sum(a.get("total_investment", 0.0) for a in results)
|
|
594
|
+
grand_cur = sum(a.get("total_current_value", 0.0) for a in results)
|
|
595
|
+
grand_pnl = grand_cur - grand_inv
|
|
596
|
+
grand_day = sum(a.get("total_day_change", 0.0) for a in results)
|
|
597
|
+
|
|
598
|
+
return {
|
|
599
|
+
"accounts": results,
|
|
600
|
+
"grand_total_investment": grand_inv,
|
|
601
|
+
"grand_total_current_value": grand_cur,
|
|
602
|
+
"grand_total_pnl": grand_pnl,
|
|
603
|
+
"grand_total_day_change": grand_day,
|
|
604
|
+
"status": "success",
|
|
605
|
+
}
|
|
606
|
+
|
|
540
607
|
def modify_order(
|
|
541
608
|
self,
|
|
542
609
|
api_key: str,
|
|
@@ -636,3 +703,18 @@ class KCLIClient:
|
|
|
636
703
|
return mgr.get_ltp_and_tokens(api_key, symbols)
|
|
637
704
|
return {}
|
|
638
705
|
|
|
706
|
+
def get_market_depth(self, symbol: str) -> dict:
|
|
707
|
+
"""Fetch 5-depth order book, OHLC, and market stats for a symbol."""
|
|
708
|
+
if hasattr(_kite_manager, "get_market_depth"):
|
|
709
|
+
res = _kite_manager.get_market_depth(symbol)
|
|
710
|
+
if res.get("status") == "success":
|
|
711
|
+
return res
|
|
712
|
+
|
|
713
|
+
for mgr in [_kotak_manager]:
|
|
714
|
+
if hasattr(mgr, "get_market_depth"):
|
|
715
|
+
res = mgr.get_market_depth(symbol)
|
|
716
|
+
if res.get("status") == "success":
|
|
717
|
+
return res
|
|
718
|
+
|
|
719
|
+
return {"status": "error", "message": f"Market depth not available for symbol '{symbol}'"}
|
|
720
|
+
|
|
@@ -81,6 +81,10 @@ class BaseBrokerManager(ABC):
|
|
|
81
81
|
def get_margins(self, account_key: str) -> dict[str, Any]:
|
|
82
82
|
"""Return {"net": float|None, "cash": float|None, "collateral": float|None}."""
|
|
83
83
|
|
|
84
|
+
@abstractmethod
|
|
85
|
+
def get_holdings(self, account_key: str) -> list[dict[str, Any]]:
|
|
86
|
+
"""Fetch equity/stock holdings using the normalised schema."""
|
|
87
|
+
|
|
84
88
|
# ── order management ──────────────────────────────────────────────────────
|
|
85
89
|
|
|
86
90
|
@abstractmethod
|
|
@@ -157,3 +161,7 @@ class BaseBrokerManager(ABC):
|
|
|
157
161
|
) -> dict[str, Any]:
|
|
158
162
|
"""Calculate margin required for a proposed order. Default: fallback estimation."""
|
|
159
163
|
return {"status": "error", "message": "not supported by this broker"}
|
|
164
|
+
|
|
165
|
+
def get_market_depth(self, symbol: str) -> dict[str, Any]:
|
|
166
|
+
"""Fetch 5-depth order book, OHLC, and market stats for a symbol. Default: not supported."""
|
|
167
|
+
return {"status": "error", "message": "not supported by this broker"}
|
|
@@ -7,7 +7,7 @@ Official Rates from https://zerodha.com/charges/#charges-explained:
|
|
|
7
7
|
- GST: 18% on (brokerage + SEBI charges + transaction charges).
|
|
8
8
|
- SEBI charges: ₹10 / crore (0.0001%).
|
|
9
9
|
- Stamp charges: 0.003% or ₹300 / crore on buy side.
|
|
10
|
-
- IPFT fee: ₹
|
|
10
|
+
- IPFT fee: ₹0.01 / crore (0.0000001%).
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from typing import Any
|
|
@@ -55,8 +55,8 @@ def calculate_option_charges(
|
|
|
55
55
|
# 4. SEBI turnover fee: ₹10 / crore (0.0001%)
|
|
56
56
|
sebi_fee = round(total_val * 0.000001, 2)
|
|
57
57
|
|
|
58
|
-
# 5. IPFT fee: ₹
|
|
59
|
-
ipft_fee = round(total_val *
|
|
58
|
+
# 5. IPFT fee: ₹0.01 / crore (0.0000001%) for NSE/NFO
|
|
59
|
+
ipft_fee = round(total_val * 1e-9, 2) if is_nse else 0.0
|
|
60
60
|
|
|
61
61
|
# 6. GST: 18% on (Brokerage + Exchange Fee + SEBI Fee)
|
|
62
62
|
gst = round((brokerage + exch_fee + sebi_fee) * 0.18, 2)
|