Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions src/bin/order_and_modify_and_cancel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use ethers::signers::LocalWallet;
use log::info;

use hyperliquid_rust_sdk::{
BaseUrl, ClientCancelRequest, ClientLimit, ClientModifyRequest, ClientOrder, ClientOrderRequest, ExchangeClient, ExchangeDataStatus, ExchangeResponseStatus
};
use std::{thread::sleep, time::Duration};

#[tokio::main]
async fn main() {
env_logger::init();
// Key was randomly generated for testing and shouldn't be used with any real funds
let wallet: LocalWallet = "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
.parse()
.unwrap();

let exchange_client = ExchangeClient::new(None, wallet, Some(BaseUrl::Testnet), None, None)
.await
.unwrap();

let order = ClientOrderRequest {
asset: "ETH".to_string(),
is_buy: true,
reduce_only: false,
limit_px: 1800.0,
sz: 0.01,
cloid: None,
order_type: ClientOrder::Limit(ClientLimit {
tif: "Gtc".to_string(),
}),
};

let response = exchange_client.order(order, None).await.unwrap();
info!("Order placed: {response:?}");

let response = match response {
ExchangeResponseStatus::Ok(exchange_response) => exchange_response,
ExchangeResponseStatus::Err(e) => panic!("error with exchange response: {e}"),
};
let status = response.data.unwrap().statuses[0].clone();
let oid = match status {
ExchangeDataStatus::Filled(order) => order.oid,
ExchangeDataStatus::Resting(order) => order.oid,
_ => panic!("Error: {status:?}"),
};

sleep(Duration::from_secs(5));
// Shift the order by 1 dollar
let modify = ClientModifyRequest {
oid: oid.into(),
order:
ClientOrderRequest {
asset: "ETH".to_string(),
is_buy: true,
reduce_only: false,
limit_px: 1801.0,
sz: 0.01,
cloid: None,
order_type: ClientOrder::Limit(ClientLimit {
tif: "Gtc".to_string(),
}),
},
};

let modify_response = exchange_client.modify(modify, None).await.unwrap();
info!("Order potentially modified: {modify_response:?}");
// This response will return an error if order was filled (since you can't modify a filled order), otherwise it will modify the order
let modify_response = match modify_response {
ExchangeResponseStatus::Ok(exchange_response) => exchange_response,
ExchangeResponseStatus::Err(e) => panic!("error with exchange response: {e}"),
};
let status = modify_response.data.unwrap().statuses[0].clone();
let oid = match status {
ExchangeDataStatus::Filled(order) => order.oid,
ExchangeDataStatus::Resting(order) => order.oid,
_ => panic!("Error: {status:?}"),
};

// So you can see the order before it's cancelled
sleep(Duration::from_secs(10));

let cancel = ClientCancelRequest {
asset: "ETH".to_string(),
oid,
};

// This response will return an error if order was filled (since you can't cancel a filled order), otherwise it will cancel the order
let response = exchange_client.cancel(cancel, None).await.unwrap();
info!("Order potentially cancelled: {response:?}");
}
71 changes: 71 additions & 0 deletions src/bin/order_and_modify_and_cancel_cloid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use ethers::signers::LocalWallet;
use log::info;

use hyperliquid_rust_sdk::{
BaseUrl, ClientCancelRequestCloid, ClientLimit, ClientModifyId, ClientModifyRequest, ClientOrder, ClientOrderRequest, ExchangeClient
};
use std::{thread::sleep, time::Duration};
use uuid::Uuid;

#[tokio::main]
async fn main() {
env_logger::init();
// Key was randomly generated for testing and shouldn't be used with any real funds
let wallet: LocalWallet = "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
.parse()
.unwrap();

let exchange_client = ExchangeClient::new(None, wallet, Some(BaseUrl::Testnet), None, None)
.await
.unwrap();

// Order and Modify and Cancel with cloid
let cloid = Uuid::new_v4();
let order = ClientOrderRequest {
asset: "ETH".to_string(),
is_buy: true,
reduce_only: false,
limit_px: 1800.0,
sz: 0.01,
cloid: Some(cloid),
order_type: ClientOrder::Limit(ClientLimit {
tif: "Gtc".to_string(),
}),
};

let response = exchange_client.order(order, None).await.unwrap();
info!("Order placed: {response:?}");

sleep(Duration::from_secs(5));

// Shift the order by 1 dollar
let modify = ClientModifyRequest {
oid: ClientModifyId::Cloid(cloid),
order: ClientOrderRequest {
asset: "ETH".to_string(),
is_buy: true,
reduce_only: false,
limit_px: 1801.0,
sz: 0.01,
cloid: Some(cloid),
order_type: ClientOrder::Limit(ClientLimit {
tif: "Gtc".to_string(),
}),
},
};

let response = exchange_client.modify(modify, None).await.unwrap();
info!("Order potentially modified: {response:?}");

// So you can see the order before it's cancelled
sleep(Duration::from_secs(10));

let cancel = ClientCancelRequestCloid {
asset: "ETH".to_string(),
cloid,
};

// This response will return an error if order was filled (since you can't cancel a filled order), otherwise it will cancel the order
let response = exchange_client.cancel_by_cloid(cancel, None).await.unwrap();
info!("Order potentially cancelled: {response:?}");
}
2 changes: 1 addition & 1 deletion src/exchange/exchange_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ impl ExchangeClient {
let mut transformed_modifies = Vec::new();
for modify in modifies.into_iter() {
transformed_modifies.push(ModifyRequest {
oid: modify.oid,
oid: modify.oid.into(),
order: modify.order.convert(&self.coin_to_asset)?,
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/exchange/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub use builder::*;
pub use cancel::{ClientCancelRequest, ClientCancelRequestCloid};
pub use exchange_client::*;
pub use exchange_responses::*;
pub use modify::{ClientModifyRequest, ModifyRequest};
pub use modify::{ClientModifyRequest, ModifyRequest, ClientModifyId};
pub use order::{
ClientLimit, ClientOrder, ClientOrderRequest, ClientTrigger, MarketCloseParams,
MarketOrderParams, Order,
Expand Down
41 changes: 39 additions & 2 deletions src/exchange/modify.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,51 @@
use crate::helpers::uuid_to_hex_string;

use super::{order::OrderRequest, ClientOrderRequest};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Clone)]
pub enum ClientModifyId {
Oid(u64),
Cloid(Uuid),
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(untagged)]
pub enum SerializedClientId {
U64(u64),
Str(String),
}

impl From<u64> for ClientModifyId {
fn from(oid: u64) -> Self {
ClientModifyId::Oid(oid)
}
}

impl From<Uuid> for ClientModifyId {
fn from(cloid: Uuid) -> Self {
ClientModifyId::Cloid(cloid)
}
}

impl From<ClientModifyId> for SerializedClientId {
fn from(client_id: ClientModifyId) -> Self {
match client_id {
ClientModifyId::Oid(oid) => SerializedClientId::U64(oid),
ClientModifyId::Cloid(cloid) => SerializedClientId::Str(uuid_to_hex_string(cloid)),
}
}
}

#[derive(Debug)]
pub struct ClientModifyRequest {
pub oid: u64,
pub oid: ClientModifyId,
pub order: ClientOrderRequest,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ModifyRequest {
pub oid: u64,
pub oid: SerializedClientId,
pub order: OrderRequest,
}