Prices
Important Notice
The Prices Antara Module is currently in development.
The specifics of the implementation are subject to change.
Please reach out to the Komodo team for more information before attempting to use this module in a production environment.
The Prices Antara Module offers a decentralized and incentivized margin-trading system on a Smart Chain. This allows users to open long and short leveraged positions against the "House" (the module itself).
A player opens a position with the desired betting amount and leverage. They can close the position anytime and receive the current equity that is in a non-negative state.
When the debt ratio of a player is close to exceeding the allowed limits, other players on the network can liquidate the indebted player's account. The liquidating players thereby receive as an incentive a small percentage of the indebted player's holdings.
For a more detailed explanation of the nature of "leveraged positions" and other terms related to margin trading, please read this explanation section.
The creation of the Prices Antara Module required the existence of a separate Antara-based module that provides trustless and decentralized price feeds. The Komodo community named this separate type of module a "Decentralized Trustless Oracle," or DTO for brevity.
In order to create the trustless and decentralized price feeds, Komodo's DTO technology relies on timestamp consensus rules.
The DTO requires the miners of the Smart Chain to include the required off-chain data as a part of the OP_RETURN in the coinbase transaction (the transaction that pays the block reward to the miner).
The validation of the off-chain data is part of the consensus rules. If the data is false, the block is rejected by the network, which serves as an incentive for the miner to be truthful. To achieve consensus, all nodes allow for an error margin of approximately 1%
in the reported data.
The Prices module retrieves prices of stocks and cryptocurrencies through the Antara Customization Parameters ac_stocks and ac_prices, respectively.
The module can extract data from a web source that can be accessed using the http/https
protocols and return the data as a json object using the ac_feeds parameter.
The module also has a pre-configured feed that always retrieves values for the pairs BTC_USD
, BTC_EUR
and BTC_GBP
.
The DTO provides the required price feed. For markets, such as AMZN/KMD
, that do not exist in real life, the DTO offers synthetic prices.
To counter the possibility of manipulation of price data by a miner (for example, a miner could attempt to take advantage of the 1%
error allowed to win an open bet), when a position is opened the price of purchase is not set until a twenty-four hour period has past. During this period, the module tracks the prices of the relevant currencies. At the end of the period, the module automatically sets the price of purchase for the position based on the price averages.
For long positions, the lock price (also called the "cost basis") is the maximum among averages; for short positions, the lock price is the minimum among averages.
Players should not expect high-speed trading in this type of system.
Assume Player X has $100
USD and is certain that Bitcoin (BTC) will soon have a large increase in value relative to USD.
In this type of scenario, Player X can use margin trading to find a greater profit percentage than he would by simply buying $100
USD worth of BTC and holding it.
However, margin trading increases the risk placed on Player X.
If Player X simply buys his BTC and then sells it after its price increases by 5%
, Player X's profit is 5%
, or $5
USD. Similarly, the loss is $5
USD if the price decreases by 5%
.
In a margin-trading system there are two roles: Lender and Trader.
In the example here, Player X is the Trader.
Lender facilitates Trader in borrowing a multiple ("leverage") of the deposited collateral ($100
). Thereby the Trader can trade using the total amount (deposit + leverage).
For example, Player X desires to trade with a leverage of 10
. This is $100 * 10 = $1000
USD.
Lender gives Player X the remaining $900
USD. Player X now buys $1000
USD worth of BTC.
If the price increases by 5%
and Player X sells their BTC, the profit is $50
USD.
Player X returns the loan of $900
and is left with $150
USD, which amounts to a profit of 50%
.
Alternatively, the price can drop and the Trader can lose higher amounts. In this example, the value of BTC relative to USD drops by 5%
.
Player X now only has $950
USD worth of BTC. Player X sells and returns the loan amount of $900
USD, and has $50
USD remaining.
This is now a loss of 50%
.
In many scenarios, a Lender has the ability to liquidate the Trader at any given time, and will force liquidation before the player can lose more than they are able to immediately repay.
The following stop-loss values are common in margin trading:
- A
10x
leverage can tolerate up to a10%
decrease in price before forced liquidation occurs - A
100x
leverage can tolerate up to a1%
decrease in price before forced liquidation occurs
Assuming $0
fees, a player can calculate actual profit or loss percentage by the following formula.
price change in percent * leverage
The Trader's "position" is the amount of coins the player places as a bet.
The Trader's "equity" is the amount of coins the player can withdraw at the current moment. Equity is calculated by the following formula.
position + (profit or loss)
"Cost basis" is the price at which the bet is opened.
The Prices data on a Smart Chain is made available by an active Decentralized Trustless Oracle (DTO), which is comprised of all nodes and miners on the network.
There are limitations to a DTO. For example, the DTO cannot offer price feeds for all possible markets across the world. Furthermore, users on the network may desire a trading pair that does not yet have a real market.
In such cases, price data of two or more different pairs can be used to derive the price of a desired pair. The resulting price data is called a "Synthetic Price."
For example, suppose the DTO for a Smart Chain does not supply the price data for the pair AMZN/KMD
. However, the chain does supply the price data for the pairs AMZN/USD
, USD/BTC
and BTC/KMD
.
The synthetic price of AMZN/KMD
is available through considering the prices of all the three pairs.
A simple syntax is offered in the Komodo API for calculating synthetic prices and use their value on the Smart Chain.
This syntax is based on the Forth programming language.
In calculating a synthetic price, the Komodo API supports up to three pairs of prices and offers four operations:
- invert(
!
) - multiply(
*
) - divide(
/
)
These operations can be supplied with positive and negative integers. The integers allow the calculation of synthetic prices for baskets of assets or indexes. The negative integers can be used to short a price.
For example, the synthetic price of a basket with 3/4
parts BTC and 1/4
parts BCH can be calculated.
The data in each price feed of the DTO has a key that appears in the structure of AAA_BBB
. This is interpreted to mean that the price for the asset AAA
is provided in the data in terms of another asset BBB
.
For example, the price of BTC in terms of USD is denoted by BTC_USD
Understanding the concept of a stack is essential when using the Komodo API's syntax for calculating synthetic prices.
Stacks are dynamic data structures that follow the Last In First Out (LIFO) principle. In other words, the last item to be inserted into a stack is the first one to be deleted from it.
For example, assume a stack of trays on a table. When a person adds another tray to the stack, they place the tray on top of the stack. When a person removes a tray from the stack, they remove the tray at the top of the stack. Therefore, the last item added to the stack is also the first item removed.
Stacks have restrictions on the insertion and deletion of elements.
Elements can be inserted or deleted only from one end of the stack (the top). The element at the top is called the top element.
The operations of inserting and deleting elements are called push and pop respectively.
When the top element of a stack is deleted, if the stack remains non-empty, the element just below the previous top element becomes the new top element of the stack.
For example, in the stack of trays, if a person takes the tray from the top, the tray just below it automatically becomes the top element.
The allowed symbols in the Komodo API's syntax are:
- prices
- operations: invert(
!
), multiply(*
), divide(/
) - positive and negative integers
The interpretation of the symbols in all the possible cases is described in the subsequent sections.
The Komodo API limits the depth of the stack for prices to three, as this appears to be reasonably sufficient data for calculating synthetic prices.
A synthetic price is calculated by summing the computed prices with integers that represent weights
.
The weight
can be any positive or negative integer whose absolute value is less than 2048
.
After an operator acts on the stack, a weight must be applied to the top element.
If the synthetic price calculation does not require the inclusion of a weight, set the weight's integer value to 1
.
With the weights sets, the module automatically calculates the resulting synthetic price.
"BTC_USD, 3, KMD_USD, 1" gives the integer weight of 3
to the price pair of BTC_USD
and the integer weight of 1
to the price pair of KMD_USD
. The resulting value is described as BTC_USD*(3/4) + KMD_USD*(1/4)
.
A "spread" in trading is a term that describes the amount or distance between the values of the maximum amount at which a buyer is willing to purchase and the minimum amount at which a seller is willing to sell.
To create a spread, use a negative weight for one of the synthetics.
For example, "BTC_USD, -2, KMD_USD, 1" gives the spread: KMD_USD - 2 * BTC_USD
. When KMD_USD
gains 2x more than BTC_USD
, percentage wise, the spread would essentially disappear.
Operator | Function |
---|---|
! (inverse) | pops the top stack element, inverts it, and pushes it back on to the stack |
"BTC_USD, !, 1" is computed to "USD_BTC".
Operator | Function |
---|---|
* | pops two elements from the top of the stack, multiplies them, and pushes the result back on to the stack |
/ | pops two elements from the top of the stack, performs a division with the first element as the denominator and the second element as the numerator, and pushes the result back on to the stack |
- "BTC_USD, USD_JPY, *, 1" is computed to "BTC_JPY"
- "BTC_EUR, BTC_USD, /, 1" is computed to "USD_EUR"
Each of these operators act on top of the stack in the order from left to right. It is possible that the value from an earlier computation rests at the top of the stack.
Operator | Function |
---|---|
*// | pops three elements from the top of the stack, inverts the last two out, multiplies them and pushes the result back on to the stack |
**/ | pops three elements from the top of the stack, inverts the last one out, multiplies them and pushes the result back on to the stack |
*** | pops three elements from the top of the stack, multiplies them, and pushes the result back on to the stack |
/// | pops three elements from the top of the stack, inverts all of them, multiplies them, and pushes the result back on to the stack |
mypriceslist [all|open|closed]
The mypriceslist
method returns the list of transaction ids (txid) of the bets executed on the Smart Chain from the executing user's pubkey. By default, the method returns both open and closed bets.
Name | Type | Description |
---|---|---|
"all|open|closed" | (string, optional) | the filter to apply to the list all - lists all of the user's bets open - lists the user's bets that are open closed - lists the user's bets that are closed |
Name | Type | Description |
---|---|---|
Array | (array of strings) | an array containing the txid's of the bets that satisfy the applied filter |
Command:
./komodo-cli -ac_name=HELLOWORLD mypriceslist
prices maxsamples
The prices
method returns samples of the data that has successfully been added to the Smart Chain via the price-feed oracles.
The argument maxsamples
defines the maximum number of samples to display for each price.
Name | Type | Description |
---|---|---|
maxsamples | (number) | the maximum number of samples to list |
Name | Type | Description |
---|---|---|
"firstheight" | (number) | |
"timestamps" | (array of numbers) | the unix timestamps at which the samples were collected |
"pricefeeds" | (array of jsons) | the unix timestamps at which the samples were collected |
"name" | (string) | the name (symbol) of the price |
"prices" | (array of arrays containing numbers) | the mined (actual received) price; correlated price; smoothed price |
"result" | (string) | whether the command executed successfully |
"seed" | (number) | |
"height" | (number) | |
"maxsamples" | (number) | the maximum number of samples displayed |
"width" | (number) | |
"daywindow" | (number) | |
"numpricefeeds" | (number) | the total number of price feeds available on the Smart Chain |
Command:
./komodo-cli -ac_name=HELLOWORLD prices 5
pricesaddfunding bettxid amount
The pricesaddfunding
method adds the amount
of funding from the user's wallet to the bettxid
bet.
This can reduce the bettxid
owner's risk of liquidation.
Name | Type | Description |
---|---|---|
bettxid | (string) | the transaction id returned previously by the pricesbet method |
amount | (number) | the amount of funding to be added to the bet |
Name | Type | Description |
---|---|---|
"hex" | (string) | the transaction in hex format; broadcast this value using the sendrawtransaction method |
"txid" | (string) | the transaction id |
"result" | (string) | whether the command executed successfully |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesaddfunding 573d45389ce9394d35f14f04f48b72a2ac639fdecf0afbe11b3d5dbf07e8fce9 2
pricesaddress [pubkey]
The pricesaddress
method returns information about the local instance of the Antara Prices Module on the Smart Chain and about associated addresses.
Optionally, if a pubkey is supplied, this method also returns the corresponding Prices CC Address and balance.
Name | Type | Description |
---|---|---|
pubkey | (string, optional) | the pubkey of another user on the network |
Name | Type | Description |
---|---|---|
"result" | (string) | whether the command executed successfully |
"PricesCCAddress" | (string) | taking the contract's EVAL code as a modifier, this is the public address that corresponds to the contract's privkey |
"PricesCCBalance" | (number) | the amount of funds in the PricesCCAddress |
"PricesNormalAddress" | (string) | the unmodified public address generated from the contract's privkey |
"PricesNormalBalance" | (number) | the amount of funds in the PricesNormalAddress |
"PricesCCTokensAddress" | (string) | the public address where Tokens are locked in the Prices module |
"myCCAddress(Prices)" | (string) | taking the module's EVAL code as a modifier, this is the Antara address from the pubkey of the user |
"myCCbalance(Prices)" | (number) | the amount of funds in the myCCAddress(Prices) |
"myaddress" | (string) | the public address of the pubkey used to launch the chain |
"mybalance" | (number) | the amount of funds in the myaddress |
"myaddr" | (string) | |
"houseaddr" | (string) | the public address of the House |
"exposureaddr" | (string) |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesaddress
pricesbet amount leverage "synthetic-expression"
The pricesbet
method is used to open a bet.
The resulting transaction id is called the bettxid
of this bet and is used in most of the subsequent RPC calls
Name | Type | Description |
---|---|---|
amount | (number) | the amount of the Smart Chain's native coin to bet |
leverage | (number) | the leverage to be used to open the bet; use positive integers for longs, negative integers for shorts |
synthetic-expression | (string) | the synthetic expression against which the bet is opened |
Name | Type | Description |
---|---|---|
"hex" | (string) | the transaction in hex format; broadcast this value using the sendrawtransaction method |
"txid" | (string) | the transaction id |
"result" | (string) | whether the command executed successfully |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesbet 1 2 "BTC_USD,1"
pricescashout bettxid
The pricescashout
method can be used to cash out the bettxid
bet. At the moment this method is executed, the user's equity must be positive and the bet must be open and not rekt.
Name | Type | Description |
---|---|---|
bettxid | (string) | the transaction id returned previously by the pricesbet method |
Name | Type | Description |
---|---|---|
bets | (array of json) | the bets that are open currently |
positionsize | (number) | the amount of native coin used to open the bet |
profits | (number) | the profits that can be actualized if the bet is closed at this moment; the value is negative if it is a loss |
costbasis | (number) | the price that has been locked in as the opening price of the bet |
firstheight | (number) | |
leverage | (number) | the leverage used to open the bet |
TotalPositionSize | (number) | the amount of native coin used to open all the bets |
TotalProfits | (number) | the total profits that can be actualized if the bets are closed at this moment; the value is negative if it is a loss |
equity | (number) | the amount of native Smart Chain coin that can be redeemed if the bet is cashed out at this moment |
LastPrice | (number) | the last known price |
LastHeight | (number) | the block height at which LastPrice was noted |
"hex" | (string) | the transaction in hex format; broadcast this value using the sendrawtransaction method |
"txid" | (string) | the transaction id |
"result" | (string) | whether the command executed successfully |
Command:
./komodo-cli -ac_name=HELLOWORLD pricescashout 573d45389ce9394d35f14f04f48b72a2ac639fdecf0afbe11b3d5dbf07e8fce9
pricesgetorderbook
The pricesgetorderbook
method shows the currently open bets and their details. The method also shows information about the house wallet's balance and statistics about the bets on the Smart Chain.
Name | Type | Description |
---|---|---|
(none) |
Name | Type | Description |
---|---|---|
Symbol of a Price | (string) | whether the command executed successfully |
positions | (array of json) | whether the command executed successfully |
isOpen | (number) | whether the bet is open; 0 if false and 1 if true |
expression | (string) | the synthetic expression supplied by the user |
positionsize | (number) | the amount of native coin used to open the bet |
leverage | (number) | the leverage used to open the bet |
costbasis | (number) | the price that has been locked in as the opening price of the bet |
lastprice | (number) | the last known price |
equity | (number) | the amount of native Smart Chain coin that can be redeemed if the bet is cashed out at this moment |
isUpPosition | (number) | |
DiffLeveragedPosition | (number) | |
TotalFund | (number) | the total amount of the Smart Chain's coins available in the House's public address |
TotalEquity | (number) | the total amount of equity across all the bets |
TotalRekt | (number) | the total number of bets that are already rekt |
TotalBets | (number) | the total number of active bets |
TotalCashoutBets | (number) | the total number of bets that have been cashed out |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesgetorderbook
pricesinfo bettxid [height]
The pricesinfo
method returns information about the bet referred by the bettxid
bet.
Name | Type | Description |
---|---|---|
bettxid | (string) | the transaction id returned previously by the pricesbet method |
height | (number, optional) | the height at which the information about the bet is required |
Name | Type | Description |
---|---|---|
rekt | (number) | whether the bet is rekt; 0 if false and 1 if true |
open | (number) | whether the bet is open; 0 if false and 1 if true |
expression | (string) | the synthetic expression supplied by the user |
reduced | (string) | the reduced synthetic expression derived from the one supplied by the user |
costbasis | (number) | the price that has been locked in as the opening price of the bet |
bets | (array of json) | the bets that are open currently |
positionsize | (number) | the amount of native coin used to open the bet |
profits | (number) | the profits that can be actualized if the bet is closed at this moment; the value is negative if the closing amount is a loss |
costbasis | (number) | the opening price of the bet; this value is locked for the duration of the bet |
firstheight | (number) | |
leverage | (number) | the leverage used to open the bet |
TotalPositionSize | (number) | the amount of native coin used to open all the bets |
TotalProfits | (number) | the total profits that can be actualized if the bets are closed at this moment; the value is negative if the amount is a loss |
equity | (number) | the amount of native Smart Chain coin that can be redeemed if the bet is cashed out at this moment |
LastPrice | (number) | the last known price |
LastHeight | (number) | the block height at which LastPrice was noted |
LiquidationPrice | (number) | the price at which the bet will be eligible for liquidation |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesinfo 573d45389ce9394d35f14f04f48b72a2ac639fdecf0afbe11b3d5dbf07e8fce9
priceslist [all|open|closed]
The priceslist
method returns the list of transaction id's (txid) of all the bets executed on chain. The method returns both open and closed bets by default.
Name | Type | Description |
---|---|---|
"all|open|closed" | (string, optional) | the filter to apply to the list all - lists all of the user's bets open - lists the user's bets that are open closed - lists the user's bets that are closed |
Name | Type | Description |
---|---|---|
Array | (array of strings) | An array containing the txid's of the bets that satisfy the applied filter |
Command:
./komodo-cli -ac_name=HELLOWORLD priceslist
pricesrefillfund amount
The pricesrefillfund
method adds funds to the house (the Global CC address).
Name | Type | Description |
---|---|---|
amount | (amount) | the amount of coins to be added to the House's public address |
Name | Type | Description |
---|---|---|
"hex" | (string) | the transaction in hex format; broadcast this value using the sendrawtransaction method |
"txid" | (string) | the transaction id |
"result" | (string) | whether the command executed successfully |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesrefillfund 100000
pricesrekt bettxid height
The pricesrekt
method creates a transaction that liquidates a bet that is "rekt" — a bet where the debt ratio has exceeded maximum limits and is now open to liquidation.
A bet that is rekt has an IsRekt: 1
flag in its pricesinfo call.
The pricesrekt
call requires some proof-of-work (PoW) activity from the machine of the executing user. This deters spamming.
All nodes on the network are incentivised to execute this transaction as it rewards some of the liquidated funds to the node that created the rekt transaction.
Name | Type | Description |
---|---|---|
bettxid | (string) | the transaction id returned previously by the pricesbet method |
height | (number, optional) | the height at which the bet is rekt |
Name | Type | Description |
---|---|---|
bets | (array of json) | the bets that are open currently |
positionsize | (number) | the amount of native coin used to open the bet |
profits | (number) | the profits that can be actualized if the bet is closed at this moment; the value is negative if the amount is a loss |
costbasis | (number) | the opening price of the bet |
firstheight | (number) | |
leverage | (number) | the leverage used to open the bet |
TotalPositionSize | (number) | the amount of native coin used to open all the bets |
TotalProfits | (number) | the total profits that can be actualized if the bets are closed at this moment; the value is negative if this amount is a loss |
equity | (number) | the amount of native Smart Chain coin that can be redeemed if the bet is cashed out at this moment |
LastPrice | (number) | the last known price |
LastHeight | (number) | the block height at which LastPrice was noted |
"result" | (string) | whether the command executed successfully |
"error" | (string) | the error encountered |
Command:
./komodo-cli -ac_name=HELLOWORLD pricesrekt 573d45389ce9394d35f14f04f48b72a2ac639fdecf0afbe11b3d5dbf07e8fce9 1540