eventSolutions.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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. inner_index,
  18. inner_rebate,
  19. gold_side_a: x,
  20. gold_side_b: y,
  21. gold_side_c: z,
  22. odds_side_a: a,
  23. odds_side_b: b,
  24. odds_side_c: c,
  25. rebate_side_a: A = 0,
  26. rebate_side_b: B = 0,
  27. rebate_side_c: C = 0,
  28. } = betInfo;
  29. /**
  30. * cross_type:
  31. * la: 全输
  32. * wa: 全赢
  33. * lh: 半输
  34. * wh: 半赢
  35. * dr: 和局
  36. * la_wh_wa, la_dr_wa, la_lh_wa, lh_dr_wa, lh_lh_wa, la_la_wa
  37. */
  38. let inner_rebate_value = 0;
  39. if (inner_index == 0) {
  40. inner_rebate_value = x * inner_rebate;
  41. }
  42. else if (inner_index == 1) {
  43. inner_rebate_value = y * inner_rebate;
  44. }
  45. else if (inner_index == 2) {
  46. inner_rebate_value = z * inner_rebate;
  47. }
  48. const k1 = a * (1 + A);
  49. const k2 = 1 - A;
  50. const k3 = b * (1 + B);
  51. const k4 = 1 - B;
  52. const k5 = c * (1 + C);
  53. const k6 = 1 - C;
  54. let win_side_a = 0, win_side_b = 0, win_side_c = 0;
  55. win_side_a = k1*x - k4*y - k6*z;
  56. win_side_b = k3*y - k2*x - k6*z;
  57. switch (cross_type) {
  58. case 'la_wh_wa': // 全输 半赢 全赢
  59. win_side_c = k5*z - k2*x + k3*y/2;
  60. break;
  61. case 'la_dr_wa': // 全输 和局 全赢
  62. win_side_c = k5*z - k2*x;
  63. break;
  64. case 'la_lh_wa': // 全输 半输 全赢
  65. win_side_c = k5*z - k2*x - k4*y/2;
  66. break;
  67. case 'lh_dr_wa': // 半输 和局 全赢
  68. win_side_c = k5*z - k2*x/2;
  69. break;
  70. case 'lh_lh_wa': // 半输 半输 全赢
  71. win_side_c = k5*z - k2*x/2 - k4*y/2;
  72. break;
  73. case 'la_la_wa': // 全输 全输 全赢
  74. win_side_c = k5*z - k2*x - k4*y;
  75. break;
  76. }
  77. win_side_a = fixFloat(win_side_a + inner_rebate_value);
  78. win_side_b = fixFloat(win_side_b + inner_rebate_value);
  79. win_side_c = fixFloat(win_side_c + inner_rebate_value);
  80. const win_average = fixFloat((win_side_a + win_side_b + win_side_c) / 3);
  81. return { win_side_a, win_side_b, win_side_c, win_average }
  82. }
  83. const triangleGoldCalc = (betInfo) => {
  84. const {
  85. cross_type, inner_index, inner_base,
  86. odds_side_a: a,
  87. odds_side_b: b,
  88. odds_side_c: c,
  89. rebate_side_a: A = 0,
  90. rebate_side_b: B = 0,
  91. rebate_side_c: C = 0,
  92. } = betInfo;
  93. if (!a || !b || !c) {
  94. return;
  95. }
  96. const k1 = a * (1 + A);
  97. const k2 = 1 - A;
  98. const k3 = b * (1 + B);
  99. const k4 = 1 - B;
  100. const k5 = c * (1 + C);
  101. const k6 = 1 - C;
  102. let x = inner_base;
  103. let y = (k1 + k2) * x / (k3 + k4);
  104. let z;
  105. switch (cross_type) {
  106. case 'la_wh_wa': // 全输 半赢 全赢
  107. z = k3 * y / 2 / (k5 + k6);
  108. break;
  109. case 'la_dr_wa': // 全输 和局 全赢
  110. z = k3 * y / (k5 + k6);
  111. break;
  112. case 'la_lh_wa': // 全输 半输 全赢
  113. z = (k3 + k4 / 2) * y / (k5 + k6);
  114. break;
  115. case 'lh_dr_wa': // 半输 和局 全赢
  116. z = (k3 * y - k2 * x / 2) / (k5 + k6);
  117. break;
  118. case 'lh_lh_wa': // 半输 半输 全赢
  119. z = ((k3 + k4/2) * y - k2 * x / 2) / (k5 + k6);
  120. break;
  121. case 'la_la_wa': // 全输 全输 全赢
  122. z = (k3 + k4) * y / (k5 + k6);
  123. break;
  124. default:
  125. z = 0;
  126. }
  127. if (inner_index == 1) {
  128. const scale = inner_base / y;
  129. x = x * scale;
  130. y = inner_base;
  131. z = z * scale;
  132. }
  133. else if (inner_index == 2) {
  134. const scale = inner_base / z;
  135. x = x * scale;
  136. y = y * scale;
  137. z = inner_base;
  138. }
  139. return {
  140. gold_side_a: fixFloat(x),
  141. gold_side_b: fixFloat(y),
  142. gold_side_c: fixFloat(z),
  143. };
  144. }
  145. const eventSolutions = (betInfo, showGolds=false) => {
  146. const goldsInfo = triangleGoldCalc(betInfo);
  147. if (!goldsInfo) {
  148. return;
  149. }
  150. const profitInfo = triangleProfitCalc({ ...betInfo, ...goldsInfo }, showGolds);
  151. const { gold_side_a, gold_side_b, gold_side_c } = goldsInfo;
  152. const { win_side_a, win_side_b, win_side_c, win_average } = profitInfo;
  153. const {
  154. cross_type, inner_index, inner_rebate, inner_base,
  155. odds_side_a, odds_side_b, odds_side_c,
  156. rebate_side_a,rebate_side_b, rebate_side_c,
  157. } = betInfo;
  158. // const win_profit = fixFloat(win_average / (gold_side_a + gold_side_b + gold_side_c) * 100);
  159. let result = {
  160. odds_side_a, odds_side_b, odds_side_c,
  161. rebate_side_a, rebate_side_b, rebate_side_c,
  162. win_average, cross_type,
  163. inner_index, inner_base, inner_rebate,
  164. }
  165. if (showGolds) {
  166. result = {
  167. ...result,
  168. gold_side_a, gold_side_b, gold_side_c,
  169. // win_side_a, win_side_b, win_side_c,
  170. }
  171. }
  172. return result;
  173. }
  174. module.exports = { eventSolutions };