|
| 1 | +# Aggregate price on-chain account structure |
| 2 | + |
| 3 | +The pyth block-chain price oracle manages a number of on-chain accounts. Accounts are segregated into different types corresponding to product reference data, price/quote data and directory, or mapping data. Mapping accounts serve as a listing or mapping of other accounts. |
| 4 | + |
| 5 | +The relationships between different account types on-chain are as follows: |
| 6 | + |
| 7 | +``` |
| 8 | +
|
| 9 | + ------------- ------------- ------------- |
| 10 | + | |1 m| | | | |
| 11 | + | mapping |------->| product |------>| price | |
| 12 | + | | | | | (price) | |
| 13 | + ------------- ------------- ------------- |
| 14 | + | | |
| 15 | + V V |
| 16 | + ------------- ------------- |
| 17 | + | | | | |
| 18 | + | mapping | | price | |
| 19 | + | | | (twap) | |
| 20 | + ------------- ------------- |
| 21 | + | | |
| 22 | + V V |
| 23 | + ... ... |
| 24 | +
|
| 25 | +``` |
| 26 | + |
| 27 | +There exists a linked list of `mapping` accounts. Each contains a simple list of `product` account ids, or public keys. Each `product` contains a set of reference attributes corresponding to a single product or asset, such as BTC/USD or AAPL/USD. These attributes are stored as a list of text key/value pairs such as "symbol", "asset_type", "country" etc.. |
| 28 | + |
| 29 | +Each `product` account refers to the head of a linked-list of `price` accounts. `price` accounts are where a product's price and other metrics are stored. Each `price` account corresponds to a different "price_type". At the moment, these include "price", "twap" and "volatility". |
| 30 | + |
| 31 | + |
| 32 | +## pcrust example |
| 33 | + |
| 34 | +The pcrust example program uses the solana rust RPC API to load and print all pyth product and price data by bootstrapping from the root `mapping` account key. The output looks something like this: |
| 35 | + |
| 36 | +``` |
| 37 | +product_account .. 4SxmcsbJWVBWvuP2cRQDjFtAgdqzWWLbHESnUTH4CegT |
| 38 | + symbol.......... AAPL/USD |
| 39 | + asset_type...... Equity |
| 40 | + country......... US |
| 41 | + quote_currency.. USD |
| 42 | + tenor........... Spot |
| 43 | + description..... APPLE INC |
| 44 | + cms_symbol...... AAPL |
| 45 | + cqs_symbol...... AAPL |
| 46 | + nasdaq_symbol... AAPL |
| 47 | + price_account .. CeLD8TC7Ktv2o57EHP7rddh6TZBHXkAhTyfWgxsTYs21 |
| 48 | + price_type ... price |
| 49 | + exponent ..... -5 |
| 50 | + status ....... trading |
| 51 | + corp_act ..... nocorpact |
| 52 | + price ........ 12276250 |
| 53 | + conf ......... 1500 |
| 54 | + valid_slot ... 55519683 |
| 55 | + publish_slot . 55519684 |
| 56 | +product_account .. 9BQ2WKSVbfzpSJYyLCJuxVuiUFxHmQvkhhez94AdffEZ |
| 57 | + symbol.......... BTC/USD |
| 58 | + asset_type...... Crypto |
| 59 | + country......... US |
| 60 | + quote_currency.. USD |
| 61 | + tenor........... Spot |
| 62 | + jlqd_symbol..... BTCUSD |
| 63 | + price_account .. FCLf9N8xcN9HBA9Cw68FfEZoSBr4bYYJtyRxosNzswMH |
| 64 | + price_type ... price |
| 65 | + exponent ..... -9 |
| 66 | + status ....... trading |
| 67 | + corp_act ..... nocorpact |
| 68 | + price ........ 55233535000000 |
| 69 | + conf ......... 81650000000 |
| 70 | + valid_slot ... 55519684 |
| 71 | + publish_slot . 55519685 |
| 72 | +... |
| 73 | +
|
| 74 | +``` |
| 75 | + |
| 76 | +The details of each `product` account and their corresponding `price` accounts are dumped to stdout. |
| 77 | + |
| 78 | +Each `product` may have a slightly different set of reference attributes, depending on their type, but all have "symbol", "asset_type", "quote_currency" and "tenor". US equity products, for example, include various additional reference symbology that is useful for mapping pyth products to other industry-standard identifiers. |
| 79 | + |
| 80 | +Each `price` contains a "price" and "conf" value. "conf" represents a confidence interval on price and broadly corresponds to bid-offer spread. All "price"s are stored as 64bit integers with a fixed, implied number of decimal places defined by the "exponent" field. The AAPL price of 12276250 above, therefore, respresents a value of 122.76250 because the "exponent" is set at -5 or 5 decimal places. |
| 81 | + |
| 82 | +Each `price` has a "status" which is an enumeration of the following values: "trading", "halted", "auction" or "unknown". Only "trading" prices are valid. Equity products also contain a "corp_act" status to notify users of any ongoing corprate action event that may affect a product's price or symbology. |
| 83 | + |
| 84 | +The "valid_slot" and "publish_slot" fields correspond to which solana slots the aggregate price was published in. More on this in the next section. |
| 85 | + |
| 86 | + |
| 87 | +## Aggregate Price Procedure |
| 88 | + |
| 89 | +The pyth price represents an aggregate derived from multiple contributing market "quoters". It is a two-stage process to derive the aggregate price: first, individual quoters submit their prices along with what they believe to be the most recently confirmed solana slot value. The second stage gathers the latest prices from each quoter, discards those that are too old or not in a valid trading state and derives an aggregate price, currently through a simple median. |
| 90 | + |
| 91 | +The pyth program accumulates prices with respect to whatever the current slot is inside the solana node. This is called the "valid_slot" above. As soon as the slot ticks forward by one, the pyth program computes the aggregate price and publishes it with respect to the new "publish_slot" and starts repeating the process with a new "valid_slot". |
| 92 | + |
| 93 | +The aggregate "status" of a price is subject to whether there are any valid contributors (i.e. "unknown" status) or whether any contributors are in a "halted" or "auction" state. |
0 commit comments