1st
This commit is contained in:
112
static/aliases.js
Executable file
112
static/aliases.js
Executable file
@@ -0,0 +1,112 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
Handball = 2
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let lastTeamID;
|
||||
|
||||
let zoneSelect = new Select({
|
||||
field: document.getElementById('zone'),
|
||||
key: 'zoneID',
|
||||
name: 'name'
|
||||
})
|
||||
|
||||
zoneSelect.on('select', zoneID => {
|
||||
aliasesModel.clear()
|
||||
|
||||
api.req({
|
||||
func: 'listTeamsByZone',
|
||||
data: zoneID,
|
||||
onSuccess: resp => {
|
||||
teamSelect.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
lastTeamID = ''
|
||||
|
||||
let obj = f.getFormData()
|
||||
obj.teamID = ''
|
||||
|
||||
f.setObj(obj)
|
||||
})
|
||||
|
||||
let teamSelect = new Select({
|
||||
field: document.getElementById('team'),
|
||||
key: 'teamID',
|
||||
name: 'canonicalName'
|
||||
})
|
||||
|
||||
teamSelect.on('select', teamID => {
|
||||
aliasesModel.load({
|
||||
data: teamID,
|
||||
})
|
||||
/*
|
||||
api.req({
|
||||
func: 'listFootballTeamAliases',
|
||||
data: teamID,
|
||||
onSuccess: resp => {
|
||||
//aliasesModel.setList(resp)
|
||||
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
lastTeamID = teamID
|
||||
|
||||
let obj = f.getFormData()
|
||||
obj.teamID = teamID
|
||||
|
||||
f.setObj(obj)
|
||||
})
|
||||
|
||||
let aliasesModel = new ListModel({
|
||||
template: {
|
||||
id: 'listItem'
|
||||
},
|
||||
key: 'aliasID',
|
||||
container: 'aliases',
|
||||
btnRemove: 'removeAlias',
|
||||
ajax: {
|
||||
api: api,
|
||||
listFunc: 'listTeamAliases',
|
||||
removeFunc: 'removeTeamAlias'
|
||||
}
|
||||
})
|
||||
|
||||
let f = new Formobj({
|
||||
form: 'add',
|
||||
schema: {
|
||||
name: 'str',
|
||||
teamID: 'str'
|
||||
},
|
||||
validate: obj => {
|
||||
if (obj.teamID == '') {
|
||||
return {
|
||||
message: 'Не выбрана команда!'
|
||||
}
|
||||
}
|
||||
},
|
||||
api: api,
|
||||
submitFunc: 'addTeamAlias',
|
||||
editable: true,
|
||||
onSubmitResult: () => {
|
||||
aliasesModel.load({
|
||||
data: lastTeamID
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listTeamZones',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
zoneSelect.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
609
static/football.js
Normal file
609
static/football.js
Normal file
@@ -0,0 +1,609 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
Football = 1
|
||||
Handball = 2
|
||||
|
||||
OnexbetFootball = 1
|
||||
OnexbetHandball = 8
|
||||
|
||||
onexbetWsURL = 'ws://195.189.227.88:7772/ws'
|
||||
tipperWsURL = 'ws://195.189.227.88:7768/ws'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=> {
|
||||
interesting = new ListModel({
|
||||
template: {
|
||||
id: 'interestingMatch',
|
||||
renders: {
|
||||
interestingMatch: (tags, match) => {
|
||||
//console.log('render', match)
|
||||
let radios = new RadioList({
|
||||
container: tags.candidates,
|
||||
templateId: 'candidate-item',
|
||||
setEmptyMessage: 'нет матчей кандидатов'
|
||||
})
|
||||
|
||||
tags.flashscoreLink.href= `https://www.flashscore.com/match/${match.matchID}/#match-summary/match-summary`
|
||||
|
||||
tags.search.addEventListener('click', () => {
|
||||
let teamName = tags.teamName.value.trim()
|
||||
|
||||
if (teamName == '') {
|
||||
return
|
||||
}
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidatesByTeamName',
|
||||
data: {
|
||||
sportID: Football,
|
||||
teamName: teamName,
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
radios.clear()
|
||||
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.submit.addEventListener('click', () => {
|
||||
//console.log(radios.getSelected())
|
||||
let candidate = radios.getSelected()
|
||||
if (!candidate) {
|
||||
return
|
||||
}
|
||||
let isReverse = tags.isReverse.checked
|
||||
|
||||
var home, away;
|
||||
|
||||
if (isReverse) {
|
||||
home = {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
away = {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.home
|
||||
}
|
||||
} else {
|
||||
home = {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.home
|
||||
}
|
||||
away = {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
}
|
||||
|
||||
console.log('home:', home);
|
||||
console.log('away:', away);
|
||||
|
||||
api.req({
|
||||
func: 'addTeamsAliases',
|
||||
data: {
|
||||
home: home,
|
||||
away: away
|
||||
},
|
||||
onError: err => {
|
||||
//tags.candidates.textContent = 'FUCK: ' + err
|
||||
console.log(err)
|
||||
},
|
||||
onSuccess: resp => {
|
||||
//console.log('ok')
|
||||
//tags.identification.click()
|
||||
radios.clear()
|
||||
tags.candidates.textContent = "Алиасы добавлены!"
|
||||
tags.submit.disabled = true
|
||||
tags.isReverse.checked = false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.identification.addEventListener('click', () => {
|
||||
//console.log('details:', tags.identification.open)
|
||||
//console.log(match)
|
||||
if (tags.identification.open) {
|
||||
//tags.candidates.innerHTML = ''
|
||||
} else {
|
||||
//tags.candidates.innerHTML = ''
|
||||
radios.clear()
|
||||
|
||||
//radios.setList([
|
||||
// {home: 'Arsenal', away: 'Mancity', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
// {home: 'Arsenal', away: 'Aston villa', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
//])
|
||||
|
||||
//tags.candidates.textContent = JSON.stringify(match)
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidates',
|
||||
data: {
|
||||
sportID: Football,
|
||||
home: match.home.canonicalName,
|
||||
away: match.away.canonicalName
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'interesting',
|
||||
preFunc: modifyInterestingMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// ONEXBET
|
||||
|
||||
//1xbet
|
||||
bookLiveModel = new ListModel({
|
||||
template: {
|
||||
id: 'liveMatch',
|
||||
},
|
||||
container: 'book-live',
|
||||
preFunc: modifyLiveMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// tips
|
||||
|
||||
tipModel = new ListModel({
|
||||
template: {
|
||||
id: 'tip',
|
||||
renders: {
|
||||
tip: (tags, tip) => {
|
||||
//console.log('tags:', tags)
|
||||
//console.log('x:', x)
|
||||
if (tip.status == 1) {
|
||||
tags.matchName.classList.add('profit')
|
||||
} else if (tip.status == 2) {
|
||||
tags.matchName.classList.add('errmsg')
|
||||
} else if (tip.status == 3) {
|
||||
tags.matchName.classList.add('void')
|
||||
}
|
||||
|
||||
tags.flashscoreLink.href= `https://www.flashscore.com/match/${tip.matchID}/#match-summary/match-summary`
|
||||
|
||||
tags.setResultLink.addEventListener('click', () => {
|
||||
if (tags.setResultForm.hidden) {
|
||||
let f = new Form({
|
||||
formContainer: tags.setResultForm,
|
||||
schema: [
|
||||
{
|
||||
name: 'result',
|
||||
type: 'line',
|
||||
label: 'Результат',
|
||||
comment: 'например, 1й тайм: 1:1'
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
type: 'radios',
|
||||
label: ' ',
|
||||
getName: x => x.name,
|
||||
data: [
|
||||
{name: 'Выигрыш', status: 1},
|
||||
{name: 'Проигрыш', status: 2},
|
||||
{name: 'Возврат', status: 3},
|
||||
]
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
f.onSubmit((obj) => {
|
||||
obj.tipID = tip.tipID
|
||||
//console.log(obj)
|
||||
api.req({
|
||||
func: 'setTipResult',
|
||||
data: obj,
|
||||
onError: err => {
|
||||
f.showError(err)
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Перезагружаем список
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Football,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
f.init()
|
||||
|
||||
tags.setResultForm.hidden = false
|
||||
} else {
|
||||
tags.setResultForm.hidden = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'tips',
|
||||
preFunc: modifyTip,
|
||||
sort: {
|
||||
key: 'tipTime',
|
||||
//reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// strategies
|
||||
|
||||
strategiesModel = new ListModel({
|
||||
template: {
|
||||
id: 'strategy',
|
||||
},
|
||||
container: 'strategies',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
totalsModel = new ListModel({
|
||||
template: {
|
||||
id: 'total',
|
||||
},
|
||||
container: 'totals',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
let onexbetWs = new WebsocketClient({
|
||||
url: onexbetWsURL
|
||||
})
|
||||
|
||||
onexbetWs.handle('liveMatches', resp => {
|
||||
//console.log('liveMatches:', resp)
|
||||
|
||||
if (resp.sportID == OnexbetFootball) {
|
||||
if (Array.isArray(resp.matches)) {
|
||||
bookLiveModel.setList(resp.matches)
|
||||
|
||||
resp.matches.forEach(match => {
|
||||
interesting.partialUpdateBy(
|
||||
// update func
|
||||
(tags, obj) => {
|
||||
tags.livescore.textContent = footballScoreToString(match.scoreByPeriods)
|
||||
tags.livescore.hidden = false
|
||||
},
|
||||
// key func
|
||||
(obj) => {
|
||||
if (obj.onexbetMatchID == match.matchID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.handle('teamLiveMatchData', resp => {
|
||||
//console.log('teamLiveMatchData:', resp)
|
||||
})
|
||||
|
||||
|
||||
// tipper
|
||||
let tipperWs = new WebsocketClient({
|
||||
url: tipperWsURL
|
||||
})
|
||||
|
||||
tipperWs.onConnected = () => {
|
||||
tipperWs.send('subscribe', {channels: ['football']})
|
||||
}
|
||||
|
||||
tipperWs.handle('teamMatches', resp => {
|
||||
//console.log('reports:', resp)
|
||||
|
||||
if (Array.isArray(resp.matches)) {
|
||||
//console.log('set interesting:', resp.matches)
|
||||
interesting.setList(resp.matches)
|
||||
}
|
||||
})
|
||||
|
||||
tipperWs.handle('tipsChanged', resp => {
|
||||
//console.log('tip:', resp)
|
||||
|
||||
//tipModel.add(resp)
|
||||
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Football,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
data: Football,
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(resp)
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
tipperWs.handle('whyNot', resp => {
|
||||
//console.log('whyNot:', resp.matchID, resp.comment)
|
||||
interesting.partialUpdateBy(
|
||||
(tags, obj) => {
|
||||
tags.comment.innerHTML = resp.comment
|
||||
tags.time.textContent = resp.time
|
||||
tags.score.textContent = `${resp.homeGoals} - ${resp.awayGoals}`
|
||||
},
|
||||
(obj) => {
|
||||
if (obj.matchID == resp.matchID) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tipperWs.handle('inplayStatusChanged', resp => {
|
||||
//console.log('inplayStatusChanged:', resp)
|
||||
interesting.partialUpdateBy(
|
||||
(tags, obj) => {
|
||||
if (resp.isInplay) {
|
||||
tags.isInplay.textContent = 'inplay'
|
||||
} else {
|
||||
tags.isInplay.textContent = ''
|
||||
}
|
||||
|
||||
if (resp.isLinkedToOnexbet) {
|
||||
tags.isLinked.textContent = 'linked to 1xBet'
|
||||
} else {
|
||||
tags.isLinked.textContent = ''
|
||||
}
|
||||
},
|
||||
(obj) => {
|
||||
if (obj.matchID == resp.matchID) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
ws.handle('footballMatchReports', resp => {
|
||||
console.log('reports:', resp)
|
||||
updateChamp(resp)
|
||||
})
|
||||
*/
|
||||
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Football,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
data: Football,
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(resp)
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
api.req({
|
||||
func: 'getSportRatedReport',
|
||||
data: Football,
|
||||
onSuccess: resp => {
|
||||
showRatedTotal(resp)
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.connect()
|
||||
tipperWs.connect()
|
||||
|
||||
})
|
||||
|
||||
function showRatedTotal(report) {
|
||||
document.getElementById('ratedTotalsWonTips').textContent = report.wonTips
|
||||
document.getElementById('ratedTotalsLostTips').textContent = report.lostTips
|
||||
document.getElementById('ratedTotalsAccuracy').textContent = Math.round(report.accuracy*100)/100
|
||||
document.getElementById('ratedTotalsTurnover').textContent = report.turnover
|
||||
document.getElementById('ratedTotalsProfit').textContent = Math.round(report.profit*100)/100
|
||||
document.getElementById('ratedTotalsROI').textContent = Math.round(report.roi*100)/100
|
||||
}
|
||||
|
||||
|
||||
function showTotal(reports) {
|
||||
// 1,2,3
|
||||
let allChampsTotal = {
|
||||
name: 'Все чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
/*
|
||||
let topChampsTotal = {
|
||||
name: 'Топ чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
|
||||
let myTotal = {
|
||||
name: 'Алгоритмы от Программиста',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
*/
|
||||
let m = new Map()
|
||||
|
||||
|
||||
//m.set(1, allChampsTotal)
|
||||
//m.set(2, allChampsTotal)
|
||||
//m.set(3, allChampsTotal)
|
||||
m.set(6, allChampsTotal)
|
||||
m.set(7, allChampsTotal)
|
||||
m.set(8, allChampsTotal)
|
||||
|
||||
|
||||
if (Array.isArray(reports)) {
|
||||
reports.forEach(r => {
|
||||
let total = m.get(r.strategyID)
|
||||
if (!total) {
|
||||
return
|
||||
}
|
||||
|
||||
total.wonTips += r.wonTips
|
||||
total.lostTips += r.lostTips
|
||||
total.profit += r.profit
|
||||
total.turnover += r.turnover
|
||||
})
|
||||
}
|
||||
|
||||
clacROIandAccuracy(allChampsTotal)
|
||||
//clacROIandAccuracy(topChampsTotal)
|
||||
//clacROIandAccuracy(myTotal)
|
||||
|
||||
|
||||
//totalsModel.setList([allChampsTotal, topChampsTotal, myTotal])
|
||||
totalsModel.setList([allChampsTotal])
|
||||
|
||||
//document.getElementById('total').textContent = 'Общий итог: ' + total + ' грн'
|
||||
}
|
||||
|
||||
function clacROIandAccuracy(total) {
|
||||
total.roi = (total.profit * 100) / total.turnover
|
||||
total.accuracy = (total.wonTips * 100) / (total.wonTips + total.lostTips)
|
||||
|
||||
//total.roi = Math.round(total.roi*100)/100
|
||||
//total.accuracy = Math.round(total.accuracy*100)/100
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function modifyReport(report) {
|
||||
report.match = `${report.home.canonicalName} - ${report.away.canonicalName}`
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
|
||||
function modifyInterestingMatch(report) {
|
||||
//console.log(report)
|
||||
|
||||
report.champName = `${report.zone.name}. ${report.champ.name}`
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
let home = report.home.canonicalName
|
||||
if (!report.home.wasLinked) {
|
||||
home = '*' + home
|
||||
}
|
||||
let away = report.away.canonicalName
|
||||
if (!report.away.wasLinked) {
|
||||
away = '*' + away
|
||||
}
|
||||
report.match = `${home} - ${away}`
|
||||
if (report.isLinkedToOnexbet) {
|
||||
report.isLinked = 'linked to 1xBet'
|
||||
}
|
||||
if (report.isInplay) {
|
||||
report.isInplay = 'inplay'
|
||||
} else {
|
||||
report.isInplay = ''
|
||||
}
|
||||
report.notes = JSON.stringify(report, null, 3)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function modifyLiveMatch(report) {
|
||||
if (!report.match) {
|
||||
report.champName = `${report.sportName}. ${report.champName}`
|
||||
}
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
report.match = `${report.home} - ${report.away}`
|
||||
}
|
||||
|
||||
function modifyTip(report) {
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
function footballScoreToString(scoreByPeriods) {
|
||||
if (!scoreByPeriods) {
|
||||
return ''
|
||||
}
|
||||
|
||||
let list = []
|
||||
|
||||
for (var i=1; i <= 2; i++) {
|
||||
let p = scoreByPeriods[i]
|
||||
if (p) {
|
||||
list.push(`${p.home}-${p.away}`)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return list.join(' ')
|
||||
}
|
||||
3550
static/form2.js
Normal file
3550
static/form2.js
Normal file
File diff suppressed because it is too large
Load Diff
2324
static/formobj.js
Executable file
2324
static/formobj.js
Executable file
File diff suppressed because it is too large
Load Diff
620
static/handball.js
Normal file
620
static/handball.js
Normal file
@@ -0,0 +1,620 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
Football = 1
|
||||
Handball = 2
|
||||
|
||||
OnexbetFootball = 1
|
||||
OnexbetHandball = 8
|
||||
|
||||
onexbetWsURL = 'ws://195.189.227.88:7772/ws'
|
||||
tipperWsURL = 'ws://195.189.227.88:33465/ws'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=> {
|
||||
interesting = new ListModel({
|
||||
template: {
|
||||
id: 'interestingMatch',
|
||||
renders: {
|
||||
interestingMatch: (tags, match) => {
|
||||
//console.log('render', match)
|
||||
let radios = new RadioList({
|
||||
container: tags.candidates,
|
||||
templateId: 'candidate-item',
|
||||
setEmptyMessage: 'нет матчей кандидатов'
|
||||
})
|
||||
|
||||
tags.flashscoreLink.href= `https://www.flashscore.com/match/${match.matchID}/#match-summary/match-summary`
|
||||
|
||||
tags.search.addEventListener('click', () => {
|
||||
let teamName = tags.teamName.value.trim()
|
||||
|
||||
if (teamName == '') {
|
||||
return
|
||||
}
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidatesByTeamName',
|
||||
data: {
|
||||
sportID: Handball,
|
||||
teamName: teamName,
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
radios.clear()
|
||||
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.submit.addEventListener('click', () => {
|
||||
//console.log(radios.getSelected())
|
||||
let candidate = radios.getSelected()
|
||||
if (!candidate) {
|
||||
return
|
||||
}
|
||||
|
||||
let isReverse = tags.isReverse.checked
|
||||
|
||||
var home, away;
|
||||
|
||||
if (isReverse) {
|
||||
home = {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
away = {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.home
|
||||
}
|
||||
} else {
|
||||
home = {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.home
|
||||
}
|
||||
away = {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
}
|
||||
|
||||
console.log('home:', home);
|
||||
console.log('away:', away);
|
||||
|
||||
api.req({
|
||||
func: 'addTeamsAliases',
|
||||
data: {
|
||||
home: home,
|
||||
away: away
|
||||
},
|
||||
onError: err => {
|
||||
//tags.candidates.textContent = 'FUCK: ' + err
|
||||
console.log(err)
|
||||
},
|
||||
onSuccess: resp => {
|
||||
//console.log('ok')
|
||||
//tags.identification.click()
|
||||
radios.clear()
|
||||
tags.isReverse.checked = false
|
||||
tags.candidates.textContent = "Алиасы добавлены!"
|
||||
tags.submit.disabled = true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.identification.addEventListener('click', () => {
|
||||
//console.log('details:', tags.identification.open)
|
||||
//console.log(match)
|
||||
if (tags.identification.open) {
|
||||
//tags.candidates.innerHTML = ''
|
||||
} else {
|
||||
//tags.candidates.innerHTML = ''
|
||||
radios.clear()
|
||||
|
||||
//radios.setList([
|
||||
// {home: 'Arsenal', away: 'Mancity', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
// {home: 'Arsenal', away: 'Aston villa', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
//])
|
||||
|
||||
//tags.candidates.textContent = JSON.stringify(match)
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidates',
|
||||
data: {
|
||||
sportID: Handball,
|
||||
home: match.home.canonicalName,
|
||||
away: match.away.canonicalName
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'interesting',
|
||||
preFunc: modifyInterestingMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// ONEXBET
|
||||
|
||||
//1xbet
|
||||
bookLiveModel = new ListModel({
|
||||
template: {
|
||||
id: 'liveMatch',
|
||||
},
|
||||
container: 'book-live',
|
||||
preFunc: modifyLiveMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// tips
|
||||
|
||||
tipModel = new ListModel({
|
||||
template: {
|
||||
id: 'tip',
|
||||
renders: {
|
||||
tip: (tags, tip) => {
|
||||
//console.log('tags:', tags)
|
||||
//console.log('x:', x)
|
||||
if (tip.status == 1) {
|
||||
tags.matchName.classList.add('profit')
|
||||
} else if (tip.status == 2) {
|
||||
tags.matchName.classList.add('errmsg')
|
||||
} else if (tip.status == 3) {
|
||||
tags.matchName.classList.add('void')
|
||||
}
|
||||
|
||||
tags.flashscoreLink.href= `https://www.flashscore.com/match/${tip.matchID}/#match-summary/match-summary`
|
||||
|
||||
tags.setResultLink.addEventListener('click', () => {
|
||||
if (tags.setResultForm.hidden) {
|
||||
let f = new Form({
|
||||
formContainer: tags.setResultForm,
|
||||
schema: [
|
||||
{
|
||||
name: 'result',
|
||||
type: 'line',
|
||||
label: 'Результат',
|
||||
comment: 'например, 1й тайм: 1:1'
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
type: 'radios',
|
||||
label: ' ',
|
||||
getName: x => x.name,
|
||||
data: [
|
||||
{name: 'Выигрыш', status: 1},
|
||||
{name: 'Проигрыш', status: 2},
|
||||
{name: 'Возврат', status: 3},
|
||||
]
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
f.onSubmit((obj) => {
|
||||
obj.tipID = tip.tipID
|
||||
//console.log(obj)
|
||||
api.req({
|
||||
func: 'setTipResult',
|
||||
data: obj,
|
||||
onError: err => {
|
||||
f.showError(err)
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Перезагружаем список
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
f.init()
|
||||
|
||||
tags.setResultForm.hidden = false
|
||||
} else {
|
||||
tags.setResultForm.hidden = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'tips',
|
||||
preFunc: modifyTip,
|
||||
sort: {
|
||||
key: 'tipTime',
|
||||
//reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// strategies
|
||||
|
||||
strategiesModel = new ListModel({
|
||||
template: {
|
||||
id: 'strategy',
|
||||
},
|
||||
container: 'strategies',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
totalsModel = new ListModel({
|
||||
template: {
|
||||
id: 'total',
|
||||
},
|
||||
container: 'totals',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
let onexbetWs = new WebsocketClient({
|
||||
url: onexbetWsURL
|
||||
})
|
||||
|
||||
onexbetWs.handle('liveMatches', resp => {
|
||||
//console.log('liveMatches:', resp)
|
||||
|
||||
if (resp.sportID == OnexbetHandball) {
|
||||
if (Array.isArray(resp.matches)) {
|
||||
bookLiveModel.setList(resp.matches)
|
||||
|
||||
resp.matches.forEach(match => {
|
||||
interesting.partialUpdateBy(
|
||||
// update func
|
||||
(tags, obj) => {
|
||||
tags.livescore.textContent = handballScoreToString(match.scoreByPeriods)
|
||||
tags.livescore.hidden = false
|
||||
},
|
||||
// key func
|
||||
(obj) => {
|
||||
if (obj.onexbetMatchID == match.matchID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.handle('teamLiveMatchData', resp => {
|
||||
//console.log('teamLiveMatchData:', resp)
|
||||
})
|
||||
|
||||
|
||||
// tipper
|
||||
let tipperWs = new WebsocketClient({
|
||||
url: tipperWsURL
|
||||
})
|
||||
|
||||
tipperWs.onConnected = () => {
|
||||
tipperWs.send('subscribe', {channels: ['handball']})
|
||||
}
|
||||
|
||||
tipperWs.handle('teamMatches', resp => {
|
||||
//console.log('reports:', resp)
|
||||
if (resp.sportID == Handball) {
|
||||
if (Array.isArray(resp.matches)) {
|
||||
//console.log('set interesting:', resp.matches)
|
||||
interesting.setList(resp.matches)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
tipperWs.handle('tipsChanged', resp => {
|
||||
//console.log('tip:', resp)
|
||||
|
||||
//tipModel.add(resp)
|
||||
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(filterStrategies(resp))
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tipperWs.handle('whyNot', resp => {
|
||||
//console.log('whyNot:', resp.matchID, resp.comment)
|
||||
interesting.partialUpdateBy(
|
||||
(tags, obj) => {
|
||||
tags.comment.innerHTML = resp.comment
|
||||
tags.time.textContent = resp.time
|
||||
tags.score.textContent = `${resp.homeGoals} - ${resp.awayGoals}`
|
||||
//tags.gamePace.textContent = resp.gamePace
|
||||
//tags.gamePaceFrame.textContent = resp.gamePaceFrame + 1
|
||||
},
|
||||
(obj) => {
|
||||
if (obj.matchID == resp.matchID) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tipperWs.handle('inplayStatusChanged', resp => {
|
||||
//console.log('inplayStatusChanged:', resp)
|
||||
interesting.partialUpdateBy(
|
||||
(tags, obj) => {
|
||||
if (resp.isInplay) {
|
||||
tags.isInplay.textContent = 'inplay'
|
||||
} else {
|
||||
tags.isInplay.textContent = ''
|
||||
}
|
||||
|
||||
if (resp.isLinkedToOnexbet) {
|
||||
tags.isLinked.textContent = 'linked to 1xBet'
|
||||
} else {
|
||||
tags.isLinked.textContent = ''
|
||||
}
|
||||
},
|
||||
(obj) => {
|
||||
if (obj.matchID == resp.matchID) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
ws.handle('footballMatchReports', resp => {
|
||||
console.log('reports:', resp)
|
||||
updateChamp(resp)
|
||||
})
|
||||
*/
|
||||
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(filterStrategies(resp))
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
api.req({
|
||||
func: 'getSportRatedReport',
|
||||
data: Handball,
|
||||
onSuccess: resp => {
|
||||
showRatedTotal(resp)
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.connect()
|
||||
tipperWs.connect()
|
||||
|
||||
})
|
||||
|
||||
|
||||
function showRatedTotal(report) {
|
||||
document.getElementById('ratedTotalsWonTips').textContent = report.wonTips
|
||||
document.getElementById('ratedTotalsLostTips').textContent = report.lostTips
|
||||
document.getElementById('ratedTotalsAccuracy').textContent = Math.round(report.accuracy*100)/100
|
||||
document.getElementById('ratedTotalsTurnover').textContent = report.turnover
|
||||
document.getElementById('ratedTotalsProfit').textContent = Math.round(report.profit*100)/100
|
||||
document.getElementById('ratedTotalsROI').textContent = Math.round(report.roi*100)/100
|
||||
}
|
||||
|
||||
|
||||
function showTotal(reports) {
|
||||
// 1,2,3
|
||||
let allChampsTotal = {
|
||||
name: 'Все чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
/*
|
||||
let topChampsTotal = {
|
||||
name: 'Топ чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
|
||||
let myTotal = {
|
||||
name: 'Алгоритмы от Программиста',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
*/
|
||||
let m = new Map()
|
||||
|
||||
m.set(4, allChampsTotal)
|
||||
m.set(5, allChampsTotal)
|
||||
|
||||
m.set(11, allChampsTotal)
|
||||
m.set(12, allChampsTotal)
|
||||
|
||||
if (Array.isArray(reports)) {
|
||||
reports.forEach(r => {
|
||||
let total = m.get(r.strategyID)
|
||||
if (!total) {
|
||||
return
|
||||
}
|
||||
|
||||
total.wonTips += r.wonTips
|
||||
total.lostTips += r.lostTips
|
||||
total.profit += r.profit
|
||||
total.turnover += r.turnover
|
||||
})
|
||||
}
|
||||
|
||||
clacROIandAccuracy(allChampsTotal)
|
||||
//clacROIandAccuracy(topChampsTotal)
|
||||
//clacROIandAccuracy(myTotal)
|
||||
|
||||
|
||||
//totalsModel.setList([allChampsTotal, topChampsTotal, myTotal])
|
||||
totalsModel.setList([allChampsTotal])
|
||||
|
||||
//document.getElementById('total').textContent = 'Общий итог: ' + total + ' грн'
|
||||
}
|
||||
|
||||
function clacROIandAccuracy(total) {
|
||||
total.roi = (total.profit * 100) / total.turnover
|
||||
total.accuracy = (total.wonTips * 100) / (total.wonTips + total.lostTips)
|
||||
|
||||
//total.roi = Math.round(total.roi*100)/100
|
||||
//total.accuracy = Math.round(total.accuracy*100)/100
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function modifyReport(report) {
|
||||
report.match = `${report.home.canonicalName} - ${report.away.canonicalName}`
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
|
||||
function modifyInterestingMatch(report) {
|
||||
//console.log(report)
|
||||
|
||||
report.champName = `${report.zone.name}. ${report.champ.name}`
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
let home = report.home.canonicalName
|
||||
if (!report.home.wasLinked) {
|
||||
home = '*' + home
|
||||
}
|
||||
let away = report.away.canonicalName
|
||||
if (!report.away.wasLinked) {
|
||||
away = '*' + away
|
||||
}
|
||||
report.match = `${home} - ${away}`
|
||||
if (report.isLinkedToOnexbet) {
|
||||
report.isLinked = 'linked to 1xBet'
|
||||
}
|
||||
if (report.isInplay) {
|
||||
report.isInplay = 'inplay'
|
||||
} else {
|
||||
report.isInplay = ''
|
||||
}
|
||||
report.notes = JSON.stringify(report, null, 3)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function modifyLiveMatch(report) {
|
||||
if (!report.match) {
|
||||
report.champName = `${report.sportName}. ${report.champName}`
|
||||
}
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
report.match = `${report.home} - ${report.away}`
|
||||
}
|
||||
|
||||
function modifyTip(report) {
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
function filterStrategies(src) {
|
||||
let list = []
|
||||
if (Array.isArray(src)) {
|
||||
src.forEach(s => {
|
||||
list.push(s)
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
function handballScoreToString(scoreByPeriods) {
|
||||
if (!scoreByPeriods) {
|
||||
return ''
|
||||
}
|
||||
|
||||
let list = []
|
||||
|
||||
for (var i=1; i <= 3; i++) {
|
||||
let p = scoreByPeriods[i]
|
||||
if (p) {
|
||||
list.push(`${p.home}:${p.away}`)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return list.join(' ')
|
||||
}
|
||||
4602
static/moment.js
Executable file
4602
static/moment.js
Executable file
File diff suppressed because it is too large
Load Diff
2519
static/omg.js
Executable file
2519
static/omg.js
Executable file
File diff suppressed because it is too large
Load Diff
105
static/stats.js
Executable file
105
static/stats.js
Executable file
@@ -0,0 +1,105 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=> {
|
||||
google.charts.load('current', {'packages':['corechart']});
|
||||
|
||||
let model = new ListModel({
|
||||
template: {
|
||||
id: 'champ',
|
||||
},
|
||||
container: 'champs',
|
||||
preFunc: (r) => {
|
||||
r.champ = `${r.zoneName}. ${r.champName}`
|
||||
r.accuracy = (r.won * 100) / (r.won + r.lost)
|
||||
|
||||
r.avgPrice = Math.round(r.avgPrice*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
let s = new Select({
|
||||
field: document.getElementById('strategyID'),
|
||||
key: 'strategyID',
|
||||
name: 'name'
|
||||
})
|
||||
|
||||
s.on('select', strategyID => {
|
||||
if (strategyID) {
|
||||
api.req({
|
||||
func: 'listStrategyChampStats',
|
||||
data: strategyID,
|
||||
onSuccess: resp => {
|
||||
model.setList(resp)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
model.clear()
|
||||
}
|
||||
})
|
||||
|
||||
s.on('select', strategyID => {
|
||||
if (strategyID) {
|
||||
api.req({
|
||||
func: 'getStrategyHistory',
|
||||
data: strategyID,
|
||||
onSuccess: resp => {
|
||||
var rows = []
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(item => {
|
||||
rows.push([
|
||||
new Date(item.date * 1000),
|
||||
item.profit
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
drawChart(strategyID, rows)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
drawChart(0, [])
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategies',
|
||||
onSuccess: resp => {
|
||||
s.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
//google.charts.setOnLoadCallback(drawChart);
|
||||
|
||||
function drawChart(strategyID, rows) {
|
||||
var data = new google.visualization.DataTable();
|
||||
data.addColumn('date', 'Date');
|
||||
data.addColumn('number', 'Алгоритм ' + strategyID);
|
||||
//data.addColumn('number', 'Алгоритм 2');
|
||||
//data.addColumn('number', 'Алгоритм 3');
|
||||
|
||||
console.log(rows)
|
||||
|
||||
data.addRows(rows)
|
||||
|
||||
var options = {
|
||||
chart: {
|
||||
title: 'Кривая доходности',
|
||||
},
|
||||
width: 900,
|
||||
height: 500
|
||||
};
|
||||
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
|
||||
|
||||
//chart.draw(data, google.charts.Line.convertOptions(options));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
105
static/temp_stats.js
Normal file
105
static/temp_stats.js
Normal file
@@ -0,0 +1,105 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=> {
|
||||
google.charts.load('current', {'packages':['corechart']});
|
||||
|
||||
let model = new ListModel({
|
||||
template: {
|
||||
id: 'champ',
|
||||
},
|
||||
container: 'champs',
|
||||
preFunc: (r) => {
|
||||
r.champ = `${r.zoneName}. ${r.champName}`
|
||||
r.accuracy = (r.won * 100) / (r.won + r.lost)
|
||||
|
||||
r.avgPrice = Math.round(r.avgPrice*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
let s = new Select({
|
||||
field: document.getElementById('strategyID'),
|
||||
key: 'strategyID',
|
||||
name: 'name'
|
||||
})
|
||||
|
||||
s.on('select', strategyID => {
|
||||
if (strategyID) {
|
||||
api.req({
|
||||
func: 'listStrategyRatedChampStats',
|
||||
data: strategyID,
|
||||
onSuccess: resp => {
|
||||
model.setList(resp)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
model.clear()
|
||||
}
|
||||
})
|
||||
|
||||
s.on('select', strategyID => {
|
||||
if (strategyID) {
|
||||
api.req({
|
||||
func: 'getStrategyRatedHistory',
|
||||
data: strategyID,
|
||||
onSuccess: resp => {
|
||||
var rows = []
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(item => {
|
||||
rows.push([
|
||||
new Date(item.date * 1000),
|
||||
item.profit
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
drawChart(strategyID, rows)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
drawChart(0, [])
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategies',
|
||||
onSuccess: resp => {
|
||||
s.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
//google.charts.setOnLoadCallback(drawChart);
|
||||
|
||||
function drawChart(strategyID, rows) {
|
||||
var data = new google.visualization.DataTable();
|
||||
data.addColumn('date', 'Date');
|
||||
data.addColumn('number', 'Алгоритм ' + strategyID);
|
||||
//data.addColumn('number', 'Алгоритм 2');
|
||||
//data.addColumn('number', 'Алгоритм 3');
|
||||
|
||||
console.log(rows)
|
||||
|
||||
data.addRows(rows)
|
||||
|
||||
var options = {
|
||||
chart: {
|
||||
title: 'Кривая доходности',
|
||||
},
|
||||
width: 900,
|
||||
height: 500
|
||||
};
|
||||
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
|
||||
|
||||
//chart.draw(data, google.charts.Line.convertOptions(options));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
605
static/tennis.js
Normal file
605
static/tennis.js
Normal file
@@ -0,0 +1,605 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
Football = 1
|
||||
Handball = 2
|
||||
Tennis = 3
|
||||
|
||||
OnexbetFootball = 1
|
||||
OnexbetHandball = 8
|
||||
OnexbetTennis = 4
|
||||
|
||||
onexbetWsURL = 'ws://195.189.227.88:7772/ws'
|
||||
tipperWsURL = 'ws://195.189.227.88:7768/ws'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=> {
|
||||
interesting = new ListModel({
|
||||
template: {
|
||||
id: 'interestingMatch',
|
||||
renders: {
|
||||
interestingMatch: (tags, match) => {
|
||||
//console.log('render', match)
|
||||
let radios = new RadioList({
|
||||
container: tags.candidates,
|
||||
templateId: 'candidate-item',
|
||||
setEmptyMessage: 'нет матчей кандидатов'
|
||||
})
|
||||
|
||||
tags.flashscoreLink.href= `https://www.flashscore.com/match/${match.matchID}/#match-summary/match-summary`
|
||||
|
||||
tags.search.addEventListener('click', () => {
|
||||
let teamName = tags.teamName.value.trim()
|
||||
|
||||
if (teamName == '') {
|
||||
return
|
||||
}
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidatesByTeamName',
|
||||
data: {
|
||||
sportID: Tennis,
|
||||
teamName: teamName,
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
radios.clear()
|
||||
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.submit.addEventListener('click', () => {
|
||||
//console.log(radios.getSelected())
|
||||
let candidate = radios.getSelected()
|
||||
if (!candidate) {
|
||||
return
|
||||
}
|
||||
|
||||
let isReverse = tags.isReverse.checked
|
||||
|
||||
var home, away;
|
||||
|
||||
if (isReverse) {
|
||||
home = {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
away = {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.home
|
||||
}
|
||||
} else {
|
||||
home = {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.home
|
||||
}
|
||||
away = {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
}
|
||||
|
||||
console.log('home:', home);
|
||||
console.log('away:', away);
|
||||
|
||||
api.req({
|
||||
func: 'addTeamsAliases',
|
||||
data: {
|
||||
home: home,
|
||||
away: away
|
||||
},
|
||||
onError: err => {
|
||||
//tags.candidates.textContent = 'FUCK: ' + err
|
||||
console.log(err)
|
||||
},
|
||||
onSuccess: resp => {
|
||||
//console.log('ok')
|
||||
//tags.identification.click()
|
||||
radios.clear()
|
||||
tags.isReverse.checked = false
|
||||
tags.candidates.textContent = "Алиасы добавлены!"
|
||||
tags.submit.disabled = true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.identification.addEventListener('click', () => {
|
||||
//console.log('details:', tags.identification.open)
|
||||
//console.log(match)
|
||||
if (tags.identification.open) {
|
||||
//tags.candidates.innerHTML = ''
|
||||
} else {
|
||||
//tags.candidates.innerHTML = ''
|
||||
radios.clear()
|
||||
|
||||
//radios.setList([
|
||||
// {home: 'Arsenal', away: 'Mancity', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
// {home: 'Arsenal', away: 'Aston villa', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
//])
|
||||
|
||||
//tags.candidates.textContent = JSON.stringify(match)
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidates',
|
||||
data: {
|
||||
sportID: Tennis,
|
||||
home: match.home.canonicalName,
|
||||
away: match.away.canonicalName
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'interesting',
|
||||
preFunc: modifyInterestingMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// ONEXBET
|
||||
|
||||
//1xbet
|
||||
bookLiveModel = new ListModel({
|
||||
template: {
|
||||
id: 'liveMatch',
|
||||
},
|
||||
container: 'book-live',
|
||||
preFunc: modifyLiveMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// tips
|
||||
|
||||
tipModel = new ListModel({
|
||||
template: {
|
||||
id: 'tip',
|
||||
renders: {
|
||||
tip: (tags, tip) => {
|
||||
//console.log('tags:', tags)
|
||||
//console.log('x:', x)
|
||||
if (tip.status == 1) {
|
||||
tags.matchName.classList.add('profit')
|
||||
} else if (tip.status == 2) {
|
||||
tags.matchName.classList.add('errmsg')
|
||||
} else if (tip.status == 3) {
|
||||
tags.matchName.classList.add('void')
|
||||
}
|
||||
|
||||
tags.flashscoreLink.href= `https://www.flashscore.com/match/${tip.matchID}/#match-summary/match-summary`
|
||||
|
||||
tags.setResultLink.addEventListener('click', () => {
|
||||
if (tags.setResultForm.hidden) {
|
||||
let f = new Form({
|
||||
formContainer: tags.setResultForm,
|
||||
schema: [
|
||||
{
|
||||
name: 'result',
|
||||
type: 'line',
|
||||
label: 'Результат',
|
||||
comment: 'например, 1й тайм: 1:1'
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
type: 'radios',
|
||||
label: ' ',
|
||||
getName: x => x.name,
|
||||
data: [
|
||||
{name: 'Выигрыш', status: 1},
|
||||
{name: 'Проигрыш', status: 2},
|
||||
{name: 'Возврат', status: 3},
|
||||
]
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
f.onSubmit((obj) => {
|
||||
obj.tipID = tip.tipID
|
||||
//console.log(obj)
|
||||
api.req({
|
||||
func: 'setTipResult',
|
||||
data: obj,
|
||||
onError: err => {
|
||||
f.showError(err)
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Перезагружаем список
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Tennis,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
f.init()
|
||||
|
||||
tags.setResultForm.hidden = false
|
||||
} else {
|
||||
tags.setResultForm.hidden = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'tips',
|
||||
preFunc: modifyTip,
|
||||
sort: {
|
||||
key: 'tipTime',
|
||||
//reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// strategies
|
||||
|
||||
strategiesModel = new ListModel({
|
||||
template: {
|
||||
id: 'strategy',
|
||||
},
|
||||
container: 'strategies',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
totalsModel = new ListModel({
|
||||
template: {
|
||||
id: 'total',
|
||||
},
|
||||
container: 'totals',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
let onexbetWs = new WebsocketClient({
|
||||
url: onexbetWsURL
|
||||
})
|
||||
|
||||
onexbetWs.handle('liveMatches', resp => {
|
||||
//console.log('liveMatches:', resp)
|
||||
|
||||
if (resp.sportID == OnexbetTennis) {
|
||||
if (Array.isArray(resp.matches)) {
|
||||
bookLiveModel.setList(resp.matches)
|
||||
|
||||
resp.matches.forEach(match => {
|
||||
//console.log('partialUpdateBy')
|
||||
interesting.partialUpdateBy(
|
||||
// update func
|
||||
(tags, obj) => {
|
||||
//console.log('SCORE: ', tennisScoreToString(match.scoreByPeriods))
|
||||
tags.livescore.textContent = tennisScoreToString(match.scoreByPeriods)
|
||||
tags.livescore.hidden = false
|
||||
},
|
||||
// key func
|
||||
(obj) => {
|
||||
//console.log('COMPARE:', obj.onexbetMatchID, '=', match.matchID)
|
||||
if (obj.onexbetMatchID == match.matchID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.handle('teamLiveMatchData', resp => {
|
||||
//console.log('teamLiveMatchData:', resp)
|
||||
})
|
||||
|
||||
|
||||
// tipper
|
||||
let tipperWs = new WebsocketClient({
|
||||
url: tipperWsURL
|
||||
})
|
||||
|
||||
tipperWs.onConnected = () => {
|
||||
tipperWs.send('subscribe', {channels: ['tennis']})
|
||||
}
|
||||
|
||||
tipperWs.handle('teamMatches', resp => {
|
||||
//console.log('reports:', resp)
|
||||
if (resp.sportID == Tennis) {
|
||||
if (Array.isArray(resp.matches)) {
|
||||
//console.log('set interesting:', resp.matches)
|
||||
interesting.setList(resp.matches)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
tipperWs.handle('tipsChanged', resp => {
|
||||
//console.log('tip:', resp)
|
||||
|
||||
//tipModel.add(resp)
|
||||
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Tennis,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
data: Tennis,
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(filterStrategies(resp))
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tipperWs.handle('whyNot', resp => {
|
||||
//console.log('whyNot:', resp.matchID, resp.comment)
|
||||
interesting.partialUpdateBy(
|
||||
(tags, obj) => {
|
||||
tags.comment.innerHTML = resp.comment
|
||||
tags.time.textContent = resp.time
|
||||
tags.score.textContent = `${resp.homeGoals} - ${resp.awayGoals}`
|
||||
//tags.gamePace.textContent = resp.gamePace
|
||||
//tags.gamePaceFrame.textContent = resp.gamePaceFrame + 1
|
||||
},
|
||||
(obj) => {
|
||||
if (obj.matchID == resp.matchID) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tipperWs.handle('inplayStatusChanged', resp => {
|
||||
//console.log('inplayStatusChanged:', resp)
|
||||
interesting.partialUpdateBy(
|
||||
(tags, obj) => {
|
||||
if (resp.isInplay) {
|
||||
tags.isInplay.textContent = 'inplay'
|
||||
} else {
|
||||
tags.isInplay.textContent = ''
|
||||
}
|
||||
|
||||
if (resp.isLinkedToOnexbet) {
|
||||
tags.isLinked.textContent = 'linked to 1xBet'
|
||||
} else {
|
||||
tags.isLinked.textContent = ''
|
||||
}
|
||||
},
|
||||
(obj) => {
|
||||
if (obj.matchID == resp.matchID) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
ws.handle('footballMatchReports', resp => {
|
||||
console.log('reports:', resp)
|
||||
updateChamp(resp)
|
||||
})
|
||||
*/
|
||||
|
||||
api.req({
|
||||
func: 'listSportTips',
|
||||
data: Tennis,
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
data: Tennis,
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(filterStrategies(resp))
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.connect()
|
||||
tipperWs.connect()
|
||||
|
||||
})
|
||||
|
||||
|
||||
function showTotal(reports) {
|
||||
// 1,2,3
|
||||
let allChampsTotal = {
|
||||
name: 'Все чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
/*
|
||||
let topChampsTotal = {
|
||||
name: 'Топ чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
|
||||
let myTotal = {
|
||||
name: 'Алгоритмы от Программиста',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
*/
|
||||
let m = new Map()
|
||||
|
||||
m.set(15, allChampsTotal)
|
||||
m.set(16, allChampsTotal)
|
||||
m.set(17, allChampsTotal)
|
||||
m.set(18, allChampsTotal)
|
||||
|
||||
if (Array.isArray(reports)) {
|
||||
reports.forEach(r => {
|
||||
let total = m.get(r.strategyID)
|
||||
if (!total) {
|
||||
return
|
||||
}
|
||||
|
||||
total.wonTips += r.wonTips
|
||||
total.lostTips += r.lostTips
|
||||
total.profit += r.profit
|
||||
total.turnover += r.turnover
|
||||
})
|
||||
}
|
||||
|
||||
clacROIandAccuracy(allChampsTotal)
|
||||
//clacROIandAccuracy(topChampsTotal)
|
||||
//clacROIandAccuracy(myTotal)
|
||||
|
||||
|
||||
//totalsModel.setList([allChampsTotal, topChampsTotal, myTotal])
|
||||
totalsModel.setList([allChampsTotal])
|
||||
|
||||
//document.getElementById('total').textContent = 'Общий итог: ' + total + ' грн'
|
||||
}
|
||||
|
||||
function clacROIandAccuracy(total) {
|
||||
total.roi = (total.profit * 100) / total.turnover
|
||||
total.accuracy = (total.wonTips * 100) / (total.wonTips + total.lostTips)
|
||||
|
||||
//total.roi = Math.round(total.roi*100)/100
|
||||
//total.accuracy = Math.round(total.accuracy*100)/100
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function modifyReport(report) {
|
||||
report.match = `${report.home.canonicalName} - ${report.away.canonicalName}`
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
|
||||
function modifyInterestingMatch(report) {
|
||||
//console.log(report)
|
||||
|
||||
report.champName = `${report.zone.name}. ${report.champ.name}`
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
let home = report.home.canonicalName
|
||||
if (!report.home.wasLinked) {
|
||||
home = '*' + home
|
||||
}
|
||||
let away = report.away.canonicalName
|
||||
if (!report.away.wasLinked) {
|
||||
away = '*' + away
|
||||
}
|
||||
report.match = `${home} - ${away}`
|
||||
if (report.isLinkedToOnexbet) {
|
||||
report.isLinked = 'linked to 1xBet'
|
||||
}
|
||||
if (report.isInplay) {
|
||||
report.isInplay = 'inplay'
|
||||
} else {
|
||||
report.isInplay = ''
|
||||
}
|
||||
report.notes = JSON.stringify(report, null, 3)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function modifyLiveMatch(report) {
|
||||
if (!report.match) {
|
||||
report.champName = `${report.sportName}. ${report.champName}`
|
||||
}
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
report.match = `${report.home} - ${report.away}`
|
||||
}
|
||||
|
||||
function modifyTip(report) {
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
function filterStrategies(src) {
|
||||
let list = []
|
||||
if (Array.isArray(src)) {
|
||||
src.forEach(s => {
|
||||
list.push(s)
|
||||
})
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
function tennisScoreToString(scoreByPeriods) {
|
||||
if (!scoreByPeriods) {
|
||||
return ''
|
||||
}
|
||||
|
||||
let list = []
|
||||
|
||||
for (var i=1; i <= 5; i++) {
|
||||
let p = scoreByPeriods[i]
|
||||
if (p) {
|
||||
list.push(`${p.home}:${p.away}`)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return list.join(' ')
|
||||
}
|
||||
77
static/tipper.css
Executable file
77
static/tipper.css
Executable file
@@ -0,0 +1,77 @@
|
||||
body {
|
||||
font-family: 'Ubuntu';
|
||||
}
|
||||
|
||||
.matches {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.champ {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: antiquewhite;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
summary {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
#main {
|
||||
display: flex;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
#main div {
|
||||
margin-right: 15px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.sport-menu {
|
||||
padding-left: 45px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.interesting-title {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: #ff99cc;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
|
||||
.book-live {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: #99ccff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.tips {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: #99ffcc;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.strategies {
|
||||
margin: 15px 0;
|
||||
padding: 15px;
|
||||
background-color: gold;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.errmsg {
|
||||
/*color: red;*/
|
||||
color: #ff4040;
|
||||
}
|
||||
|
||||
.profit {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.void {
|
||||
color: #039be5;
|
||||
}
|
||||
789
static/tipper.js
Executable file
789
static/tipper.js
Executable file
@@ -0,0 +1,789 @@
|
||||
let u = new URL(location.href)
|
||||
urlPrivateAPI = u.origin + '/api'
|
||||
|
||||
api = new API({
|
||||
url: urlPrivateAPI,
|
||||
timeout: 10000, // 10 sec
|
||||
})
|
||||
|
||||
Football = 1
|
||||
Handball = 2
|
||||
|
||||
flashscoreWsURL = 'ws://195.189.227.88:5757/ws'
|
||||
onexbetWsURL = 'ws://195.189.227.88:5758/ws'
|
||||
tipperWsURL = 'ws://195.189.227.88:5759/ws'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', ()=> {
|
||||
totalsModel = new ListModel({
|
||||
template: {
|
||||
id: 'total',
|
||||
},
|
||||
container: 'totals',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
spa = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'spa',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
spa2 = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'spa2',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
eng = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'eng',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
eng2 = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'eng2',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
ger = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'ger',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
ita = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'ita',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
ita2 = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'ita2',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
por = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'por',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
ukr = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'ukr',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
swi = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'swi',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
tur = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'tur',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
rus = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'rus',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
rom = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'rom',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
mon = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'mon',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
bel = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'bel',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
gre = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'gre',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
che = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'che',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
cro = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'cro',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
den = new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: 'den',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
/*
|
||||
= new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: '',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
= new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: '',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
= new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: '',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
|
||||
|
||||
= new ListModel({
|
||||
template: {
|
||||
id: 'report',
|
||||
},
|
||||
container: '',
|
||||
preFunc: modifyReport,
|
||||
})
|
||||
*/
|
||||
|
||||
|
||||
//1xbet
|
||||
bookLiveModel = new ListModel({
|
||||
template: {
|
||||
id: 'liveMatch',
|
||||
},
|
||||
container: 'book-live',
|
||||
preFunc: modifyLiveMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// tips
|
||||
|
||||
tipModel = new ListModel({
|
||||
template: {
|
||||
id: 'tip',
|
||||
renders: {
|
||||
tip: (tags, tip) => {
|
||||
//console.log('tags:', tags)
|
||||
//console.log('x:', x)
|
||||
if (tip.status == 1) {
|
||||
tags.matchName.classList.add('profit')
|
||||
} else if (tip.status == 2) {
|
||||
tags.matchName.classList.add('errmsg')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'tips',
|
||||
preFunc: modifyTip,
|
||||
sort: {
|
||||
key: 'tipTime',
|
||||
//reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// strategies
|
||||
|
||||
strategiesModel = new ListModel({
|
||||
template: {
|
||||
id: 'strategy',
|
||||
},
|
||||
container: 'strategies',
|
||||
preFunc: (r) => {
|
||||
r.roi = Math.round(r.roi*100)/100
|
||||
r.profit = Math.round(r.profit*100)/100
|
||||
r.drawdown = Math.round(r.drawdown*100)/100
|
||||
r.accuracy = Math.round(r.accuracy*100)/100
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
// flashscore
|
||||
let ws = new WebsocketClient({
|
||||
//url: 'ws://localhost:5757/ws'
|
||||
//url: 'ws://167.99.157.181:5757/ws'
|
||||
url: flashscoreWsURL
|
||||
})
|
||||
|
||||
//ws.onconnected =
|
||||
|
||||
ws.handle('footballChamps', resp => {
|
||||
console.log('champs:', resp)
|
||||
if (Array.isArray(resp.Champs)) {
|
||||
//console.log('array')
|
||||
resp.Champs.forEach(champ => {
|
||||
console.log(champ)
|
||||
updateChamp(champ)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
ws.handle('footballMatchReports', resp => {
|
||||
console.log('reports:', resp)
|
||||
if (resp) {
|
||||
updateChamp(resp)
|
||||
}
|
||||
})
|
||||
|
||||
interesting = new ListModel({
|
||||
template: {
|
||||
id: 'interestingMatch',
|
||||
renders: {
|
||||
interestingMatch: (tags, match) => {
|
||||
let radios = new RadioList({
|
||||
container: tags.candidates,
|
||||
templateId: 'candidate-item',
|
||||
setEmptyMessage: 'нет матчей кандидатов'
|
||||
})
|
||||
|
||||
tags.search.addEventListener('click', () => {
|
||||
let teamName = tags.teamName.value.trim()
|
||||
|
||||
if (teamName == '') {
|
||||
return
|
||||
}
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidatesByTeamName',
|
||||
data: {
|
||||
sportID: Football,
|
||||
teamName: teamName
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
radios.clear()
|
||||
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.submit.addEventListener('click', () => {
|
||||
//console.log(radios.getSelected())
|
||||
let candidate = radios.getSelected()
|
||||
if (!candidate) {
|
||||
return
|
||||
}
|
||||
api.req({
|
||||
func: 'addTeamsAliases',
|
||||
data: {
|
||||
home: {
|
||||
teamID: match.home.teamID,
|
||||
name: candidate.home
|
||||
},
|
||||
away: {
|
||||
teamID: match.away.teamID,
|
||||
name: candidate.away
|
||||
}
|
||||
|
||||
},
|
||||
onError: err => {
|
||||
//tags.candidates.textContent = 'FUCK: ' + err
|
||||
console.log(err)
|
||||
},
|
||||
onSuccess: resp => {
|
||||
//console.log('ok')
|
||||
//tags.identification.click()
|
||||
radios.clear()
|
||||
tags.candidates.textContent = "Алиасы добавлены!"
|
||||
tags.submit.disabled = true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
tags.identification.addEventListener('click', () => {
|
||||
//console.log('details:', tags.identification.open)
|
||||
//console.log(match)
|
||||
if (tags.identification.open) {
|
||||
//tags.candidates.innerHTML = ''
|
||||
} else {
|
||||
//tags.candidates.innerHTML = ''
|
||||
radios.clear()
|
||||
|
||||
//radios.setList([
|
||||
// {home: 'Arsenal', away: 'Mancity', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
// {home: 'Arsenal', away: 'Aston villa', sport: 'Football', champName: 'England. Premier League', startTimeStr: "Oct 06, 12:30:00"},
|
||||
//])
|
||||
|
||||
//tags.candidates.textContent = JSON.stringify(match)
|
||||
|
||||
api.req({
|
||||
func: 'searchMatchCandidates',
|
||||
data: {
|
||||
sportID: Football,
|
||||
home: match.home.canonicalName,
|
||||
away: match.away.canonicalName
|
||||
},
|
||||
onError: err => {
|
||||
console.log(err)
|
||||
tags.candidates.textContent = "FUCK: " + err
|
||||
},
|
||||
onSuccess: resp => {
|
||||
tags.submit.disabled = false
|
||||
console.log(resp)
|
||||
if (Array.isArray(resp)) {
|
||||
resp.forEach(candidate => {
|
||||
candidate.startTimeStr = moment(candidate.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
})
|
||||
}
|
||||
// show model + form
|
||||
radios.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
container: 'interesting',
|
||||
preFunc: modifyInterestingMatch,
|
||||
sort: {
|
||||
key: 'startTime',
|
||||
reverse: true
|
||||
}
|
||||
})
|
||||
|
||||
// 1xbet
|
||||
let onexbetWs = new WebsocketClient({
|
||||
//url: 'ws://localhost:5758/ws'
|
||||
//url: 'ws://167.99.157.181:5758/ws'
|
||||
url: onexbetWsURL
|
||||
})
|
||||
|
||||
onexbetWs.handle('liveMatches', resp => {
|
||||
console.log('liveMatches:', resp)
|
||||
|
||||
if (Array.isArray(resp.matches)) {
|
||||
bookLiveModel.setList(resp.matches)
|
||||
}
|
||||
})
|
||||
|
||||
onexbetWs.handle('liveMatchesUpdate', resp => {
|
||||
//console.log('liveMatchesUpdate:', resp)
|
||||
let list = bookLiveModel.getList()
|
||||
|
||||
let removeMap = {}
|
||||
if (resp.removedMatchIDs) {
|
||||
resp.removedMatchIDs.forEach(matchID => {
|
||||
removeMap[matchID] = true
|
||||
})
|
||||
}
|
||||
|
||||
let newList = []
|
||||
|
||||
list.forEach(old => {
|
||||
if (removeMap[old.matchID] === true) {
|
||||
return
|
||||
} else {
|
||||
newList.push(old)
|
||||
}
|
||||
})
|
||||
|
||||
if (Array.isArray(resp.addedMatches)) {
|
||||
resp.addedMatches.forEach(newMatch => {
|
||||
newList.push(newMatch)
|
||||
})
|
||||
}
|
||||
|
||||
bookLiveModel.setList(newList)
|
||||
})
|
||||
|
||||
onexbetWs.handle('footballLiveMatchData', resp => {
|
||||
//console.log('footballLiveMatchData:', resp)
|
||||
})
|
||||
|
||||
|
||||
// tipper
|
||||
let tipperWs = new WebsocketClient({
|
||||
// url: 'ws://localhost:5759/ws'
|
||||
// url: 'ws://167.99.157.181:5759/ws'
|
||||
url: tipperWsURL
|
||||
})
|
||||
|
||||
tipperWs.handle('interestingFootballMatches', resp => {
|
||||
console.log('interesting matches:', resp)
|
||||
|
||||
if (Array.isArray(resp.matches)) {
|
||||
interesting.setList(resp.matches)
|
||||
}
|
||||
})
|
||||
|
||||
tipperWs.handle('tipsChanged', resp => {
|
||||
//console.log('tip:', resp)
|
||||
|
||||
//tipModel.add(resp)
|
||||
|
||||
api.req({
|
||||
func: 'listTips',
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(resp)
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
ws.handle('footballMatchReports', resp => {
|
||||
console.log('reports:', resp)
|
||||
updateChamp(resp)
|
||||
})
|
||||
*/
|
||||
ws.connect()
|
||||
onexbetWs.connect()
|
||||
tipperWs.connect()
|
||||
|
||||
api.req({
|
||||
func: 'listTips',
|
||||
onSuccess: resp => {
|
||||
tipModel.setList(resp)
|
||||
}
|
||||
})
|
||||
|
||||
api.req({
|
||||
func: 'listStrategiesReports',
|
||||
onSuccess: resp => {
|
||||
strategiesModel.setList(resp)
|
||||
showTotal(resp)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function showTotal(reports) {
|
||||
// 1,2,3
|
||||
let allChampsTotal = {
|
||||
name: 'Все чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
/*
|
||||
let topChampsTotal = {
|
||||
name: 'Топ чемпионаты',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
|
||||
let myTotal = {
|
||||
name: 'Алгоритмы от Программиста',
|
||||
wonTips: 0,
|
||||
lostTips: 0,
|
||||
accuracy: 0,
|
||||
profit: 0,
|
||||
turnover: 0,
|
||||
roi: 0
|
||||
}
|
||||
*/
|
||||
let m = new Map()
|
||||
|
||||
m.set(1, allChampsTotal)
|
||||
m.set(2, allChampsTotal)
|
||||
m.set(3, allChampsTotal)
|
||||
|
||||
/*
|
||||
m.set(11, topChampsTotal)
|
||||
m.set(22, topChampsTotal)
|
||||
m.set(33, topChampsTotal)
|
||||
|
||||
m.set(701, myTotal)
|
||||
m.set(702, myTotal)
|
||||
m.set(703, myTotal)
|
||||
*/
|
||||
|
||||
let total = 0
|
||||
if (Array.isArray(reports)) {
|
||||
reports.forEach(r => {
|
||||
let total = m.get(r.strategyID)
|
||||
if (!total) {
|
||||
return
|
||||
}
|
||||
|
||||
total.wonTips += r.wonTips
|
||||
total.lostTips += r.lostTips
|
||||
total.profit += r.profit
|
||||
total.turnover += r.turnover
|
||||
})
|
||||
}
|
||||
|
||||
clacROIandAccuracy(allChampsTotal)
|
||||
//clacROIandAccuracy(topChampsTotal)
|
||||
//clacROIandAccuracy(myTotal)
|
||||
|
||||
|
||||
//totalsModel.setList([allChampsTotal, topChampsTotal, myTotal])
|
||||
totalsModel.setList([allChampsTotal])
|
||||
|
||||
//document.getElementById('total').textContent = 'Общий итог: ' + total + ' грн'
|
||||
}
|
||||
|
||||
function clacROIandAccuracy(total) {
|
||||
total.roi = (total.profit * 100) / total.turnover
|
||||
total.accuracy = (total.wonTips * 100) / (total.wonTips + total.lostTips)
|
||||
|
||||
//total.roi = Math.round(total.roi*100)/100
|
||||
//total.accuracy = Math.round(total.accuracy*100)/100
|
||||
}
|
||||
|
||||
function updateChamp(champ) {
|
||||
if (!champ.Champ) {
|
||||
return
|
||||
}
|
||||
let lastSync = moment(champ.LastSync * 1000).format("MMM DD, HH:mm:ss")
|
||||
|
||||
switch (champ.Champ.champID) {
|
||||
case "/england/premier-league":
|
||||
document.getElementById('engLastSync').textContent = lastSync
|
||||
eng.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/germany/bundesliga":
|
||||
document.getElementById('gerLastSync').textContent = lastSync
|
||||
ger.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/italy/serie-a":
|
||||
document.getElementById('itaLastSync').textContent = lastSync
|
||||
ita.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/spain/laliga":
|
||||
document.getElementById('spaLastSync').textContent = lastSync
|
||||
spa.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/ukraine/premier-league":
|
||||
document.getElementById('ukrLastSync').textContent = lastSync
|
||||
ukr.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/portugal/primeira-liga":
|
||||
document.getElementById('porLastSync').textContent = lastSync
|
||||
por.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/switzerland/super-league":
|
||||
document.getElementById('swiLastSync').textContent = lastSync
|
||||
swi.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/turkey/super-lig":
|
||||
document.getElementById('turLastSync').textContent = lastSync
|
||||
tur.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/russia/premier-league":
|
||||
document.getElementById('rusLastSync').textContent = lastSync
|
||||
rus.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/belarus/vysshaya-liga":
|
||||
document.getElementById('belLastSync').textContent = lastSync
|
||||
bel.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/greece/super-league":
|
||||
document.getElementById('greLastSync').textContent = lastSync
|
||||
gre.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/montenegro/prva-crnogorska-liga":
|
||||
document.getElementById('monLastSync').textContent = lastSync
|
||||
mon.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/romania/liga-1":
|
||||
document.getElementById('romLastSync').textContent = lastSync
|
||||
rom.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/croatia/1-hnl":
|
||||
document.getElementById('croLastSync').textContent = lastSync
|
||||
cro.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/czech-republic/1-liga":
|
||||
document.getElementById('cheLastSync').textContent = lastSync
|
||||
che.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/denmark/superliga":
|
||||
document.getElementById('denLastSync').textContent = lastSync
|
||||
den.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/england/championship":
|
||||
document.getElementById('eng2LastSync').textContent = lastSync
|
||||
eng2.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/italy/serie-b":
|
||||
document.getElementById('ita2LastSync').textContent = lastSync
|
||||
ita2.setList(champ.Reports)
|
||||
break
|
||||
|
||||
case "/spain/laliga2":
|
||||
document.getElementById('spa2LastSync').textContent = lastSync
|
||||
spa2.setList(champ.Reports)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function modifyReport(report) {
|
||||
report.match = `${report.Home.canonicalName} - ${report.Away.canonicalName}`
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
|
||||
function modifyInterestingMatch(report) {
|
||||
report.champName = `${report.zone.name}. ${report.champ.name}`
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
let home = report.home.canonicalName
|
||||
if (!report.home.wasLinked) {
|
||||
home = '*' + home
|
||||
}
|
||||
let away = report.away.canonicalName
|
||||
if (!report.away.wasLinked) {
|
||||
away = '*' + away
|
||||
}
|
||||
report.match = `${home} - ${away}`
|
||||
if (report.isLinkedToOnexbet) {
|
||||
report.isLinked = 'linked to 1xBet'
|
||||
}
|
||||
if (report.isInplay) {
|
||||
report.isInplay = 'inplay'
|
||||
} else {
|
||||
report.isInplay = ''
|
||||
}
|
||||
report.notes = JSON.stringify(report.notes, null, 3)
|
||||
}
|
||||
|
||||
|
||||
function modifyLiveMatch(report) {
|
||||
if (!report.match) {
|
||||
report.champName = `${report.sportName}. ${report.champName}`
|
||||
}
|
||||
report.startTimeStr = moment(report.startTime * 1000).format("MMM DD, HH:mm:ss")
|
||||
report.match = `${report.home} - ${report.away}`
|
||||
}
|
||||
|
||||
function modifyTip(report) {
|
||||
report.msg = JSON.stringify(report, null, 3)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user