eventsMatch.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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 SETTING = {
  10. innerDefaultAmount: 10000,
  11. minProfitAmount: 0,
  12. innerRebateRatio: 0,
  13. runWorkerEnabled: false
  14. }
  15. const GLOBAL_DATA = {
  16. relationLength: 0,
  17. loopStatus: -1,
  18. };
  19. const getDataFromParent = (type, callback) => {
  20. const id = ++Request.count;
  21. Request.callbacks[id] = callback;
  22. process.send({ method: 'get', id, type });
  23. }
  24. const postDataToParent = (type, data) => {
  25. process.send({ method: 'post', type, data });
  26. }
  27. process.on('message', (message) => {
  28. const { callbacks } = Request;
  29. const { method, id, type, data } = message;
  30. if (method == 'get' && id) {
  31. let responseData = null;
  32. // if (data == 'getSolution') {
  33. // responseData = Solution.get();
  34. // }
  35. process.send({ type: 'response', id, data: responseData });
  36. }
  37. else if (type == 'response' && id && callbacks[id]) {
  38. callbacks[id](data);
  39. delete callbacks[id];
  40. }
  41. });
  42. /**
  43. * 精确浮点数字
  44. * @param {number} number
  45. * @param {number} x
  46. * @returns {number}
  47. */
  48. const fixFloat = (number, x=2) => {
  49. return parseFloat(number.toFixed(x));
  50. }
  51. const getSetting = () => {
  52. return new Promise(resolve => {
  53. getDataFromParent('getSetting', (setting) => {
  54. resolve(setting);
  55. });
  56. });
  57. }
  58. const getGamesRelation = () => {
  59. const status = +SETTING.runWorkerEnabled;
  60. if (GLOBAL_DATA.loopStatus !== status) {
  61. GLOBAL_DATA.loopStatus = status;
  62. Logs.out('loop status changed to', status);
  63. }
  64. if (!SETTING.runWorkerEnabled) {
  65. return Promise.resolve([]);
  66. }
  67. return new Promise(resolve => {
  68. getDataFromParent('getGamesRelation', (relations) => {
  69. resolve(relations);
  70. });
  71. });
  72. }
  73. // const getSolutionHistory = () => {
  74. // return new Promise(resolve => {
  75. // getDataFromParent('getSolutionHistory', (solutions) => {
  76. // resolve(solutions);
  77. // });
  78. // });
  79. // }
  80. const setSolutions = (solutions) => {
  81. postDataToParent('setSolutions', solutions);
  82. }
  83. const extractOdds = ({ evtime, events, sptime, special }) => {
  84. const expireTime = Date.now() - 15000;
  85. let odds = {};
  86. if (evtime > expireTime) {
  87. odds = { ...odds, ...events };
  88. }
  89. if (sptime > expireTime) {
  90. odds = { ...odds, ...special };
  91. }
  92. return odds;
  93. }
  94. // const getOptimalOdds = (oddsMap) => {
  95. // const oddsInfo = {};
  96. // Object.keys(oddsMap).forEach(platform => {
  97. // const odds = oddsMap[platform];
  98. // Object.keys(odds).forEach(ior => {
  99. // const oddsValue = odds[ior];
  100. // if (!oddsInfo[ior] || oddsInfo[ior]?.v < oddsValue) {
  101. // oddsInfo[ior] = {
  102. // p: platform,
  103. // v: oddsValue
  104. // }
  105. // }
  106. // });
  107. // });
  108. // return oddsInfo;
  109. // }
  110. const eventMatch = () => {
  111. getGamesRelation()
  112. .then(relations => {
  113. if (!relations?.length) {
  114. return;
  115. }
  116. const nowTime = Date.now();
  117. relations = relations.filter(relaiton => {
  118. const expire = Object.values(relaiton.rel).find(event => event.timestamp <= nowTime);
  119. if (expire) {
  120. return false;
  121. }
  122. return true;
  123. });
  124. const relationLength = relations.length;
  125. if (!relationLength) {
  126. if (GLOBAL_DATA.relationLength) {
  127. GLOBAL_DATA.relationLength = 0;
  128. Logs.out('relation list is empty');
  129. }
  130. return [];
  131. }
  132. GLOBAL_DATA.relationLength = relationLength;
  133. const passableEvents = relations.map(({ id, rel }) => {
  134. const eventsMap = {};
  135. const oddsMap = {};
  136. Object.keys(rel).forEach(platform => {
  137. const { leagueName, teamHomeName, teamAwayName, timestamp, evtime, events, sptime, special } = rel[platform];
  138. if (!events && !special) {
  139. return;
  140. }
  141. if (!eventsMap.info) {
  142. eventsMap.info = { leagueName, teamHomeName, teamAwayName, id, timestamp };
  143. }
  144. const odds = extractOdds({ evtime, events, sptime, special });
  145. Object.keys(odds).forEach(ior => {
  146. if (!oddsMap[ior]) {
  147. oddsMap[ior] = {};
  148. }
  149. oddsMap[ior][platform] = odds[ior];
  150. });
  151. });
  152. eventsMap.odds = oddsMap;
  153. return eventsMap;
  154. });
  155. const solutions = eventsCombination(passableEvents, SETTING);
  156. setSolutions(solutions);
  157. })
  158. .finally(() => {
  159. setTimeout(() => {
  160. eventMatch();
  161. }, 2000);
  162. });
  163. };
  164. const syncSetting = () => {
  165. getSetting()
  166. .then(setting => {
  167. if (setting) {
  168. Object.keys(setting).forEach(key => {
  169. SETTING[key] = setting[key];
  170. });
  171. }
  172. })
  173. .finally(() => {
  174. setTimeout(() => {
  175. syncSetting();
  176. }, 10000);
  177. });
  178. }
  179. syncSetting();
  180. eventMatch();