use crate::core::types::AccountType;
#[derive(Debug, Clone)]
pub struct PhemexUrls {
pub rest: &'static str,
pub ws: &'static str,
}
impl PhemexUrls {
pub const MAINNET: Self = Self {
rest: "https://api.phemex.com",
ws: "wss://ws.phemex.com/ws",
};
pub const VIP: Self = Self {
rest: "https://vapi.phemex.com",
ws: "wss://vapi.phemex.com/ws",
};
pub const TESTNET: Self = Self {
rest: "https://testnet-api.phemex.com",
ws: "wss://testnet.phemex.com/ws",
};
pub fn rest_url(&self, _account_type: AccountType) -> &str {
self.rest
}
pub fn ws_url(&self, _account_type: AccountType) -> &str {
self.ws
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PhemexEndpoint {
ServerTime,
Products,
SpotOrderbook,
SpotTrades,
SpotTicker24h,
SpotKlines,
ContractOrderbook,
ContractTrades,
ContractTicker24h,
ContractKlines,
FundingRateHistory,
SpotCreateOrder,
SpotAmendOrder,
SpotCancelOrder,
SpotCancelAllOrders,
SpotOpenOrders,
ContractCreateOrder,
ContractAmendOrder,
ContractCancelOrder,
ContractCancelAllOrders,
ContractOpenOrders,
ContractClosedOrders,
ContractGetOrder,
ContractGetTrades,
HedgedCreateOrder,
HedgedAmendOrder,
HedgedCancelOrder,
SpotWallets,
ContractAccount,
Transfer,
TransferHistory,
Positions,
SetLeverage,
SetRiskLimit,
AssignBalance,
DepositAddress,
Withdraw,
DepositList,
WithdrawList,
SubAccountCreate,
SubAccountList,
SubAccountTransfer,
TradeHistory,
OpenInterest,
}
impl PhemexEndpoint {
pub fn path(&self) -> &'static str {
match self {
Self::ServerTime => "/public/time",
Self::Products => "/public/products",
Self::SpotOrderbook => "/md/orderbook",
Self::SpotTrades => "/md/trade",
Self::SpotTicker24h => "/md/spot/ticker/24hr",
Self::SpotKlines => "/exchange/public/md/v2/kline",
Self::ContractOrderbook => "/md/orderbook",
Self::ContractTrades => "/md/trade",
Self::ContractTicker24h => "/md/ticker/24hr",
Self::ContractKlines => "/exchange/public/md/v2/kline",
Self::FundingRateHistory => "/api-data/public/data/funding-rate-history",
Self::SpotCreateOrder => "/spot/orders",
Self::SpotAmendOrder => "/spot/orders",
Self::SpotCancelOrder => "/spot/orders",
Self::SpotCancelAllOrders => "/spot/orders/all",
Self::SpotOpenOrders => "/spot/orders/active",
Self::ContractCreateOrder => "/orders",
Self::ContractAmendOrder => "/orders/replace",
Self::ContractCancelOrder => "/orders",
Self::ContractCancelAllOrders => "/orders/all",
Self::ContractOpenOrders => "/orders/activeList",
Self::ContractClosedOrders => "/exchange/order/list",
Self::ContractGetOrder => "/exchange/order",
Self::ContractGetTrades => "/exchange/order/trade",
Self::HedgedCreateOrder => "/g-orders/create",
Self::HedgedAmendOrder => "/g-orders/replace",
Self::HedgedCancelOrder => "/g-orders/cancel",
Self::SpotWallets => "/spot/wallets",
Self::ContractAccount => "/accounts/accountPositions",
Self::Transfer => "/assets/transfer",
Self::TransferHistory => "/assets/transfer",
Self::Positions => "/accounts/accountPositions",
Self::SetLeverage => "/positions/leverage",
Self::SetRiskLimit => "/positions/riskLimit",
Self::AssignBalance => "/positions/assign",
Self::DepositAddress => "/exchange/wallets/v2/depositAddress",
Self::Withdraw => "/exchange/wallets/createWithdraw",
Self::DepositList => "/exchange/wallets/depositList",
Self::WithdrawList => "/exchange/wallets/withdrawList",
Self::SubAccountCreate => "/phemex-user/users/children",
Self::SubAccountList => "/phemex-user/users/children",
Self::SubAccountTransfer => "/assets/universal-transfer",
Self::TradeHistory => "/exchange/order/v2/tradingList",
Self::OpenInterest => "/api-data/public/data/open-interest",
}
}
pub fn requires_auth(&self) -> bool {
match self {
Self::ServerTime
| Self::Products
| Self::SpotOrderbook
| Self::SpotTrades
| Self::SpotTicker24h
| Self::SpotKlines
| Self::ContractOrderbook
| Self::ContractTrades
| Self::ContractTicker24h
| Self::ContractKlines
| Self::FundingRateHistory
| Self::OpenInterest => false,
_ => true,
}
}
pub fn method(&self) -> &'static str {
match self {
Self::SpotCreateOrder
| Self::ContractCreateOrder
| Self::HedgedCreateOrder
| Self::Transfer
| Self::AssignBalance
| Self::Withdraw
| Self::SubAccountCreate
| Self::SubAccountTransfer => "POST",
Self::SpotAmendOrder
| Self::ContractAmendOrder
| Self::HedgedAmendOrder
| Self::SetLeverage
| Self::SetRiskLimit => "PUT",
Self::SpotCancelOrder
| Self::SpotCancelAllOrders
| Self::ContractCancelOrder
| Self::ContractCancelAllOrders
| Self::HedgedCancelOrder => "DELETE",
_ => "GET",
}
}
}
pub fn format_symbol(base: &str, quote: &str, account_type: AccountType) -> String {
match account_type {
AccountType::Spot => {
format!("s{}{}", base.to_uppercase(), quote.to_uppercase())
}
AccountType::FuturesCross | AccountType::FuturesIsolated => {
format!("{}{}", base.to_uppercase(), quote.to_uppercase())
}
AccountType::Margin => {
format!("s{}{}", base.to_uppercase(), quote.to_uppercase())
}
_ => {
format!("s{}{}", base.to_uppercase(), quote.to_uppercase())
}
}
}
pub fn map_kline_interval(interval: &str) -> u32 {
match interval {
"1m" => 60,
"5m" => 300,
"15m" => 900,
"30m" => 1800,
"1h" => 3600,
"4h" => 14400,
"1d" => 86400,
"1w" => 604800,
"1M" => 2592000,
"3M" => 7776000, "1y" => 31104000,
_ => 3600, }
}
pub fn unscale_price(price_ep: i64, price_scale: u8) -> f64 {
price_ep as f64 / 10_f64.powi(price_scale as i32)
}
pub fn scale_price(price: f64, price_scale: u8) -> i64 {
(price * 10_f64.powi(price_scale as i32)).round() as i64
}
pub fn unscale_value(value_ev: i64, value_scale: u8) -> f64 {
value_ev as f64 / 10_f64.powi(value_scale as i32)
}
pub fn scale_value(value: f64, value_scale: u8) -> i64 {
(value * 10_f64.powi(value_scale as i32)).round() as i64
}
pub fn _unscale_ratio(ratio_er: i64, ratio_scale: u8) -> f64 {
ratio_er as f64 / 10_f64.powi(ratio_scale as i32)
}
pub fn _scale_ratio(ratio: f64, ratio_scale: u8) -> i64 {
(ratio * 10_f64.powi(ratio_scale as i32)).round() as i64
}