bw-essentials-core 0.1.7__tar.gz → 0.1.8__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.

Potentially problematic release.


This version of bw-essentials-core might be problematic. Click here for more details.

Files changed (34) hide show
  1. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/PKG-INFO +1 -1
  2. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/user_portfolio.py +165 -1
  3. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials_core.egg-info/PKG-INFO +1 -1
  4. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/setup.py +1 -1
  5. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/README.md +0 -0
  6. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/__init__.py +0 -0
  7. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/constants/__init__.py +0 -0
  8. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/constants/services.py +0 -0
  9. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/data_loch/__init__.py +0 -0
  10. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/data_loch/data_loch.py +0 -0
  11. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/email_client/__init__.py +0 -0
  12. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/email_client/email_client.py +0 -0
  13. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/notifications/__init__.py +0 -0
  14. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/notifications/teams_notification_schemas.py +0 -0
  15. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/notifications/teams_notifications.py +0 -0
  16. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/s3_utils/__init__.py +0 -0
  17. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/s3_utils/s3_utils.py +0 -0
  18. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/__init__.py +0 -0
  19. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/api_client.py +0 -0
  20. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/broker.py +0 -0
  21. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/market_pricer.py +0 -0
  22. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/master_data.py +0 -0
  23. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/model_portfolio_reporting.py +0 -0
  24. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/notification.py +0 -0
  25. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/portfolio_catalogue.py +0 -0
  26. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/portfolio_content.py +0 -0
  27. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/trade_placement.py +0 -0
  28. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/user_app.py +0 -0
  29. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials/services/user_portfolio_reporting.py +0 -0
  30. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials_core.egg-info/SOURCES.txt +0 -0
  31. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials_core.egg-info/dependency_links.txt +0 -0
  32. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials_core.egg-info/requires.txt +0 -0
  33. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/bw_essentials_core.egg-info/top_level.txt +0 -0
  34. {bw_essentials_core-0.1.7 → bw_essentials_core-0.1.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bw-essentials-core
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Reusable utilities for S3, email, Data Loch, Microsoft Teams Notifications and more.
5
5
  Author: InvestorAI
6
6
  Author-email: support+tech@investorai.in
@@ -43,7 +43,9 @@ class UserPortfolio(ApiClient):
43
43
  "skip": "userportfolio/order/skip/basket",
44
44
  "create_order_instructions": "userportfolio/order/order-instruction",
45
45
  "basket_details": "userportfolio/basket",
46
- "broker_users_holdings": "holding/{}/users"
46
+ "broker_users_holdings": "holding/{}/users",
47
+ "user_portfolio_thresholds": "alerts/portfolio/thresholds",
48
+ "holding_thresholds": "alerts/holding/thresholds"
47
49
  }
48
50
 
49
51
  def create_holding_transaction(self, payload):
@@ -404,3 +406,165 @@ class UserPortfolio(ApiClient):
404
406
  endpoint = self.urls.get('broker_users_holdings').format(broker)
405
407
  response = self._get(url=self.base_url, endpoint=endpoint)
406
408
  return response.get('data')
409
+
410
+ def create_user_portfolio_threshold(self, payload):
411
+ """Create a *User Portfolio* threshold.
412
+
413
+ Parameters
414
+ ----------
415
+ payload : dict | str
416
+ JSON-serialisable dictionary (or raw JSON string) containing the
417
+ following **required** keys.
418
+
419
+ * **portfolio_type** (str) – One of the portfolio types accepted by
420
+ the User-Portfolio service (e.g. ``USER_PORTFOLIO`` or ``BASKET``).
421
+ * **portfolio_id** (str) – Unique identifier of the portfolio
422
+ entity.
423
+ * **side** (str) – Either ``LONG`` or ``SHORT``.
424
+ * **threshold_type** (str) – Threshold category, e.g. ``PT`` or
425
+ ``SL``.
426
+ * **status** (str) – Initial status, typically ``ACTIVE``.
427
+
428
+ **Optional** keys:
429
+
430
+ * **target_pct** (Decimal | float) – Percent based trigger level.
431
+ * **target_value** (Decimal | float) – Absolute money value trigger.
432
+ * **source** (str) – Origin of the instruction (``user``, ``admin`` …).
433
+
434
+ Returns
435
+ -------
436
+ dict
437
+ A dictionary representing the newly-created threshold (same shape
438
+ as the backend response ``data`` field).
439
+ """
440
+ logger.info(f"In create_user_portfolio_threshold {payload =}")
441
+ data = self._post(url=self.base_url,
442
+ endpoint=self.urls.get("user_portfolio_thresholds"),
443
+ data=payload)
444
+ logger.info(f"{data =}")
445
+ return data.get("data")
446
+
447
+ def get_user_portfolio_thresholds(self, params=None):
448
+ """Retrieve *User Portfolio* thresholds.
449
+
450
+ Parameters
451
+ ----------
452
+ params : dict | None, optional
453
+ Query-string parameters used as filters; accepted keys mirror the
454
+ columns of ``UserPortfolioThreshold`` (e.g. ``portfolio_type``,
455
+ ``portfolio_id``, ``status`` …). Passing ``None`` performs an
456
+ unfiltered list retrieval.
457
+
458
+ Returns
459
+ -------
460
+ list[dict]
461
+ List of serialised thresholds ordered by ``-effective_from``.
462
+ """
463
+ logger.info(f"In get_user_portfolio_thresholds {params =}")
464
+ data = self._get(url=self.base_url,
465
+ endpoint=self.urls.get("user_portfolio_thresholds"),
466
+ params=params)
467
+ logger.info(f"{data =}")
468
+ return data.get("data")
469
+
470
+ def update_user_portfolio_threshold(self, payload):
471
+ """Update an existing *User Portfolio* threshold.
472
+
473
+ The request is forwarded verbatim to ``PUT /portfolio/thresholds``.
474
+
475
+ Parameters
476
+ ----------
477
+ payload : dict | str
478
+ Dictionary (or JSON string) that **must** include:
479
+
480
+ * **id** (int) – Primary key of the threshold to update.
481
+
482
+ Any of the following *optional* fields may also be supplied; only
483
+ those present will be updated:
484
+
485
+ * **target_pct** (Decimal | float)
486
+ * **status** (str)
487
+ * **source** (str)
488
+
489
+ Returns
490
+ -------
491
+ dict
492
+ The updated threshold as returned by the backend (``data`` field).
493
+ """
494
+ logger.info(f"In update_user_portfolio_threshold {payload =}")
495
+ data = self._put(url=self.base_url,
496
+ endpoint=self.urls.get("user_portfolio_thresholds"),
497
+ json=payload)
498
+ logger.info(f"{data =}")
499
+ return data.get("data")
500
+
501
+ def create_holding_threshold(self, payload):
502
+ """Create a *Holding* threshold.
503
+
504
+ Parameters
505
+ ----------
506
+ payload : dict | str
507
+ Data required by ``POST /holding/thresholds``. Mandatory keys:
508
+
509
+ * **holding_type** (str)
510
+ * **holding_id** (str)
511
+ * **side** (str)
512
+ * **threshold** (Decimal | float)
513
+ * **effective_from** (datetime-iso-str)
514
+
515
+ Optional: **source** (str)
516
+
517
+ Returns
518
+ -------
519
+ dict
520
+ Newly created Holding-threshold representation.
521
+ """
522
+ logger.info(f"In create_holding_threshold {payload =}")
523
+ data = self._post(url=self.base_url,
524
+ endpoint=self.urls.get("holding_thresholds"),
525
+ data=payload)
526
+ logger.info(f"{data =}")
527
+ return data.get("data")
528
+
529
+ def get_holding_thresholds(self, params=None):
530
+ """Retrieve *Holding* thresholds with optional filters.
531
+
532
+ Parameters
533
+ ----------
534
+ params : dict | None, optional
535
+ Filter parameters (``holding_type``, ``holding_id`` …). ``None``
536
+ results in an unfiltered list.
537
+
538
+ Returns
539
+ -------
540
+ list[dict]
541
+ Serialised Holding-thresholds ordered by ``-effective_from``.
542
+ """
543
+ logger.info(f"In get_holding_thresholds {params =}")
544
+ data = self._get(url=self.base_url,
545
+ endpoint=self.urls.get("holding_thresholds"),
546
+ params=params)
547
+ logger.info(f"{data =}")
548
+ return data.get("data")
549
+
550
+ def update_holding_threshold(self, payload):
551
+ """Update an existing *Holding* threshold.
552
+
553
+ Parameters
554
+ ----------
555
+ payload : dict | str
556
+ Must include the primary key ``id`` and any fields to be changed
557
+ (e.g. ``threshold``, ``status`` or ``effective_to``).
558
+
559
+ Returns
560
+ -------
561
+ dict
562
+ Updated Holding-threshold object as returned by the backend.
563
+ """
564
+ logger.info(f"In update_holding_threshold {payload =}")
565
+ data = self._put(url=self.base_url,
566
+ endpoint=self.urls.get("holding_thresholds"),
567
+ json=payload)
568
+ logger.info(f"{data =}")
569
+ return data.get("data")
570
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bw-essentials-core
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Reusable utilities for S3, email, Data Loch, Microsoft Teams Notifications and more.
5
5
  Author: InvestorAI
6
6
  Author-email: support+tech@investorai.in
@@ -10,7 +10,7 @@ from setuptools import setup, find_packages
10
10
 
11
11
  setup(
12
12
  name="bw-essentials-core",
13
- version="0.1.7",
13
+ version="0.1.8",
14
14
  author="InvestorAI",
15
15
  author_email="support+tech@investorai.in",
16
16
  description="Reusable utilities for S3, email, Data Loch, Microsoft Teams Notifications and more.",