eventsMatch.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. const Logs = require('../libs/logs');
  2. const eventsCombination = require('./trangleCalc');
  3. const Request = {
  4. callbacks: {},
  5. count: 0,
  6. }
  7. const WIN_STEP = 15;
  8. const SOL_FREEZ_TIME = 1000 * 30;
  9. const GLOBAL_DATA = {
  10. relationLength: 0,
  11. solutions: {},
  12. };
  13. const getDataFromParent = (type, callback) => {
  14. const id = ++Request.count;
  15. Request.callbacks[id] = callback;
  16. process.send({ method: 'get', id, type });
  17. }
  18. const postDataToParent = (type, data) => {
  19. process.send({ method: 'post', type, data });
  20. }
  21. process.on('message', (message) => {
  22. const { callbacks } = Request;
  23. const { method, id, type, data } = message;
  24. if (method == 'get' && id) {
  25. let responseData = null;
  26. // if (data == 'getSolution') {
  27. // responseData = Solution.get();
  28. // }
  29. process.send({ type: 'response', id, data: responseData });
  30. }
  31. else if (type == 'response' && id && callbacks[id]) {
  32. callbacks[id](data);
  33. delete callbacks[id];
  34. }
  35. });
  36. const getGamesRelation = () => {
  37. return new Promise(resolve => {
  38. getDataFromParent('getGamesRelation', (relations) => {
  39. resolve(relations);
  40. });
  41. });
  42. }
  43. const getSolutionHistory = () => {
  44. return new Promise(resolve => {
  45. getDataFromParent('getSolutionHistory', (solutions) => {
  46. resolve(solutions);
  47. });
  48. });
  49. }
  50. const setSolution = (solutions) => {
  51. postDataToParent('setSolution', solutions);
  52. }
  53. const extractOdds = ({ evtime, events, sptime, special }) => {
  54. const expireTime = Date.now() - 15000;
  55. let odds = {};
  56. if (evtime > expireTime) {
  57. odds = { ...odds, ...events };
  58. }
  59. if (sptime > expireTime) {
  60. odds = { ...odds, ...special };
  61. }
  62. return odds;
  63. }
  64. // const getOptimalOdds = (oddsMap) => {
  65. // const oddsInfo = {};
  66. // Object.keys(oddsMap).forEach(platform => {
  67. // const odds = oddsMap[platform];
  68. // Object.keys(odds).forEach(ior => {
  69. // const oddsValue = odds[ior];
  70. // if (!oddsInfo[ior] || oddsInfo[ior]?.v < oddsValue) {
  71. // oddsInfo[ior] = {
  72. // p: platform,
  73. // v: oddsValue
  74. // }
  75. // }
  76. // });
  77. // });
  78. // return oddsInfo;
  79. // }
  80. const eventMatch = () => {
  81. getGamesRelation()
  82. .then(relations => {
  83. const nowTime = Date.now();
  84. relations = relations.filter(relaiton => {
  85. const expire = Object.values(relaiton.rel).find(event => event.timestamp <= nowTime);
  86. if (expire) {
  87. return false;
  88. }
  89. return true;
  90. });
  91. const relationLength = relations.length;
  92. if (!relationLength) {
  93. if (GLOBAL_DATA.relationLength) {
  94. GLOBAL_DATA.relationLength = 0;
  95. Logs.out('relation list is empty');
  96. }
  97. return [];
  98. }
  99. GLOBAL_DATA.relationLength = relationLength;
  100. const passableEvents = relations.map(({ id, rel }) => {
  101. const eventsMap = {};
  102. const oddsMap = {};
  103. Object.keys(rel).forEach(platform => {
  104. const { leagueName, teamHomeName, teamAwayName, timestamp, evtime, events, sptime, special } = rel[platform];
  105. if (!events && !special) {
  106. return;
  107. }
  108. if (!eventsMap.info) {
  109. eventsMap.info = { leagueName, teamHomeName, teamAwayName, id, timestamp };
  110. }
  111. const odds = extractOdds({ evtime, events, sptime, special });
  112. Object.keys(odds).forEach(ior => {
  113. if (!oddsMap[ior]) {
  114. oddsMap[ior] = {};
  115. }
  116. oddsMap[ior][platform] = odds[ior];
  117. });
  118. });
  119. eventsMap.odds = oddsMap;
  120. return eventsMap;
  121. });
  122. const solutions = eventsCombination(passableEvents);
  123. if (solutions?.length) {
  124. const solutionsHistory = GLOBAL_DATA.solutions;
  125. solutions.forEach(item => {
  126. const { sid, timestamp, sol: { win_average } } = item;
  127. if (!solutionsHistory[sid]) {
  128. solutionsHistory[sid] = item;
  129. Logs.out(JSON.stringify(item, null, 2));
  130. return;
  131. }
  132. const historyTimestamp = solutionsHistory[sid].timestamp;
  133. const historyWinAverage = solutionsHistory[sid].sol.win_average;
  134. if (win_average - historyWinAverage > WIN_STEP && timestamp - historyTimestamp > SOL_FREEZ_TIME) {
  135. solutionsHistory[sid] = item;
  136. Logs.out(JSON.stringify(item, null, 2));
  137. }
  138. });
  139. }
  140. })
  141. .finally(() => {
  142. setTimeout(() => {
  143. eventMatch();
  144. }, 2000);
  145. });
  146. };
  147. const solutionsCleanup = () => {
  148. const solutionsHistory = GLOBAL_DATA.solutions;
  149. Object.keys(solutionsHistory).forEach(sid => {
  150. const solution = solutionsHistory[sid];
  151. const eventTime = solution.info.timestamp;
  152. const nowTime = Date.now();
  153. if (nowTime > eventTime) {
  154. delete solutionsHistory[sid];
  155. Logs.out('solution history cleanup', sid);
  156. }
  157. });
  158. }
  159. setInterval(() => {
  160. solutionsCleanup();
  161. }, 1000*30);
  162. eventMatch();