| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- const Logs = require('../libs/logs');
- const eventsCombination = require('./trangleCalc');
- const Request = {
- callbacks: {},
- count: 0,
- }
- // const WIN_STEP = 15;
- // const SOL_FREEZ_TIME = 1000 * 30;
- const GLOBAL_DATA = {
- relationLength: 0,
- solutions: {},
- };
- const getDataFromParent = (type, callback) => {
- const id = ++Request.count;
- Request.callbacks[id] = callback;
- process.send({ method: 'get', id, type });
- }
- const postDataToParent = (type, data) => {
- process.send({ method: 'post', type, data });
- }
- process.on('message', (message) => {
- const { callbacks } = Request;
- const { method, id, type, data } = message;
- if (method == 'get' && id) {
- let responseData = null;
- // if (data == 'getSolution') {
- // responseData = Solution.get();
- // }
- process.send({ type: 'response', id, data: responseData });
- }
- else if (type == 'response' && id && callbacks[id]) {
- callbacks[id](data);
- delete callbacks[id];
- }
- });
- /**
- * 精确浮点数字
- * @param {number} number
- * @param {number} x
- * @returns {number}
- */
- const fixFloat = (number, x=2) => {
- return parseFloat(number.toFixed(x));
- }
- const getGamesRelation = () => {
- return new Promise(resolve => {
- getDataFromParent('getGamesRelation', (relations) => {
- resolve(relations);
- });
- });
- }
- const getSolutionHistory = () => {
- return new Promise(resolve => {
- getDataFromParent('getSolutionHistory', (solutions) => {
- resolve(solutions);
- });
- });
- }
- const setSolution = (solutions) => {
- postDataToParent('setSolution', solutions);
- }
- const extractOdds = ({ evtime, events, sptime, special }) => {
- const expireTime = Date.now() - 15000;
- let odds = {};
- if (evtime > expireTime) {
- odds = { ...odds, ...events };
- }
- if (sptime > expireTime) {
- odds = { ...odds, ...special };
- }
- return odds;
- }
- // const getOptimalOdds = (oddsMap) => {
- // const oddsInfo = {};
- // Object.keys(oddsMap).forEach(platform => {
- // const odds = oddsMap[platform];
- // Object.keys(odds).forEach(ior => {
- // const oddsValue = odds[ior];
- // if (!oddsInfo[ior] || oddsInfo[ior]?.v < oddsValue) {
- // oddsInfo[ior] = {
- // p: platform,
- // v: oddsValue
- // }
- // }
- // });
- // });
- // return oddsInfo;
- // }
- const eventMatch = () => {
- getGamesRelation()
- .then(relations => {
- const nowTime = Date.now();
- relations = relations.filter(relaiton => {
- const expire = Object.values(relaiton.rel).find(event => event.timestamp <= nowTime);
- if (expire) {
- return false;
- }
- return true;
- });
- console.log(JSON.stringify(relations, null, 2));
- const relationLength = relations.length;
- if (!relationLength) {
- if (GLOBAL_DATA.relationLength) {
- GLOBAL_DATA.relationLength = 0;
- Logs.out('relation list is empty');
- }
- return [];
- }
- GLOBAL_DATA.relationLength = relationLength;
- const passableEvents = relations.map(({ id, rel }) => {
- const eventsMap = {};
- const oddsMap = {};
- Object.keys(rel).forEach(platform => {
- const { leagueName, teamHomeName, teamAwayName, timestamp, evtime, events, sptime, special } = rel[platform];
- if (!events && !special) {
- return;
- }
- if (!eventsMap.info) {
- eventsMap.info = { leagueName, teamHomeName, teamAwayName, id, timestamp };
- }
- const odds = extractOdds({ evtime, events, sptime, special });
- Object.keys(odds).forEach(ior => {
- if (!oddsMap[ior]) {
- oddsMap[ior] = {};
- }
- oddsMap[ior][platform] = odds[ior];
- });
- });
- eventsMap.odds = oddsMap;
- return eventsMap;
- });
- const solutions = eventsCombination(passableEvents);
- if (solutions?.length) {
- const solutionsHistory = GLOBAL_DATA.solutions;
- const updateIds = { add: [], update: [] }
- solutions.forEach(item => {
- const { sid, sol: { win_average } } = item;
- if (!solutionsHistory[sid]) {
- solutionsHistory[sid] = item;
- updateIds.add.push({ sid, win_average });
- return;
- }
- const historyWinAverage = solutionsHistory[sid].sol.win_average;
- if (win_average != historyWinAverage) {
- solutionsHistory[sid] = item;
- updateIds.update.push({ sid, win_average, his_average: historyWinAverage, diff: fixFloat(win_average - historyWinAverage) });
- return;
- }
- const { timestamp } = item;
- solutionsHistory[sid].timestamp = timestamp;
- });
- if (updateIds.add.length || updateIds.update.length) {
- const solutionsList = Object.values(solutionsHistory).sort((a, b) => b.sol.win_average - a.sol.win_average);
- Logs.out('solutions history update', solutionsList, updateIds);
- }
- }
- })
- .finally(() => {
- setTimeout(() => {
- eventMatch();
- }, 2000);
- });
- };
- const solutionsCleanup = () => {
- const solutionsHistory = GLOBAL_DATA.solutions;
- Object.keys(solutionsHistory).forEach(sid => {
- const { timestamp } = solutionsHistory[sid];
- const nowTime = Date.now();
- if (nowTime - timestamp > 1000*60) {
- delete solutionsHistory[sid];
- Logs.out('solution history timeout', sid);
- return;
- }
- const solution = solutionsHistory[sid];
- const eventTime = solution.info.timestamp;
- if (nowTime > eventTime) {
- delete solutionsHistory[sid];
- Logs.out('solution history expired', sid);
- }
- });
- }
- setInterval(() => {
- solutionsCleanup();
- }, 1000*30);
- eventMatch();
|