eventSolutions.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. const Logs = require('../libs/logs');
  2. /**
  3. * 精确浮点数字
  4. * @param {number} number
  5. * @param {number} x
  6. * @returns {number}
  7. */
  8. const fixFloat = (number, x=2) => {
  9. return parseFloat(number.toFixed(x));
  10. }
  11. /**
  12. * 计算盈利
  13. */
  14. const triangleProfitCalc = (betInfo) => {
  15. const {
  16. cross_type,
  17. gold_side_a: x,
  18. gold_side_b: y,
  19. gold_side_c: z,
  20. odds_side_a: a,
  21. odds_side_b: b,
  22. odds_side_c: c,
  23. rebate_side_a: A = 0,
  24. rebate_side_b: B = 0,
  25. rebate_side_c: C = 0,
  26. rebate_type_side_a: TA = 0,
  27. rebate_type_side_b: TB = 0,
  28. rebate_type_side_c: TC = 0,
  29. } = betInfo;
  30. /**
  31. * cross_type:
  32. * la: 全输
  33. * wa: 全赢
  34. * lh: 半输
  35. * wh: 半赢
  36. * dr: 和局
  37. * la_wh_wa, la_dr_wa, la_lh_wa, lh_dr_wa, lh_lh_wa, la_la_wa
  38. */
  39. // let inner_rebate_value = 0;
  40. // if (inner_index == 0) {
  41. // inner_rebate_value = x * inner_rebate;
  42. // }
  43. // else if (inner_index == 1) {
  44. // inner_rebate_value = y * inner_rebate;
  45. // }
  46. // else if (inner_index == 2) {
  47. // inner_rebate_value = z * inner_rebate;
  48. // }
  49. const k1 = TA == 1 ? a + A : a * (1 + A);
  50. const k2 = 1 - A;
  51. const k3 = TB == 1 ? b + B : b * (1 + B);
  52. const k4 = 1 - B;
  53. const k5 = TC == 1 ? c + C : c * (1 + C);
  54. const k6 = 1 - C;
  55. let win_side_a = 0, win_side_b = 0, win_side_c = 0;
  56. win_side_a = k1*x - k4*y - k6*z;
  57. win_side_b = k3*y - k2*x - k6*z;
  58. switch (cross_type) {
  59. case 'la_wh_wa': // 全输 半赢 全赢
  60. win_side_c = k5*z - k2*x + k3*y/2;
  61. break;
  62. case 'la_dr_wa': // 全输 和局 全赢
  63. win_side_c = k5*z - k2*x;
  64. break;
  65. case 'la_lh_wa': // 全输 半输 全赢
  66. win_side_c = k5*z - k2*x - k4*y/2;
  67. break;
  68. case 'lh_dr_wa': // 半输 和局 全赢
  69. win_side_c = k5*z - k2*x/2;
  70. break;
  71. case 'lh_lh_wa': // 半输 半输 全赢
  72. win_side_c = k5*z - k2*x/2 - k4*y/2;
  73. break;
  74. case 'la_la_wa': // 全输 全输 全赢
  75. win_side_c = k5*z - k2*x - k4*y;
  76. break;
  77. case 'la_wa_rv': // 两盘口输赢
  78. win_side_c = 0;
  79. break;
  80. default:
  81. win_side_c = 0;
  82. }
  83. win_side_a = fixFloat(win_side_a);
  84. win_side_b = fixFloat(win_side_b);
  85. win_side_c = fixFloat(win_side_c);
  86. let win_average = 0;
  87. if (cross_type == 'la_wa_rv') {
  88. win_side_c = 0;
  89. win_average = fixFloat((win_side_a + win_side_b) / 2);
  90. }
  91. else {
  92. win_average = fixFloat((win_side_a + win_side_b + win_side_c) / 3);
  93. }
  94. return { win_side_a, win_side_b, win_side_c, win_average }
  95. }
  96. const triangleGoldCalc = (betInfo) => {
  97. const {
  98. cross_type, inner_index, inner_base,
  99. odds_side_a: a,
  100. odds_side_b: b,
  101. odds_side_c: c,
  102. rebate_side_a: A = 0,
  103. rebate_side_b: B = 0,
  104. rebate_side_c: C = 0,
  105. rebate_type_side_a: TA = 0,
  106. rebate_type_side_b: TB = 0,
  107. rebate_type_side_c: TC = 0,
  108. } = betInfo;
  109. if (typeof a !== 'number' || typeof b !== 'number' || typeof c !== 'number') {
  110. return;
  111. }
  112. const k1 = TA == 1 ? a + A : a * (1 + A);
  113. const k2 = 1 - A;
  114. const k3 = TB == 1 ? b + B : b * (1 + B);
  115. const k4 = 1 - B;
  116. const k5 = TC == 1 ? c + C : c * (1 + C);
  117. const k6 = 1 - C;
  118. let x = inner_base;
  119. let y = (k1 + k2) * x / (k3 + k4);
  120. let z;
  121. switch (cross_type) {
  122. case 'la_wh_wa': // 全输 半赢 全赢
  123. z = k3 * y / 2 / (k5 + k6);
  124. break;
  125. case 'la_dr_wa': // 全输 和局 全赢
  126. z = k3 * y / (k5 + k6);
  127. break;
  128. case 'la_lh_wa': // 全输 半输 全赢
  129. z = (k3 + k4 / 2) * y / (k5 + k6);
  130. break;
  131. case 'lh_dr_wa': // 半输 和局 全赢
  132. z = (k3 * y - k2 * x / 2) / (k5 + k6);
  133. break;
  134. case 'lh_lh_wa': // 半输 半输 全赢
  135. z = ((k3 + k4/2) * y - k2 * x / 2) / (k5 + k6);
  136. break;
  137. case 'la_la_wa': // 全输 全输 全赢
  138. z = (k3 + k4) * y / (k5 + k6);
  139. break;
  140. case 'la_wa_rv': // 两盘口输赢
  141. z = 0;
  142. break;
  143. default:
  144. z = 0;
  145. }
  146. if (inner_index == 1) {
  147. const scale = inner_base / y;
  148. x = x * scale;
  149. y = inner_base;
  150. z = z * scale;
  151. }
  152. else if (inner_index == 2) {
  153. const scale = inner_base / z;
  154. x = x * scale;
  155. y = y * scale;
  156. z = inner_base;
  157. }
  158. if (x < 0 || y < 0 || z < 0) {
  159. return;
  160. }
  161. return {
  162. gold_side_a: fixFloat(x),
  163. gold_side_b: fixFloat(y),
  164. gold_side_c: fixFloat(z),
  165. };
  166. }
  167. const eventSolutions = (betInfo, showGolds=false) => {
  168. const goldsInfo = triangleGoldCalc(betInfo);
  169. if (!goldsInfo) {
  170. return;
  171. }
  172. const profitInfo = triangleProfitCalc({ ...betInfo, ...goldsInfo }, showGolds);
  173. const { gold_side_a, gold_side_b, gold_side_c } = goldsInfo;
  174. const { win_side_a, win_side_b, win_side_c, win_average } = profitInfo;
  175. const {
  176. cross_type, inner_index, inner_base,
  177. odds_side_a, odds_side_b, odds_side_c,
  178. rebate_side_a, rebate_side_b, rebate_side_c,
  179. rebate_type_side_a, rebate_type_side_b, rebate_type_side_c,
  180. } = betInfo;
  181. const win_average_rate = fixFloat(win_average / inner_base * 100);
  182. const win_profit_rate = fixFloat(win_average / (gold_side_a + gold_side_b + gold_side_c) * 100);
  183. let result = {
  184. odds_side_a, odds_side_b, odds_side_c,
  185. rebate_side_a, rebate_side_b, rebate_side_c,
  186. rebate_type_side_a, rebate_type_side_b, rebate_type_side_c,
  187. win_average, win_average_rate, win_profit_rate, cross_type,
  188. inner_index, inner_base,
  189. }
  190. if (showGolds) {
  191. result = {
  192. ...result,
  193. gold_side_a, gold_side_b, gold_side_c,
  194. win_side_a, win_side_b, win_side_c,
  195. }
  196. }
  197. return result;
  198. }
  199. module.exports = { eventSolutions };