utils.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use std::ops::{Div, Mul};
  2. use chrono::Utc;
  3. use rand::Rng;
  4. use rust_decimal::{Decimal};
  5. use tracing::error;
  6. use global::public_params;
  7. // 生成订单的id,可以根据交易所名字来
  8. pub fn generate_client_id(exchange_name_some: Option<String>) -> String {
  9. // 交易所名字获取
  10. let exchange_name = exchange_name_some.unwrap_or("".to_string());
  11. // 0-1000的随机数
  12. let rand_num = rand::thread_rng().gen_range(1..1000);
  13. // 随机时间戳
  14. let in_ms = Utc::now().timestamp_micros();
  15. let time_str = in_ms.to_string();
  16. let time_slice = &time_str[10..];
  17. let result = format!("{}{}{}", time_slice, rand_num, exchange_name);
  18. return result;
  19. }
  20. // 大小限定:将num限定在lower_limit和upper_limit范围内
  21. pub fn clip(num: Decimal, lower_limit: Decimal, upper_limit: Decimal) -> Decimal {
  22. if num.ge(&upper_limit) {
  23. return upper_limit;
  24. }
  25. if num.le(&lower_limit) {
  26. return lower_limit;
  27. }
  28. num
  29. }
  30. // 步长修复数量
  31. pub fn fix_amount(amount: Decimal, step_size: Decimal) -> Decimal {
  32. // 思路:做除法后取整,然后使用这个值乘以步长
  33. amount.div(step_size).floor().mul(step_size)
  34. }
  35. // 步长修复价格
  36. pub fn fix_price(amount: Decimal, tick_size: Decimal) -> Decimal {
  37. // 思路:做除法后四舍五入,然后使用这个值乘以步长
  38. amount.div(tick_size).round().mul(tick_size)
  39. }
  40. // 每秒请求频率
  41. pub fn get_limit_requests_num_per_second(exchange: String) -> i64 {
  42. if exchange.eq("kucoin_spot") {
  43. return public_params::KUCOIN_SPOT_LIMIT * public_params::RATIO;
  44. } else if exchange.eq("kucoin_usdt_swap") {
  45. return public_params::KUCOIN_USDT_SWAP_LIMIT * public_params::RATIO;
  46. } else if exchange.eq("binance_usdt_swap") {
  47. return public_params::BINANCE_USDT_SWAP_LIMIT * public_params::RATIO;
  48. } else if exchange.eq("binance_spot") {
  49. return public_params::BINANCE_SPOT_LIMIT * public_params::RATIO;
  50. } else if exchange.eq("gate_spot") {
  51. return public_params::GATE_SPOT_LIMIT * public_params::RATIO;
  52. } else if exchange.eq("gate_usdt_swap") {
  53. return public_params::GATE_USDT_SWAP_LIMIT * public_params::RATIO;
  54. } else if exchange.eq("coinex_usdt_swap") {
  55. return public_params::COINEX_USDT_SWAP_LIMIT * public_params::RATIO;
  56. } else if exchange.eq("coinex_spot") {
  57. return public_params::COINEX_SPOT_LIMIT * public_params::RATIO;
  58. } else if exchange.eq("okex_usdt_swap") {
  59. return public_params::OKEX_USDT_SWAP_LIMIT * public_params::RATIO;
  60. } else if exchange.eq("bitget_spot") {
  61. return public_params::BITGET_USDT_SPOT_LIMIT * public_params::RATIO;
  62. } else {
  63. error!("限频规则(ratio)未找到,请检查配置!");
  64. panic!("限频规则(ratio)未找到,请检查配置!");
  65. }
  66. }
  67. // 每秒下单请求频率
  68. pub fn get_limit_order_requests_num_per_second(exchange: String) -> i64 {
  69. if exchange.eq("kucoin_spot") {
  70. return public_params::KUCOIN_SPOT_LIMIT
  71. } else if exchange.eq("kucoin_usdt_swap") {
  72. return public_params::KUCOIN_USDT_SWAP_LIMIT
  73. } else if exchange.eq("binance_usdt_swap") {
  74. return public_params::BINANCE_USDT_SWAP_LIMIT
  75. } else if exchange.eq("binance_spot") {
  76. return public_params::BINANCE_SPOT_LIMIT
  77. } else if exchange.eq("gate_spot") {
  78. return public_params::GATE_SPOT_LIMIT
  79. } else if exchange.eq("gate_usdt_swap") {
  80. return public_params::GATE_USDT_SWAP_LIMIT
  81. } else if exchange.eq("coinex_usdt_swap") {
  82. return public_params::COINEX_USDT_SWAP_LIMIT
  83. } else if exchange.eq("coinex_spot") {
  84. return public_params::COINEX_SPOT_LIMIT
  85. } else if exchange.eq("okex_usdt_swap") {
  86. return public_params::OKEX_USDT_SWAP_LIMIT
  87. } else if exchange.eq("bitget_spot") {
  88. return public_params::BITGET_USDT_SPOT_LIMIT
  89. } else {
  90. error!("限频规则(limit)未找到,请检查配置!");
  91. panic!("限频规则(limit)未找到,请检查配置!");
  92. }
  93. }
  94. #[cfg(test)]
  95. mod tests {
  96. use chrono::Utc;
  97. use rust_decimal_macros::dec;
  98. use crate::utils::{clip, fix_amount, fix_price, generate_client_id};
  99. #[test]
  100. fn clip_test() {
  101. let num = dec!(11);
  102. let num2 = dec!(2);
  103. let lower_limit = dec!(3);
  104. let upper_limit = dec!(6);
  105. println!("mum: {}", clip(num, lower_limit, upper_limit));
  106. println!("mum2: {}", clip(num, lower_limit, upper_limit));
  107. }
  108. #[test]
  109. fn generate_client_id_test() {
  110. println!("{}", generate_client_id(None));
  111. println!("{}", generate_client_id(Some("binance".to_string())));
  112. }
  113. #[test]
  114. fn fix_amount_test() {
  115. println!("{}", fix_amount(dec!(0.9), dec!(0.04)));
  116. println!("{}", fix_amount(dec!(1.0), dec!(0.1)));
  117. println!("{}", fix_amount(dec!(0.9), dec!(0.05)));
  118. println!("{}", fix_amount(dec!(1), dec!(0.1)));
  119. println!("{}", fix_amount(dec!(0.01), dec!(0.05)));
  120. }
  121. #[test]
  122. fn fix_price_test() {
  123. println!("{}", fix_price(dec!(1), dec!(0.1)));
  124. println!("{}", fix_price(dec!(0.9), dec!(2.0)));
  125. println!("{}", fix_price(dec!(1.1), dec!(0.1)));
  126. println!("{}", fix_price(dec!(1.2), dec!(0.5)));
  127. println!("{}", fix_price(dec!(4999.99), dec!(0.5)));
  128. }
  129. #[test]
  130. fn utc_timestamp_test() {
  131. let now = Utc::now();
  132. println!("timestamp: {}", now.timestamp());
  133. println!("timestamp_millis: {}", now.timestamp_millis());
  134. println!("timestamp_micros: {}", now.timestamp_micros());
  135. println!("timestamp_nanos: {}", now.timestamp_nanos_opt().unwrap());
  136. }
  137. }