Orders and Trades
Most traders will use our website to create familiar "trades", implemented by one or more orders acting on a position. For instance, a "limit order" is an order that triggers to create a new position if price enters a certain range. A "stop loss" is two orders: one to create a position, and one that will trigger to close it if the position's PnL drops below a certain percent. Right now, our UI exposes simple trades that are familiar to most users. The exchange can handle very complicated trades, which will be supported by a future Advanced Trading interface and upgraded order bots.
Basic Trades
- Limit
- Market
- Trigger
Placing a limit order means you want to create a position as soon as the current dominance value rises above or below a certain value. A long limit order will trigger only while dominance is below the selected limit; a short limit order will trigger only while dominance is above the selected limit. For more information on limit orders, see Investopedia.
Unlike exchanges with true order books, limit orders will never execute at a price worse than the current market price. For instance, placing a long order with a limit of 40% while dominance is currently 30% will lead to the order immediately filling at 30%. On an order book exchange, the only guarantee of such orders is that the order will execute at the limit price or better. Such an order might be matched with a seller at 35%, leaving you worse off.
The most familiar type of trade. Placing a market order means you want to create a position at whatever the current dominance value is. For information on market orders, see Investopedia.
To protect users from unexpected price swings and frontrunning attacks, our "market orders" are implemented as limit orders that will execute at the current market price or 0.3% worse. For a traditional market order, with all the dangers that entails, place a limit order with a very high or low limit.
You can set a Stop Loss. This order will trigger to close the position once it has lost a certain percent of its value. This is useful to avoid liquidation. You can also set a stop loss to close once dominance has decreased (for long positions) or increased (for short positions) beyond a certain price. For more information, see Investopedia.
You can set a Take Profit. This order will trigger to close the position once it has gained a certain percent of its value. You can also set a take profit to close once dominance has increased (for long positions) or decreased (for short positions) beyond a certain price. For more information, see Investopedia.
Orders
Domination Finance allows users to submit orders, which automatically execute in response to an execution trigger. Each order has an action that it will execute when triggered. Users may submit collateral with their order, to be used by the order's action. If an order is canceled or expires, that collateral is returned to the user.
Trigger Criteria
Each order has a single execution trigger that compares an on-chain metric (for instance, the value of Bitcoin Dominance) to a target value (for instance, 50%).
- Product Price
- Position PnL %
Compare a product's price to a target value.
const priceTriggerOrder = {
productId: ethers.utils.formatBytes32String('ETHDOM'),
triggerDetails: {
triggerType: TriggerType.PRICE,
triggerCondition: TriggerCondition.GTE, // or .LTE
triggerPrice: E18.mul(25).div(100), // 25%
},
...
}
Compare a position's PnL percent () to a target.
const pnlRateTriggerOrder = {
accountPositionId: somePositionLabel,
triggerDetails: {
triggerType: TriggerType.PNL_RATE,
triggerCondition: TriggerCondition.GTE, // or .LTE
triggerPnlRate: E18.mul(5).div(100), // 5%
},
...
}
Actions
Each Order contains one action, which will interact with DomFiPerp on behalf of a user.
- Increase Position
- Decrease Position
- Add Margin
- Remove Margin
When triggered, these actions spend collateral to create a new position or increase an existing one with the specified margin
and leverage
.
They incur a trade fee of 0.15% of the size () increase.
const increaseOrderParams = {
actionType: ActionType.INCREASE_SIZE,
action: {
leverage: E18.mul(25).div(10), // 2.5x
margin: E6.mul(100), // $100
},
accountPositionId: existingPositionLabel,
...
}
When creating a new position, order.isLong
and order.productId
must also be specified.
When triggered, these actions decrease a position by the specified size
or close it entirely. The resulting collateral, and any realized PnL, is returned to the position's owner.
They incur a trade fee of 0.15% of the size () decrease.
const decreaseOrderParams = {
actionType: ActionType.DECREASE_SIZE,
action: {
size: E6.mul(250), // $250
},
accountPositionId: somePositionLabel,
...
}
When triggered, these actions spend collateral to increase a position's margin while keeping its size constant. This is equivalent to an Increase Size action with leverage 0.
Since position size does not increase, these actions incur no trade fee.
const addMarginOrderParams = {
actionType: ActionType.ADD_MARGIN,
action: {
margin: E6.mul(100), // $100
},
accountPositionId: existingPositionLabel,
...
}
Since position size remains the same, and margin increases, leverage must decrease. Domination Finance does not allow positions with leverage below 1x. If executing an Add Margin order would create a position with less than 1x leverage, execution will revert. You will have to cancel such orders or let them expire to reclaim your collateral.
When triggered, these actions remove margin from a position while keeping its size constant. They must include either a nonzero removeMarginFactor
or a nonzero margin
, but not both.
Since position size does not decrease, these actions incur no trade fee.
const removeMarginOrderParams = {
actionType: ActionType.REMOVE_MARGIN,
action: { // choose only one
margin: 0,
removeMarginFactor: E18.mul(70).div(100), // 70%
},
accountPositionId: existingPositionLabel,
...
}
Margin cannot be removed from a position if doing so would cause the position to be liquidatable, raise its leverage above the maximum, or lower its margin below the global minimum requirement. A removeMarginFactor
parameter causes the OrderBook to calculate the maximum and remove a fraction of that "safe removal amount".
:::
Solidity Overview
Orders share some common fields: the account to which they belong, the position to affect, an execution deadline, and creation/cancelation/execution timestamps. Orders also include an arbitrary bytes userData
, used for tagging orders but not processed on chain. Currently, this is used to differentiate market orders from limit orders in the UI.
struct Order {
address payable owner;
uint256 executionFee; // gas reimbursement to order executor
uint64 submittedAt;
uint64 canceledAt;
uint64 executedAt;
uint64 executionDeadline;
PositionLabel accountPositionId;
bytes32 productId; // omit unless PRICE trigger or creating a new position
bool isLong; // omit unless creating a new position
TriggerDetails triggerDetails;
ActionType actionType;
OrderDetails action;
bytes userData;
}
Each order has a TriggerDetails that specifies when it can execute.
struct TriggerDetails {
TriggerType triggerType;
TriggerCondition triggerCondition;
FPSigned triggerPnLRate;
FPUnsigned triggerPrice;
}
enum TriggerType {
INVALID,
PRICE,
PNL_RATE
}
enum TriggerCondition {
LTE,
GTE
}
Each order has an Action that specifies what it will do once executed:
enum ActionType {
INCREASE_SIZE,
DECREASE_SIZE,
ADD_MARGIN,
REMOVE_MARGIN
}
struct OrderDetails {
FPUnsigned leverage;
uint256 margin;
uint256 tradeFee; // calculated at order submission
FPUnsigned size;
FPUnsigned removeMarginFactor;
}
For more detailed information, see the OrderBookV1 API documentation.