moexapi 1.7.21__tar.gz → 1.7.22__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moexapi
3
- Version: 1.7.21
3
+ Version: 1.7.22
4
4
  Summary: Python API for MOEX ISS
5
5
  Author-email: Aliaksei Rak <kventinel@gmail.com>
6
6
  License: MIT License
@@ -66,6 +66,13 @@ Out[4]: [Candle(date=datetime.date(2023, 10, 2), low=165.51, high=168.86, open=1
66
66
 
67
67
  ### Bonds
68
68
 
69
+ `get_history()` returns `History.accrued_interest` from ISS `ACCRUEDINT`.
70
+ It is accrued coupon cash per security in `History.currency` (settlement
71
+ currency), not a percentage or a ruble conversion. Missing values remain `None`;
72
+ zero is a valid observation. Same-day board merges retain one matching value
73
+ and reject conflicting known values; if any merged observation is missing the
74
+ result is `None`. Split adjustments scale accrued cash with per-security prices.
75
+
69
76
  ```
70
77
  In [5]: moexapi.Bond(moexapi.get_ticker('SU26238RMFS4'))
71
78
  Out[5]: Bond(secid='SU26238RMFS4', shortname='ОФЗ 26238', amortization=[Amortization(date=datetime.date(2041, 5, 15), value=1000, initialfacevalue=1000)], coupons=[Coupon(date=2021-12-08, value=34.04), Coupon(date=2022-06-08, value=35.4), Coupon(date=2022-12-07, value=35.4), Coupon(date=2023-06-07, value=35.4), Coupon(date=2023-12-06, value=35.4), Coupon(date=2024-06-05, value=35.4), Coupon(date=2024-12-04, value=35.4), Coupon(date=2025-06-04, value=35.4), Coupon(date=2025-12-03, value=35.4), Coupon(date=2026-06-03, value=35.4), Coupon(date=2026-12-02, value=35.4), Coupon(date=2027-06-02, value=35.4), Coupon(date=2027-12-01, value=35.4), Coupon(date=2028-05-31, value=35.4), Coupon(date=2028-11-29, value=35.4), Coupon(date=2029-05-30, value=35.4), Coupon(date=2029-11-28, value=35.4), Coupon(date=2030-05-29, value=35.4), Coupon(date=2030-11-27, value=35.4), Coupon(date=2031-05-28, value=35.4), Coupon(date=2031-11-26, value=35.4), Coupon(date=2032-05-26, value=35.4), Coupon(date=2032-11-24, value=35.4), Coupon(date=2033-05-25, value=35.4), Coupon(date=2033-11-23, value=35.4), Coupon(date=2034-05-24, value=35.4), Coupon(date=2034-11-22, value=35.4), Coupon(date=2035-05-23, value=35.4), Coupon(date=2035-11-21, value=35.4), Coupon(date=2036-05-21, value=35.4), Coupon(date=2036-11-19, value=35.4), Coupon(date=2037-05-20, value=35.4), Coupon(date=2037-11-18, value=35.4), Coupon(date=2038-05-19, value=35.4), Coupon(date=2038-11-17, value=35.4), Coupon(date=2039-05-18, value=35.4), Coupon(date=2039-11-16, value=35.4), Coupon(date=2040-05-16, value=35.4), Coupon(date=2040-11-14, value=35.4), Coupon(date=2041-05-15, value=35.4)], offers=[])
@@ -26,6 +26,13 @@ Out[4]: [Candle(date=datetime.date(2023, 10, 2), low=165.51, high=168.86, open=1
26
26
 
27
27
  ### Bonds
28
28
 
29
+ `get_history()` returns `History.accrued_interest` from ISS `ACCRUEDINT`.
30
+ It is accrued coupon cash per security in `History.currency` (settlement
31
+ currency), not a percentage or a ruble conversion. Missing values remain `None`;
32
+ zero is a valid observation. Same-day board merges retain one matching value
33
+ and reject conflicting known values; if any merged observation is missing the
34
+ result is `None`. Split adjustments scale accrued cash with per-security prices.
35
+
29
36
  ```
30
37
  In [5]: moexapi.Bond(moexapi.get_ticker('SU26238RMFS4'))
31
38
  Out[5]: Bond(secid='SU26238RMFS4', shortname='ОФЗ 26238', amortization=[Amortization(date=datetime.date(2041, 5, 15), value=1000, initialfacevalue=1000)], coupons=[Coupon(date=2021-12-08, value=34.04), Coupon(date=2022-06-08, value=35.4), Coupon(date=2022-12-07, value=35.4), Coupon(date=2023-06-07, value=35.4), Coupon(date=2023-12-06, value=35.4), Coupon(date=2024-06-05, value=35.4), Coupon(date=2024-12-04, value=35.4), Coupon(date=2025-06-04, value=35.4), Coupon(date=2025-12-03, value=35.4), Coupon(date=2026-06-03, value=35.4), Coupon(date=2026-12-02, value=35.4), Coupon(date=2027-06-02, value=35.4), Coupon(date=2027-12-01, value=35.4), Coupon(date=2028-05-31, value=35.4), Coupon(date=2028-11-29, value=35.4), Coupon(date=2029-05-30, value=35.4), Coupon(date=2029-11-28, value=35.4), Coupon(date=2030-05-29, value=35.4), Coupon(date=2030-11-27, value=35.4), Coupon(date=2031-05-28, value=35.4), Coupon(date=2031-11-26, value=35.4), Coupon(date=2032-05-26, value=35.4), Coupon(date=2032-11-24, value=35.4), Coupon(date=2033-05-25, value=35.4), Coupon(date=2033-11-23, value=35.4), Coupon(date=2034-05-24, value=35.4), Coupon(date=2034-11-22, value=35.4), Coupon(date=2035-05-23, value=35.4), Coupon(date=2035-11-21, value=35.4), Coupon(date=2036-05-21, value=35.4), Coupon(date=2036-11-19, value=35.4), Coupon(date=2037-05-20, value=35.4), Coupon(date=2037-11-18, value=35.4), Coupon(date=2038-05-19, value=35.4), Coupon(date=2038-11-17, value=35.4), Coupon(date=2039-05-18, value=35.4), Coupon(date=2039-11-16, value=35.4), Coupon(date=2040-05-16, value=35.4), Coupon(date=2040-11-14, value=35.4), Coupon(date=2041-05-15, value=35.4)], offers=[])
@@ -40,6 +40,8 @@ class History:
40
40
  volume -- number of shares/bonds/currencies sold on the day
41
41
  value -- sum of all transactions in currency for the day
42
42
  currency -- currency of transaction value
43
+ accrued_interest -- accrued coupon cash per security in currency, or None
44
+ when ISS does not supply it (not a percent quote)
43
45
  """
44
46
  date: datetime.date
45
47
  low: float
@@ -51,11 +53,18 @@ class History:
51
53
  volume: T.Optional[int]
52
54
  value: T.Optional[float]
53
55
  currency: T.Optional[str] = None
56
+ accrued_interest: T.Optional[float] = None
54
57
 
55
58
  @classmethod
56
59
  def merge(cls, first: 'History', second: 'History'):
57
60
  assert first.date == second.date
58
61
  assert first.currency == second.currency, "Can't merge history in different currencies"
62
+ accrued_interest = None
63
+ if first.accrued_interest is not None and second.accrued_interest is not None:
64
+ if not np.isclose(first.accrued_interest, second.accrued_interest):
65
+ raise ValueError(f"Conflicting accrued interest on {first.date}")
66
+ # This is cash per security, not turnover: never sum across boards.
67
+ accrued_interest = first.accrued_interest
59
68
  return cls(
60
69
  date=first.date,
61
70
  low=min(first.low, second.low),
@@ -67,6 +76,7 @@ class History:
67
76
  volume=_maybe_sum(first.volume, second.volume),
68
77
  value=_maybe_sum(first.value, second.value),
69
78
  currency=first.currency,
79
+ accrued_interest=accrued_interest,
70
80
  )
71
81
 
72
82
  def mult(self, mult: float) -> None:
@@ -75,6 +85,8 @@ class History:
75
85
  self.open *= mult
76
86
  self.close *= mult
77
87
  self.mid_price *= mult
88
+ if self.accrued_interest is not None:
89
+ self.accrued_interest *= mult
78
90
  if self.volume is not None:
79
91
  self.volume /= mult
80
92
 
@@ -156,6 +168,7 @@ def _parse_history(
156
168
  volume=line.get("VOLUME"),
157
169
  value=value,
158
170
  currency=currency,
171
+ accrued_interest=line.get("ACCRUEDINT"),
159
172
  )
160
173
  if len(result) > 0 and result[-1].date == date:
161
174
  if board in boards:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: moexapi
3
- Version: 1.7.21
3
+ Version: 1.7.22
4
4
  Summary: Python API for MOEX ISS
5
5
  Author-email: Aliaksei Rak <kventinel@gmail.com>
6
6
  License: MIT License
@@ -66,6 +66,13 @@ Out[4]: [Candle(date=datetime.date(2023, 10, 2), low=165.51, high=168.86, open=1
66
66
 
67
67
  ### Bonds
68
68
 
69
+ `get_history()` returns `History.accrued_interest` from ISS `ACCRUEDINT`.
70
+ It is accrued coupon cash per security in `History.currency` (settlement
71
+ currency), not a percentage or a ruble conversion. Missing values remain `None`;
72
+ zero is a valid observation. Same-day board merges retain one matching value
73
+ and reject conflicting known values; if any merged observation is missing the
74
+ result is `None`. Split adjustments scale accrued cash with per-security prices.
75
+
69
76
  ```
70
77
  In [5]: moexapi.Bond(moexapi.get_ticker('SU26238RMFS4'))
71
78
  Out[5]: Bond(secid='SU26238RMFS4', shortname='ОФЗ 26238', amortization=[Amortization(date=datetime.date(2041, 5, 15), value=1000, initialfacevalue=1000)], coupons=[Coupon(date=2021-12-08, value=34.04), Coupon(date=2022-06-08, value=35.4), Coupon(date=2022-12-07, value=35.4), Coupon(date=2023-06-07, value=35.4), Coupon(date=2023-12-06, value=35.4), Coupon(date=2024-06-05, value=35.4), Coupon(date=2024-12-04, value=35.4), Coupon(date=2025-06-04, value=35.4), Coupon(date=2025-12-03, value=35.4), Coupon(date=2026-06-03, value=35.4), Coupon(date=2026-12-02, value=35.4), Coupon(date=2027-06-02, value=35.4), Coupon(date=2027-12-01, value=35.4), Coupon(date=2028-05-31, value=35.4), Coupon(date=2028-11-29, value=35.4), Coupon(date=2029-05-30, value=35.4), Coupon(date=2029-11-28, value=35.4), Coupon(date=2030-05-29, value=35.4), Coupon(date=2030-11-27, value=35.4), Coupon(date=2031-05-28, value=35.4), Coupon(date=2031-11-26, value=35.4), Coupon(date=2032-05-26, value=35.4), Coupon(date=2032-11-24, value=35.4), Coupon(date=2033-05-25, value=35.4), Coupon(date=2033-11-23, value=35.4), Coupon(date=2034-05-24, value=35.4), Coupon(date=2034-11-22, value=35.4), Coupon(date=2035-05-23, value=35.4), Coupon(date=2035-11-21, value=35.4), Coupon(date=2036-05-21, value=35.4), Coupon(date=2036-11-19, value=35.4), Coupon(date=2037-05-20, value=35.4), Coupon(date=2037-11-18, value=35.4), Coupon(date=2038-05-19, value=35.4), Coupon(date=2038-11-17, value=35.4), Coupon(date=2039-05-18, value=35.4), Coupon(date=2039-11-16, value=35.4), Coupon(date=2040-05-16, value=35.4), Coupon(date=2040-11-14, value=35.4), Coupon(date=2041-05-15, value=35.4)], offers=[])
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "moexapi"
7
- version = "1.7.21"
7
+ version = "1.7.22"
8
8
  description = "Python API for MOEX ISS"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Aliaksei Rak", email = "kventinel@gmail.com" }]
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