totalProfitCalc.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. const fixFloat = (number, x = 2) => {
  2. return parseFloat(number.toFixed(x));
  3. }
  4. const HandicapCalc = function (data) {
  5. const { i, g, a, b, c, w, l } = data;
  6. const t = w + l;
  7. const calcTemplate = (handlers) => {
  8. if (i > 2 || i < 0) {
  9. return {};
  10. }
  11. if (i === 2) {
  12. const z = g;
  13. const x = (b + 1) * (t + z) / (a * b - 1);
  14. const y = (a + 1) * (t + z) / (a * b - 1);
  15. return { x, y, z };
  16. };
  17. return handlers[i]?.() ?? {};
  18. };
  19. return {
  20. la_wh_wa() {
  21. return calcTemplate([
  22. () => {
  23. const x = g;
  24. const z = (t + x) / (2 * c + 1);
  25. const y = (c + 1) * (t + x) / (c + 0.5) / b;
  26. return { x, y, z };
  27. },
  28. () => {
  29. const y = g;
  30. const z = ((a + 1) * t + (1 - a * b / 2) * y) / (a * c - 1);
  31. const x = ((c + 1) * t + (c - b / 2) * y) / (a * c - 1);
  32. return { x, y, z };
  33. }
  34. ]);
  35. },
  36. la_dr_wa() {
  37. return calcTemplate([
  38. () => {
  39. const x = g;
  40. const z = (t + x) / c;
  41. const y = (t + x + z) / b;
  42. return { x, y, z };
  43. },
  44. () => {
  45. const y = g;
  46. const z = ((a + 1) * t + y) / (a * c - 1);
  47. const x = ((c + 1) * t + c * y) / (a * c - 1);
  48. return { x, y, z };
  49. }
  50. ]);
  51. },
  52. la_lh_wa() {
  53. return calcTemplate([
  54. () => {
  55. const x = g;
  56. const z = (2 * b + 1) * (t + x) / (2 * b * c - 1);
  57. const y = (c + 1) * (t + x) / (b * c - 0.5);
  58. return { x, y, z };
  59. },
  60. () => {
  61. const y = g;
  62. const z = ((a + 1) * t + (a / 2 + 1) * y) / (a * c - 1);
  63. const x = ((c + 1) * t + (c + 0.5) * y) / (a * c - 1);
  64. return { x, y, z };
  65. }
  66. ]);
  67. },
  68. lh_dr_wa() {
  69. return calcTemplate([
  70. () => {
  71. const x = g;
  72. const z = (t + x / 2) / c;
  73. const y = (t + x + z) / b;
  74. return { x, y, z };
  75. },
  76. () => {
  77. const y = g;
  78. const z = ((2 * a + 1) * t + y) / (2 * a * c - 1);
  79. const x = ((c + 1) * t + c * y) / (a * c - 0.5);
  80. return { x, y, z };
  81. }
  82. ]);
  83. },
  84. lh_lh_wa() {
  85. return calcTemplate([
  86. () => {
  87. const x = g;
  88. const z = ((2 * b + 1) * t + (b + 1) * x) / (2 * b * c - 1);
  89. const y = ((c + 1) * t + (c + 0.5) * x) / (b * c - 0.5);
  90. },
  91. () => {
  92. const y = g;
  93. const z = ((2 * a + 1) * t + (a + 1) * y) / (2 * a * c - 1);
  94. const x = ((c + 1) * t + (c + 0.5) * y) / (a * c - 0.5);
  95. return { x, y, z };
  96. }
  97. ]);
  98. },
  99. la_la_wa() {
  100. return calcTemplate([
  101. () => {
  102. const x = g;
  103. const z = (b + 1) * (t + x) / (b * c - 1);
  104. const y = (c + 1) * (t + x) / (b * c - 1);
  105. return { x, y, z };
  106. },
  107. () => {
  108. const y = g;
  109. const z = (a + 1) * (t + y) / (a * c - 1);
  110. const x = (c + 1) * (t + y) / (a * c - 1);
  111. return { x, y, z };
  112. }
  113. ]);
  114. }
  115. }
  116. }
  117. const calcExternalHandicap = (data) => {
  118. const { gold_side_jc: g, odds_side_a: a, odds_side_b: b, odds_side_m: c, jc_index: i, cross_type: t, win_target: w, pre_loss } = data;
  119. const l = pre_loss ?? 0;
  120. const calc = new HandicapCalc({ i, g, a, b, c, w, l });
  121. const { x, y, z } = calc?.[t]() ?? {};
  122. return {
  123. gold_side_a: fixFloat(x),
  124. gold_side_b: fixFloat(y),
  125. gold_side_m: fixFloat(z),
  126. jc_index: i,
  127. }
  128. }
  129. const calcGoldsWithWinTarget = (data) => {
  130. const { gold_side_jc, win_target, sol1, sol2 } = data;
  131. const preInfo = calcExternalHandicap({ ...sol1, gold_side_jc, win_target });
  132. const { gold_side_a: goldA1, gold_side_b: goldB1, gold_side_m: goldM1, jc_index: jc_index_1 } = preInfo;
  133. let pre_loss = 0;
  134. switch (jc_index_1) {
  135. case 0:
  136. pre_loss = goldB1 + goldM1;
  137. break;
  138. case 1:
  139. pre_loss = goldA1 + goldM1;
  140. break;
  141. case 2:
  142. pre_loss = goldA1 + goldB1;
  143. break;
  144. }
  145. const nextInfo = calcExternalHandicap({ ...sol2, gold_side_jc, win_target, pre_loss });
  146. const { gold_side_a: goldA2, gold_side_b: goldB2, gold_side_m: goldM2, jc_index: jc_index_2 } = nextInfo;
  147. const jcWin = fixFloat(10000 * (sol1.odds_side_a + 1) * (sol2.odds_side_a + 1) - goldB1 - goldM1 - goldB2 - goldM2 - 10000);
  148. return {
  149. jcWin,
  150. goldA1,
  151. goldB1,
  152. goldM1,
  153. goldA2,
  154. goldB2,
  155. goldM2,
  156. jc_index_1,
  157. jc_index_2,
  158. }
  159. }
  160. const calcTotalProfit = (sol1, sol2, gold_side_jc) => {
  161. const winTarget1 = sol1.win_average;
  162. const winTarget2 = sol2.win_average;
  163. const winTarget = fixFloat(Math.min(winTarget1, winTarget2), 2);
  164. const jcWin1 = calcGoldsWithWinTarget({ gold_side_jc, win_target: winTarget1, sol1, sol2 })?.jcWin;
  165. const jcWin2 = calcGoldsWithWinTarget({ gold_side_jc, win_target: winTarget2, sol1, sol2 })?.jcWin;
  166. const jcWin = fixFloat(Math.max(jcWin1, jcWin2), 2);
  167. const start = Math.max(winTarget, jcWin);
  168. const end = Math.min(winTarget, jcWin);
  169. const result = [];
  170. for (let i = start; i > end; i--) {
  171. const win_target = i;
  172. const goldsInfo = calcGoldsWithWinTarget({ gold_side_jc, win_target, sol1, sol2 });
  173. const win_diff = Math.abs(fixFloat(win_target - goldsInfo.jcWin));
  174. const lastResult = result.at(-1);
  175. if (!lastResult?.win_diff || win_diff < lastResult.win_diff) {
  176. result.push({ win_target: fixFloat(win_target), win_diff, ...goldsInfo });
  177. }
  178. else {
  179. break;
  180. }
  181. }
  182. return result.at(-1);
  183. }
  184. module.exports = calcTotalProfit;