| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- import GetTranslation from "../libs/getTranslation.js";
- import { getSolutionsWithRelations, getGamesRelationsMap } from "../libs/getGamesRelations.js";
- import Store from "../state/store.js";
- import { createBetOrder, getBetOrders, removeBetOrder } from "./BetOrder.js";
- import {
- getPlatformIorsDetailInfo,
- getSolutionByLatestIors,
- createPolymarketLimitBuyOrder,
- getPolymarketBalanceAllowance,
- getPolymarketOpenOrders,
- getPolymarketOrder,
- getPinnacleBalance,
- transferPolymarketWallet,
- } from "./Markets.js";
- /**
- * 精确浮点数字
- * @param {number} number
- * @param {number} x
- * @returns {number}
- */
- const fixFloat = (number, x=3) => {
- return parseFloat(number.toFixed(x));
- }
- export const getLeagues = async () => {
- const { polymarket, pinnacle } = Store.get('leagues') ?? { polymarket: [], pinnacle: [] };
- const polymarketNames = polymarket.map(item => item.name);
- const translatedNames = await GetTranslation(polymarketNames);
- const newPolymarket = polymarket.map(item => {
- const { name } = item;
- const localesName = translatedNames[name] ?? name;
- return { ...item, localesName };
- });
- return { polymarket: newPolymarket, pinnacle };
- }
- export const setLeaguesRelation = async (relation) => {
- const { id, platforms } = relation;
- if (!id || !platforms) {
- return Promise.reject(new Error('invalid request', { cause: 400 }));
- }
- const storeRelations = Store.get('leaguesRelations') ?? {};
- if (storeRelations[id]) {
- return Promise.reject(new Error('relation already exists', { cause: 400 }));
- }
- storeRelations[id] = relation;
- Store.set('leaguesRelations', storeRelations);
- return Promise.resolve();
- };
- export const removeLeaguesRelation = async (id) => {
- if (!id) {
- return Promise.reject(new Error('invalid request', { cause: 400 }));
- }
- const storeRelations = Store.get('leaguesRelations') ?? {};
- if (!storeRelations[id]) {
- return Promise.reject(new Error('relation not found', { cause: 400 }));
- }
- delete storeRelations[id];
- Store.set('leaguesRelations', storeRelations);
- return Promise.resolve();
- };
- export const getLeaguesRelations = async () => {
- const storeRelations = Object.values(Store.get('leaguesRelations') ?? {});
- const polymarketNames = storeRelations.map(item => item.platforms.polymarket.name);
- const translatedNames = await GetTranslation(polymarketNames);
- const newRelations = storeRelations.map(item => {
- const { platforms: { polymarket, pinnacle } } = item;
- const { name } = polymarket;
- const localesName = translatedNames[name] ?? name;
- return { ...item, platforms: { polymarket: { ...polymarket, localesName }, pinnacle } };
- });
- return Promise.resolve(newRelations);
- };
- export const getGames = async () => {
- const { polymarket, pinnacle } = Store.get('games') ?? { polymarket: [], pinnacle: [] };
- const polymarketNames = [ ...new Set(polymarket.map(item => [item.teamHomeName, item.teamAwayName, item.leagueName]).flat()) ];
- const translatedNames = await GetTranslation(polymarketNames);
- const newPolymarket = polymarket.map(item => {
- const { leagueName, teamHomeName, teamAwayName } = item;
- const localesTeamHomeName = translatedNames[teamHomeName] ?? teamHomeName;
- const localesTeamAwayName = translatedNames[teamAwayName] ?? teamAwayName;
- const localesLeagueName = translatedNames[leagueName] ?? leagueName;
- return { ...item, localesTeamHomeName, localesTeamAwayName, localesLeagueName };
- }).filter(item => {
- const { timestamp } = item;
- const now = Date.now();
- return (timestamp + 1000 * 60 * 60 * 2) > now;
- }).sort((a, b) => a.timestamp - b.timestamp);
- return { polymarket: newPolymarket, pinnacle };
- }
- export const setGamesRelation = async (relation) => {
- const { id, platforms, timestamp } = relation;
- if (!id || !platforms || !timestamp) {
- return Promise.reject(new Error('invalid request', { cause: 400 }));
- }
- const storeRelations = Store.get('gamesRelations') ?? {};
- if (storeRelations[id]) {
- return Promise.reject(new Error('relation already exists', { cause: 400 }));
- }
- storeRelations[id] = relation;
- Store.set('gamesRelations', storeRelations);
- return Promise.resolve();
- }
- export const removeGamesRelation = async (id) => {
- if (!id) {
- return Promise.reject(new Error('invalid request', { cause: 400 }));
- }
- const storeRelations = Store.get('gamesRelations') ?? {};
- if (!storeRelations[id]) {
- return Promise.reject(new Error('relation not found', { cause: 400 }));
- }
- delete storeRelations[id];
- Store.set('gamesRelations', storeRelations);
- return Promise.resolve();
- }
- export const getGamesRelations = async () => {
- const gamesRelations = Object.values(getGamesRelationsMap()).sort((a, b) => a.timestamp - b.timestamp);
- return Promise.resolve(gamesRelations);
- }
- /**
- * 获取解决方案
- * @param {*} param0
- * @returns
- */
- export const getSolutions = async ({ min_profit_rate = 0 } = {}) => {
- const solutions = Store.get('solutions') ?? [];
- const solutionsList = solutions.filter(solution => {
- const { sol: { win_profit_rate } } = solution;
- return win_profit_rate >= min_profit_rate;
- }).sort((a, b) => {
- return b.sol.win_profit_rate - a.sol.win_profit_rate;
- });
- return getSolutionsWithRelations(solutionsList, 5);
- }
- /**
- * 计算Polymarket下注数量精度
- */
- const calculatePolymarketStakeCount = ({ stake, tick_size, bid_ex, min_order_size } = {}) => {
- const decimalPlaces = tick_size.toString().split('.')[1]?.length ?? 0;
- const stakeCount = fixFloat(stake / bid_ex, decimalPlaces);
- if (stakeCount < min_order_size) {
- return null;
- }
- return stakeCount;
- }
- /**
- * 获取策略对应的盘口信息
- */
- export const getSolutionIorsInfo = async (sid) => {
- const gamesRelations = getGamesRelationsMap();
- const solution = Store.get('solutions')?.find(item => item.sid == sid);
- if (!solution) {
- return Promise.reject(new Error('solution not found', { cause: 400 }));
- }
- const { rid, cpr, sol: { cross_type } } = solution;
- const gameRelation = gamesRelations[rid];
- if (!gameRelation) {
- return Promise.reject(new Error('game relation not found', { cause: 400 }));
- }
- const { platforms: { polymarket, pinnacle } } = gameRelation;
- const idMap = { polymarket: polymarket.id, pinnacle: pinnacle.id };
- const iorsInfo = await Promise.all(cpr.map(item => {
- const { k, p } = item;
- return getPlatformIorsDetailInfo(k, p, idMap[p]);
- }));
- return { cpr, iorsInfo, cross_type, gameRelation };
- }
- /**
- * 根据策略下注
- */
- export const betSolution = async (sid, stake=0) => {
- const { cpr, iorsInfo, cross_type, gameRelation } = await getSolutionIorsInfo(sid);
- const { iorsValues, stakeLimit, winLimit, sol } = getSolutionByLatestIors(iorsInfo, cross_type);
- const { minGroup } = stakeLimit ?? {};
- if (!minGroup?.length) {
- return Promise.reject(new Error('no stake limit', { cause: 400 }));
- }
- const polymarketIndex = cpr.findIndex(item => item.p === 'polymarket');
- const polymarketInfo = iorsInfo[polymarketIndex];
- if (!polymarketInfo) {
- return Promise.reject(new Error('polymarket info not found', { cause: 400 }));
- }
- const pinnacleInfos = [...iorsInfo];
- pinnacleInfos.splice(polymarketIndex, 1);
- const polymarketStake = minGroup[polymarketIndex];
- const polymarketPrice = cpr[polymarketIndex].bid_ex;
- const polymarketStakeCount = calculatePolymarketStakeCount({ stake: polymarketStake, tick_size: polymarketInfo.tick_size, bid_ex: polymarketPrice, min_order_size: polymarketInfo.min_order_size });
- if (!polymarketStakeCount) {
- return Promise.reject(new Error('polymarket stake count not found', { cause: 400 }));
- }
- // return { cpr, solutionInfo, polymarketInfo, pinnacleInfos, polymarketStakeCount};
- const polymarketOrder = await createPolymarketLimitBuyOrder({
- tokenID: polymarketInfo.asset_id,
- price: polymarketPrice,
- size: polymarketStakeCount,
- tickSize: polymarketInfo.tick_size,
- negRisk: polymarketInfo.neg_risk,
- });
- const result = {
- polymarketOrder,
- iorsValues,
- sol,
- stakeLimit,
- winLimit,
- iorsInfo,
- cpr,
- gameRelation,
- };
- return createBetOrder({
- sid,
- stake: polymarketStake,
- side: 'BUY',
- size: polymarketStakeCount,
- ...result,
- });
- }
- /**
- * 获取下注订单记录
- */
- export const getOrders = async ({ limit = 100 } = {}) => {
- return getBetOrders({ limit });
- }
- /**
- * 删除下注订单记录
- */
- export const removeOrder = async (id) => {
- return removeBetOrder(id);
- }
- /**
- * 查询Polymarket单个订单
- */
- export const getOrder = async ({ orderID } = {}) => {
- return getPolymarketOrder({ orderID });
- }
- /**
- * 查询Polymarket开放订单
- */
- export const getOpenOrders = async ({
- id,
- market,
- asset_id,
- only_first_page = false,
- next_cursor,
- } = {}) => {
- return getPolymarketOpenOrders({
- id,
- market,
- asset_id,
- only_first_page,
- next_cursor,
- });
- }
- /**
- * 获取Pinnacle账户余额信息
- */
- export const getPinnacleAccountBalance = async ({ channel } = {}) => {
- return getPinnacleBalance({ channel });
- }
- /**
- * 清理过期关系
- */
- const cleanGamesRelations = () => {
- const now = Date.now();
- const storeRelations = Store.get('gamesRelations') ?? [];
- Object.keys(storeRelations).forEach(key => {
- const relation = storeRelations[key];
- const { timestamp } = relation;
- if ((timestamp + 1000 * 60 * 60 * 2) < now) {
- delete storeRelations[key];
- }
- });
- Store.set('gamesRelations', storeRelations);
- }
- setInterval(cleanGamesRelations, 1000 * 60);
- export default {
- getLeagues, setLeaguesRelation, removeLeaguesRelation, getLeaguesRelations,
- getGames, setGamesRelation, removeGamesRelation, getGamesRelations,
- getSolutions, getSolutionIorsInfo, betSolution, getOrders, removeOrder, getOrder, getOpenOrders,
- getPolymarketBalanceAllowance, getPinnacleAccountBalance, transferPolymarketWallet,
- };
|