Skip to content

Commit

Permalink
Account for confidence interval in price difference check (#55)
Browse files Browse the repository at this point in the history
* adjusted price difference

* pre-commit

* add test

* Bump version

---------

Co-authored-by: Jayant Krishnamurthy <[email protected]>
Co-authored-by: Ali Behjati <[email protected]>
  • Loading branch information
3 people authored Feb 8, 2023
1 parent e5fb272 commit 7c05112
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ignore_missing_imports = true

[tool.poetry]
name = "pyth-observer"
version = "0.1.9"
version = "0.1.10"
description = "Alerts and stuff"
authors = []
readme = "README.md"
Expand Down
12 changes: 8 additions & 4 deletions pyth_observer/check/publisher.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ def run(self) -> bool:
if self.__state.price == 0:
return True

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

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

def error_message(self) -> str:
price_diff = abs(self.__state.price - self.__state.price_aggregate)
deviation = (price_diff / self.__state.price_aggregate) * 100
deviation = (self.ci_adjusted_price_diff() / self.__state.price_aggregate) * 100

return dedent(
f"""
Expand All @@ -219,6 +217,12 @@ def error_message(self) -> str:
"""
).strip()

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


PUBLISHER_CHECKS = [
PublisherWithinAggregateConfidenceCheck,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_checks_price_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pyth_observer.check.price_feed import PriceFeedOfflineCheck, PriceFeedState


def test_price_feed_aggregate_check():
def test_price_feed_offline_check():
state = PriceFeedState(
symbol="Crypto.BTC/USD",
asset_type="Crypto",
Expand Down
46 changes: 46 additions & 0 deletions tests/test_checks_publisher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from pythclient.pythaccounts import PythPriceStatus
from pythclient.solana import SolanaPublicKey

from pyth_observer.check.publisher import PublisherPriceCheck, PublisherState


def make_state(
pub_slot: int,
pub_price: float,
pub_conf: float,
agg_slot: int,
agg_price: float,
agg_conf: float,
) -> PublisherState:
return PublisherState(
publisher_name="publisher",
symbol="Crypto.BTC/USD",
public_key=SolanaPublicKey("2hgu6Umyokvo8FfSDdMa9nDKhcdv9Q4VvGNhRCeSWeD3"),
status=PythPriceStatus.TRADING,
aggregate_status=PythPriceStatus.TRADING,
slot=pub_slot,
aggregate_slot=agg_slot,
latest_block_slot=agg_slot,
price=pub_price,
price_aggregate=agg_price,
confidence_interval=pub_conf,
confidence_interval_aggregate=agg_conf,
)


def test_publisher_price_check():
def check_is_ok(
state: PublisherState, max_aggregate_distance: int, max_slot_distance: int
) -> bool:
return PublisherPriceCheck(
state,
{
"max_aggregate_distance": max_aggregate_distance,
"max_slot_distance": max_slot_distance,
},
).run()

# check triggering threshold for price difference
state1 = make_state(1, 100.0, 2.0, 1, 110.0, 1.0)
assert check_is_ok(state1, 10, 25)
assert not check_is_ok(state1, 6, 25)

0 comments on commit 7c05112

Please sign in to comment.