totalProfitCalc.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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, loss_out_1 } = data;
  119. const l = loss_out_1 ?? 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 {
  132. gold_side_a: goldA1,
  133. gold_side_b: goldB1,
  134. gold_side_m: goldM1,
  135. jc_index: jc_index_1
  136. } = calcExternalHandicap({ ...sol1, gold_side_jc, win_target });
  137. let loss_out_1 = 0, win_jc_1 = 0;
  138. switch (jc_index_1) {
  139. case 0:
  140. loss_out_1 = goldB1 + goldM1;
  141. win_jc_1 = gold_side_jc * (sol1.odds_side_a + 1);
  142. break;
  143. case 1:
  144. loss_out_1 = goldA1 + goldM1;
  145. win_jc_1 = gold_side_jc * (sol1.odds_side_b + 1);
  146. break;
  147. case 2:
  148. loss_out_1 = goldA1 + goldB1;
  149. win_jc_1 = gold_side_jc * (sol1.odds_side_m + 1)
  150. break;
  151. }
  152. const {
  153. gold_side_a: goldA2,
  154. gold_side_b: goldB2,
  155. gold_side_m: goldM2,
  156. jc_index: jc_index_2
  157. } = calcExternalHandicap({ ...sol2, gold_side_jc, win_target, loss_out_1 });
  158. let loss_out_2 = 0, win_jc_2 = 0;
  159. switch (jc_index_2) {
  160. case 0:
  161. loss_out_2 = gold_side_jc +goldB2 + goldM2 + loss_out_1;
  162. win_jc_2 = win_jc_1 * (sol2.odds_side_a + 1);
  163. break;
  164. case 1:
  165. loss_out_2 = gold_side_jc + goldA2 + goldM2 + loss_out_1;
  166. win_jc_2 = win_jc_1 * (sol2.odds_side_b + 1);
  167. break;
  168. case 2:
  169. loss_out_2 = gold_side_jc + goldA2 + goldB2 + loss_out_1;
  170. win_jc_2 = win_jc_1 * (sol2.odds_side_m + 1);
  171. break;
  172. }
  173. const win_jc = fixFloat(win_jc_2 - loss_out_2);
  174. return {
  175. goldA1,
  176. goldB1,
  177. goldM1,
  178. goldA2,
  179. goldB2,
  180. goldM2,
  181. win_jc,
  182. jc_index_1,
  183. jc_index_2,
  184. jc_base: gold_side_jc,
  185. }
  186. }
  187. const calcTotalProfit = (sol1, sol2, gold_side_jc) => {
  188. const winTarget1 = sol1.win_average;
  189. const winTarget2 = sol2.win_average;
  190. const winTarget = fixFloat(Math.min(winTarget1, winTarget2), 2);
  191. const win1 = calcGoldsWithWinTarget({ gold_side_jc, win_target: winTarget1, sol1, sol2 })?.win_jc;
  192. const win2 = calcGoldsWithWinTarget({ gold_side_jc, win_target: winTarget2, sol1, sol2 })?.win_jc;
  193. const winJc = fixFloat(Math.max(win1, win2), 2);
  194. const start = Math.max(winTarget, winJc);
  195. const end = Math.min(winTarget, winJc);
  196. const result = [];
  197. for (let i = start; i > end; i--) {
  198. const win_target = i;
  199. const goldsInfo = calcGoldsWithWinTarget({ gold_side_jc, win_target, sol1, sol2 });
  200. const win_diff = Math.abs(fixFloat(win_target - goldsInfo.win_jc));
  201. const lastResult = result.at(-1);
  202. if (!lastResult?.win_diff || win_diff < lastResult.win_diff) {
  203. result.push({ win_target: fixFloat(win_target), win_diff, ...goldsInfo });
  204. }
  205. else {
  206. break;
  207. }
  208. }
  209. return result.at(-1);
  210. }
  211. module.exports = calcTotalProfit;