Skip to content

Commit 7c05112

Browse files
jayantkJayant Krishnamurthyali-bahjati
authored
Account for confidence interval in price difference check (#55)
* adjusted price difference * pre-commit * add test * Bump version --------- Co-authored-by: Jayant Krishnamurthy <[email protected]> Co-authored-by: Ali Behjati <[email protected]>
1 parent e5fb272 commit 7c05112

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ ignore_missing_imports = true
44

55
[tool.poetry]
66
name = "pyth-observer"
7-
version = "0.1.9"
7+
version = "0.1.10"
88
description = "Alerts and stuff"
99
authors = []
1010
readme = "README.md"

pyth_observer/check/publisher.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ def run(self) -> bool:
194194
if self.__state.price == 0:
195195
return True
196196

197-
price_diff = abs(self.__state.price - self.__state.price_aggregate)
198-
deviation = (price_diff / self.__state.price_aggregate) * 100
197+
deviation = (self.ci_adjusted_price_diff() / self.__state.price_aggregate) * 100
199198

200199
# Pass if deviation is less than max distance
201200
if deviation <= self.__max_aggregate_distance:
@@ -205,8 +204,7 @@ def run(self) -> bool:
205204
return False
206205

207206
def error_message(self) -> str:
208-
price_diff = abs(self.__state.price - self.__state.price_aggregate)
209-
deviation = (price_diff / self.__state.price_aggregate) * 100
207+
deviation = (self.ci_adjusted_price_diff() / self.__state.price_aggregate) * 100
210208

211209
return dedent(
212210
f"""
@@ -219,6 +217,12 @@ def error_message(self) -> str:
219217
"""
220218
).strip()
221219

220+
# Returns the distance between the aggregate price and the closest side of the publisher's confidence interval
221+
# Returns 0 if the aggregate price is within the publisher's confidence interval.
222+
def ci_adjusted_price_diff(self) -> float:
223+
price_only_diff = abs(self.__state.price - self.__state.price_aggregate)
224+
return max(price_only_diff - self.__state.confidence_interval, 0)
225+
222226

223227
PUBLISHER_CHECKS = [
224228
PublisherWithinAggregateConfidenceCheck,

tests/test_checks_price_feed.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pyth_observer.check.price_feed import PriceFeedOfflineCheck, PriceFeedState
55

66

7-
def test_price_feed_aggregate_check():
7+
def test_price_feed_offline_check():
88
state = PriceFeedState(
99
symbol="Crypto.BTC/USD",
1010
asset_type="Crypto",

tests/test_checks_publisher.py

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from pythclient.pythaccounts import PythPriceStatus
2+
from pythclient.solana import SolanaPublicKey
3+
4+
from pyth_observer.check.publisher import PublisherPriceCheck, PublisherState
5+
6+
7+
def make_state(
8+
pub_slot: int,
9+
pub_price: float,
10+
pub_conf: float,
11+
agg_slot: int,
12+
agg_price: float,
13+
agg_conf: float,
14+
) -> PublisherState:
15+
return PublisherState(
16+
publisher_name="publisher",
17+
symbol="Crypto.BTC/USD",
18+
public_key=SolanaPublicKey("2hgu6Umyokvo8FfSDdMa9nDKhcdv9Q4VvGNhRCeSWeD3"),
19+
status=PythPriceStatus.TRADING,
20+
aggregate_status=PythPriceStatus.TRADING,
21+
slot=pub_slot,
22+
aggregate_slot=agg_slot,
23+
latest_block_slot=agg_slot,
24+
price=pub_price,
25+
price_aggregate=agg_price,
26+
confidence_interval=pub_conf,
27+
confidence_interval_aggregate=agg_conf,
28+
)
29+
30+
31+
def test_publisher_price_check():
32+
def check_is_ok(
33+
state: PublisherState, max_aggregate_distance: int, max_slot_distance: int
34+
) -> bool:
35+
return PublisherPriceCheck(
36+
state,
37+
{
38+
"max_aggregate_distance": max_aggregate_distance,
39+
"max_slot_distance": max_slot_distance,
40+
},
41+
).run()
42+
43+
# check triggering threshold for price difference
44+
state1 = make_state(1, 100.0, 2.0, 1, 110.0, 1.0)
45+
assert check_is_ok(state1, 10, 25)
46+
assert not check_is_ok(state1, 6, 25)

0 commit comments

Comments
 (0)