Skip to content
This repository has been archived by the owner on Dec 29, 2023. It is now read-only.

Commit

Permalink
Margin market order (#38)
Browse files Browse the repository at this point in the history
* save

* feat: fix margin order and impl market buy to margin order

* fix: cargo.toml

* fix: warning

* feat: update FE Script
  • Loading branch information
politeWall authored Nov 23, 2023
1 parent 2bf661f commit 9a62052
Show file tree
Hide file tree
Showing 69 changed files with 1,055 additions and 329 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ A spot order is fulfilled when the specified price set by the trader aligns with

- **Stop Loss Functionality**: Enable users to set automated orders that trigger when the asset's price reaches a specified lower limit, minimizing potential losses.
- **Limit Sell Functionality**: Allow users to set automated orders that execute when the asset's price reaches a specified upper limit, securing profits.
- **Limit Buy Fuctionality**: Allow user to set automated orders that execute when the limit price is reaches, securing profits.
- **Limit Buy Fuctionality**: Allow users to set automated orders that execute when the limit price is reaches, securing profits.
- **Market Buy Fuctionality**: Allow users to set automated orders that will execute at market price

### Margin Order

A margin order involves trading an asset using funds provided by a third party. It allows users to trade larger positions with a smaller initial capital outlay.

- **Long Position Functionality**: Allows users to borrow an asset to sell it, hoping to repurchase it later at a lower price, thus profiting from the difference.
- **Short Position Functionality**: Allows users to borrow an asset, selling it with the expectation of buying it back at a lower price to repay the loan and pocket the difference.
- **Unspecified Position Functionality**: A neutral or unspecified position in a margin order, potentially indicating no active trading or a position that isn't explicitly long or short.
- **Stop Loss Functionality**: Enable users to set automated orders that trigger when the asset's price reaches a specified lower limit, minimizing potential losses.
- **Limit Sell Functionality**: Allow users to set automated orders that execute when the asset's price reaches a specified upper limit, securing profits.
- **Limit Buy Fuctionality**: Allow users to set automated orders that execute when the limit price is reaches, securing profits.
- **Market Buy Fuctionality**: Allow users to set automated orders that will execute at market price

## Getting Started

Expand Down
43 changes: 35 additions & 8 deletions front_end_script/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ getSpotOrders(
);
```

### 6. createMarginOrder(position, collateral, leverage, borrow_asset, take_profit_price)
### 6. createMarginOrder(position, collateral, leverage, borrow_asset, take_profit_price, order_type, trigger_price)

This function allows you to create a margin order by sending a transaction to the CosmWasm contract.

Expand All @@ -163,6 +163,8 @@ This function allows you to create a margin order by sending a transaction to th
- `leverage` (String): The leverage for the margin order.
- `borrow_asset` (String): The asset to borrow for the margin order.
- `take_profit_price` (String): The price at which the order will take profit.
- `order_type` (String): The type of the order (e.g., "stop_loss", "limit_sell", "limit_buy").
- `trigger_price` ({`base_denom`:String, `quote_denom`:String, `rate` :String}): Price relates two assets exchange rate that the user should define

#### Usage

Expand All @@ -172,7 +174,9 @@ createMarginOrder(
"collateral",
"leverage_value",
"borrow_asset",
"take_profit_price"
"take_profit_price",
"order_type",
"trigger_price"
);
```

Expand All @@ -185,6 +189,8 @@ createMarginOrder(
"4.3",
"ueth",
"2.2"
"limit_buy",
{ base_denom: "ueth", quote_denom: "uusdc", rate: "2076.5" }
);
```

Expand All @@ -208,7 +214,7 @@ cancelMarginOrder("your_order_id_here");
cancelMarginOrder("1");
```

### 8. getMarginOrder(address,id)
### 8. getMarginOrder(id)

This function retrieves information about a specific margin order by querying a CosmWasm contract on the blockchain.

Expand All @@ -226,10 +232,31 @@ getMarginOrder("your_order_id_here");
#### Exemple

```js
getMarginOrder("255");
getMarginOrder("2");
```

### 9. getMarginPosition(address,id)

This function retrieves information about a specific margin order by querying a CosmWasm contract on the blockchain.

#### Parameters

- `address` (String): The address associated with the margin order.
- `order_id` (String): The unique identifier for the order you want to retrieve.

#### Usage

```javascript
getMarginPosition("your_address", "your_order_id_here");
```

#### Exemple

```js
getMarginPosition("elys1x5fehwug2vtkyn4vpunwkfn9zxkpxl8jg0lwuu", "255");
```

### 9. getMarginOrders(pagination)
### 10. getMarginPositions(pagination)

This function retrieves multiple margin orders by querying a CosmWasm contract on the blockchain.

Expand All @@ -240,16 +267,16 @@ This function retrieves multiple margin orders by querying a CosmWasm contract o
#### Usage

```javascript
getMarginOrders("pagination");
getMarginPositions("pagination");
```

#### Exemple

```js
getMarginOrders({ count_total: true, limit: 10, reverse: false, key: null });
getMarginPositions({ count_total: true, limit: 10, reverse: false, key: null });
```

### 10. SwapEstimationByDenom(amount, denom_in, denom_out)
### 11. SwapEstimationByDenom(amount, denom_in, denom_out)

This function retrieves an estimation of the value obtained by swapping one asset for another.

Expand Down
123 changes: 123 additions & 0 deletions front_end_script/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,126 @@ async function SwapEstimationByDenom(amount, denom_in, denom_out) {
);
console.log(`Result: `, result);
}

async function createMarginOrder(
position_type,
collateral,
leverage_value,
borrow_asset,
take_profit_price,
order_type,
trigger_price
) {
const gasPrice = GasPrice.fromString(GASPRICE);
const sender_wallet = await DirectSecp256k1HdWallet.fromMnemonic(
sender.mnemonic,
{ prefix: "elys" }
);
const sender_client = await SigningCosmWasmClient.connectWithSigner(
rpcEndpoint,
sender_wallet
);
const executeFee = calculateFee(300_000, gasPrice);
const msg = {
create_margin_order: {
position_type: position_type,
collateral: collateral,
leverage_value: leverage_value,
borrow_asset: borrow_asset,
take_profit_price: take_profit_price,
order_type: order_type,
trigger_price: trigger_price,
},
};

const create_margin_order_res = await sender_client.execute(
sender.address,
trade_shield_contract_addr,
msg,
executeFee,
"",
coins(amount_send, denom_send)
);
console.log("create_margin_order_res:", create_margin_order_res);
}

async function cancelMarginOrder(order_id) {
const gasPrice = GasPrice.fromString(GASPRICE);
const sender_wallet = await DirectSecp256k1HdWallet.fromMnemonic(
sender.mnemonic,
{ prefix: "elys" }
);
const sender_client = await SigningCosmWasmClient.connectWithSigner(
rpcEndpoint,
sender_wallet
);
const executeFee = calculateFee(300_000, gasPrice);
const msg = {
cancel_margin_order: {
order_id: order_id,
},
};

const create_margin_order_res = await sender_client.execute(
sender.address,
trade_shield_contract_addr,
msg,
executeFee,
""
);
console.log("create_margin_order_res:", create_margin_order_res);
}

async function getMarginOrder(order_id) {
const sender_wallet = await DirectSecp256k1HdWallet.fromMnemonic(
sender.mnemonic,
{ prefix: "elys" }
);
const sender_client = await SigningCosmWasmClient.connectWithSigner(
rpcEndpoint,
sender_wallet
);
const result = await sender_client.queryContractSmart(
trade_shield_contract_addr,
{
get_margin_order: { order_id: order_id },
}
);
console.log(`Result: `, result);
}

async function getMarginPosition(id, address) {
const sender_wallet = await DirectSecp256k1HdWallet.fromMnemonic(
sender.mnemonic,
{ prefix: "elys" }
);
const sender_client = await SigningCosmWasmClient.connectWithSigner(
rpcEndpoint,
sender_wallet
);
const result = await sender_client.queryContractSmart(
trade_shield_contract_addr,
{
get_margin_position: { id: id, address: address },
}
);
console.log(`Result: `, result);
}

async function getMarginPositions(pagination) {
const sender_wallet = await DirectSecp256k1HdWallet.fromMnemonic(
sender.mnemonic,
{ prefix: "elys" }
);
const sender_client = await SigningCosmWasmClient.connectWithSigner(
rpcEndpoint,
sender_wallet
);
const result = await sender_client.queryContractSmart(
trade_shield_contract_addr,
{
get_margin_positions: { pagination: pagination },
}
);
console.log(`Result: `, result);
}
36 changes: 13 additions & 23 deletions src/action/execute/cancel_margin_order.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
use cosmwasm_std::{to_json_binary, SubMsg};

use crate::msg::ReplyType;

use super::*;

pub fn cancel_margin_order(
Expand All @@ -16,34 +12,28 @@ pub fn cancel_margin_order(
None => return Err(ContractError::OrderNotFound { order_id }),
};

if order.creator == info.sender.to_string() {
if order.owner != info.sender.to_string() {
return Err(ContractError::Unauthorized {
sender: info.sender,
});
}

let meta_data = Some(to_json_binary(&order_id)?);

let cancel_msg = ElysMsg::margin_close_position(order.creator, order_id);

let mut reply_infos = REPLY_INFO.load(deps.storage)?;

let reply_info_id =
if let Some(reply_info) = reply_infos.iter().max_by_key(|reply_info| reply_info.id) {
reply_info.id + 1
} else {
0
};
let orders: Vec<MarginOrder> = orders
.iter()
.filter(|order| order.order_id != order_id)
.cloned()
.collect();

let reply_info = ReplyInfo {
id: reply_info_id,
reply_type: ReplyType::MarginClosePosition,
data: meta_data,
let refund_msg = BankMsg::Send {
to_address: order.owner,
amount: vec![order.collateral],
};

reply_infos.push(reply_info);
let resp = Response::new()
.add_message(CosmosMsg::Bank(refund_msg))
.add_attribute("order_id", order.order_id.to_string());

let resp = Response::new().add_submessage(SubMsg::reply_always(cancel_msg, reply_info_id));
MARGIN_ORDER.save(deps.storage, &orders)?;

Ok(resp)
}
4 changes: 2 additions & 2 deletions src/action/execute/cancel_spot_orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub fn cancel_spot_orders(
deps: DepsMut<ElysQuery>,
order_ids: Option<Vec<u64>>,
owner_address: String,
order_type: Option<SpotOrderType>,
order_type: Option<OrderType>,
) -> Result<Response<ElysMsg>, ContractError> {
if info.sender.as_str() != owner_address {
return Err(ContractError::Unauthorized {
Expand Down Expand Up @@ -95,7 +95,7 @@ fn filter_order_by_id(

fn filter_order_by_type(
orders: Vec<SpotOrder>,
order_type: Option<SpotOrderType>,
order_type: Option<OrderType>,
) -> Result<Vec<SpotOrder>, ContractError> {
let order_type = match order_type {
Some(order_type) => order_type,
Expand Down
Loading

0 comments on commit 9a62052

Please sign in to comment.