as_libs.rs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. use crate::exchange_middle_ware::{Depth, Record};
  2. // 获取买一卖一价差(spread)、中间价
  3. pub fn get_spread(depth: &Depth) -> (f64, f64, f64, f64) {
  4. // 定义一个乘法系数,主要是防止f64精度丢失问题
  5. let mul = 1e6;
  6. let ask = depth.asks[0].price;
  7. let bid = depth.bids[0].price;
  8. let spread = (ask * mul - bid * mul) / mul;
  9. let price_diff = (ask * mul + bid * mul) / (2f64 * mul);
  10. return (spread, price_diff, ask, bid);
  11. }
  12. // 计算最近N根K线的收盘价的标准差
  13. pub fn std_n_by_records(records: &Vec<Record>, n: usize) -> f64 {
  14. let close_list: Vec<_> = records.iter().rev().take(n).map(|r| r.close).collect();
  15. let count = close_list.len();
  16. let mean = close_list.iter().sum::<f64>() / (count as f64);
  17. let variance = close_list.iter().map(|&value| {
  18. let diff = mean - value;
  19. diff * diff
  20. }).sum::<f64>() / count as f64;
  21. return variance.sqrt();
  22. }
  23. // 计算gamma值
  24. // max_spread: 最大价差
  25. // q: 库存价值
  26. // std: 标准差
  27. pub fn calc_gamma(max_spread: f64, q: f64, std: f64) -> f64 {
  28. return max_spread / ((2f64) * q * std.powf(2f64));
  29. }
  30. // 计算价格偏差范围(加权平均值)
  31. pub fn calc_deviation_range(max_ira: f64, spread_list: &Vec<f64>, ira: f64) -> f64 {
  32. let max_spread = spread_list.iter().cloned().fold(f64::NAN, f64::max);
  33. let min_spread = spread_list.iter().cloned().fold(f64::NAN, f64::min);
  34. return (max_ira - ira) * max_spread + ira * min_spread;
  35. }
  36. // 计算Reservation price(预定价格)
  37. // s = midprice = 当前市场中间价
  38. // q = 基础资产库存中的资产数量(多头/空头头寸可为正值/负值)
  39. // (gamma * i) = γ = 库存风险规避参数
  40. // σ = std = 市场波动率
  41. // i = 当前第几个ira
  42. // 1 = T-t = 关闭时间,即测量周期结束时(方便地归一化为 1),当前时间(T 归一化 = 1,因此 t 是时间分数)
  43. pub fn calc_rp(mid_price: f64, quantity: f64, ira: f64, gamma: f64, std: f64) -> f64 {
  44. return mid_price - quantity * (gamma * ira) * 1f64 * std.powf(2f64);
  45. }
  46. pub fn calc_dk(deviation_range: f64, gamma: f64, std: f64, ira: f64) -> f64 {
  47. return (deviation_range * (gamma * ira) - std.powf(2f64) * (gamma * ira).powf(2f64)) / 2f64;
  48. }
  49. pub fn calc_kappa(gamma: f64, dk: f64, deviation_range: f64, ira: f64) -> f64 {
  50. return ((gamma * ira) / ( std::f64::consts::E.powf(dk) - 1f64)) / deviation_range;
  51. }
  52. // 核心公式二 Optimal bid & ask spread 最佳买卖价差
  53. // δa、δb = cal_theta = 买入/卖出价差,对称 → δa=δb
  54. // (gamma * i) = γ = 库存风险规避参数
  55. // σ = std = 市场波动率
  56. pub fn calc_theta(gamma: f64, std: f64, kappa: f64, ira: f64) -> f64 {
  57. let a = (gamma * ira) * std.powf(2f64);
  58. let b = 2f64 / (gamma * ira) * (1f64 + (gamma * ira) / kappa).ln();
  59. return (a + b) / 2f64;
  60. }
  61. // 给定ira、当前库存、最大库存、买入价格、下单数量小数位数,计算合理下单数量
  62. // 下单数量要与ira(风险系数)、quantity(库存)成反比
  63. pub fn calc_order_amount(ira_max: f64, ira: f64, quantity: f64, quantity_max: f64, bid_price: f64, amount_decimal_places: usize) -> f64 {
  64. let eta = (ira / ira_max) / (1.0 + quantity * 2.0);
  65. let order_value_base = (-quantity * eta).abs();
  66. let order_value = (quantity_max * 1.0/50.0) * (1.0 - order_value_base / quantity_max);
  67. let order_amount = order_value / bid_price;
  68. return truncate_decimal_places(order_amount, amount_decimal_places);
  69. }
  70. // 保留指定位数的小数
  71. pub fn truncate_decimal_places(num: f64, decimal_places: usize) -> f64 {
  72. let multiplier = 10f64.powi(decimal_places as i32);
  73. (num * multiplier).trunc() / multiplier
  74. }
  75. // 单元测试集
  76. #[cfg(test)]
  77. mod tests {
  78. // use crate::exchange_middle_ware::{get_binance_depth, get_binance_klines};
  79. use super::*;
  80. // #[tokio::test]
  81. // async fn test_get_spread() {
  82. // let depth = get_binance_depth(&"BTC_USDT".to_string(), 100i32).await;
  83. // let ask = depth.asks[0].price;
  84. // let bid = depth.bids[0].price;
  85. //
  86. // println!("ask={}, bid={}", ask, bid);
  87. // println!("{:?}", get_spread(&depth))
  88. // }
  89. #[test]
  90. fn test_std_n_by_records() {
  91. let records = vec![
  92. Record{
  93. time: 1567736576000,
  94. open: 1000.0,
  95. high: 1500.0,
  96. low: 900.9,
  97. close: 1200.9,
  98. volume: 1000000.0,
  99. }, Record{
  100. time: 1567736576000,
  101. open: 1000.0,
  102. high: 1500.0,
  103. low: 900.9,
  104. close: 1219.9,
  105. volume: 1000000.0,
  106. }, Record{
  107. time: 1567736576000,
  108. open: 1000.0,
  109. high: 1500.0,
  110. low: 900.9,
  111. close: 1218.1,
  112. volume: 1000000.0,
  113. }];
  114. println!("{}", std_n_by_records(&records, 3))
  115. }
  116. #[test]
  117. fn test_calc_gamma() {
  118. println!("{}", calc_gamma(0.1, 49.0, 23.0))
  119. }
  120. #[test]
  121. fn test_calc_deviation_range() {
  122. let max_ira = 10.0;
  123. let ira = 0.1;
  124. let spread_list = vec![
  125. 0.1,
  126. 0.2,
  127. 0.15,
  128. 0.1
  129. ];
  130. println!("{}", calc_deviation_range(max_ira, &spread_list, ira));
  131. }
  132. #[test]
  133. fn test_calc_rp() {
  134. let mid_price = 1992.01;
  135. let quantity = 49.0;
  136. let ira = 0.1;
  137. let gamma = 1.9289379267775165e-06;
  138. let std = 23.0;
  139. println!("{}", calc_rp(mid_price, quantity, ira, gamma, std));
  140. }
  141. #[test]
  142. fn test_calc_dk() {
  143. let deviation_range = 1.9900000000000002;
  144. let ira = 0.1;
  145. let gamma = 1.9289379267775165e-06;
  146. let std = 23.0;
  147. println!("{}", calc_dk(deviation_range, gamma, std, ira));
  148. }
  149. #[test]
  150. fn test_calc_kappa() {
  151. let deviation_range = 1.9900000000000002;
  152. let ira = 0.1;
  153. let gamma = 1.9289379267775165e-06;
  154. let dk = 0.00000019191948219432835;
  155. println!("{}", calc_kappa(gamma, dk, deviation_range, ira));
  156. }
  157. #[test]
  158. fn test_calc_order_amount() {
  159. let quantity = 10.0;
  160. let quantity_max = 20.0;
  161. let bid_price = 28684.0;
  162. let amount_decimal_places = 8;
  163. let start = 0.1;
  164. let end = 10.0;
  165. let step = 0.1;
  166. let mut ira = start;
  167. while ira <= end {
  168. println!("ira={}, order_amount={}", ira, calc_order_amount(end, ira, quantity, quantity_max, bid_price, amount_decimal_places));
  169. ira += step;
  170. }
  171. }
  172. }