Code:function transform(input) {
var outcomes = input.outcomes || [];
var items = [];
for (var i = 0; i < outcomes.length; i++) {
var o = outcomes[i];
if (o.isFallback || o.settled) continue;
if (o.class === 'priceBucket') continue;
var parsed = parseDescription(o.rawDescription || '', o);
if (!parsed) continue;
if (parsed.perSide) {
for (var s = 0; s < parsed.perSide.length; s++) {
var ps = parsed.perSide[s];
items.push({
outcomeIndex: o.outcomeIndex,
name: ps.name,
pmQuery: ps.query,
sides: o.sides.map(function(x) { return x.name; }),
sideIndex: s,
sideName: ps.sideName,
matchCriteria: ps.criteria,
marketType: 'sports'
});
}
} else if (parsed.query) {
items.push({
outcomeIndex: o.outcomeIndex,
name: parsed.name,
pmQuery: parsed.query,
sides: o.sides.map(function(x) { return x.name; }),
matchCriteria: parsed.criteria,
marketType: parsed.marketType
});
}
}
return { items: items, count: items.length };
}
function parseDescription(desc, o) {
if (desc.indexOf('CPI') >= 0) return parseCPI(desc, o);
if (desc.indexOf('federal funds rate') >= 0 || desc.indexOf('FOMC') >= 0) return parseFed(desc, o);
if (o.class === 'priceBinary' && o.underlying) return parsePriceBinary(desc, o);
var sportInfo = detectSport(desc, o);
if (sportInfo) return parseSports(desc, o, sportInfo);
return { name: o.name, query: o.name, marketType: 'unknown', criteria: { requiredKeywords: [], rejectedKeywords: [], metricType: 'unknown', threshold: null, direction: null, minLiquidity: 1000 } };
}
function detectSport(desc, o) {
var sports = [
{ kw: ['Champions League', 'UEFA', 'UCL'], event: 'Champions League', sport: 'football' },
{ kw: ['Premier League', 'EPL'], event: 'Premier League', sport: 'football' },
{ kw: ['La Liga'], event: 'La Liga', sport: 'football' },
{ kw: ['Serie A'], event: 'Serie A', sport: 'football' },
{ kw: ['Bundesliga'], event: 'Bundesliga', sport: 'football' },
{ kw: ['World Cup', 'FIFA'], event: 'World Cup', sport: 'football' },
{ kw: ['Europa League'], event: 'Europa League', sport: 'football' },
{ kw: ['NBA'], event: 'NBA', sport: 'basketball' },
{ kw: ['NFL', 'Super Bowl'], event: 'NFL', sport: 'american_football' },
{ kw: ['MLB'], event: 'MLB', sport: 'baseball' },
{ kw: ['NHL'], event: 'NHL', sport: 'hockey' },
{ kw: ['UFC', 'MMA'], event: 'UFC', sport: 'mma' },
{ kw: ['F1', 'Formula 1', 'Grand Prix'], event: 'Formula 1', sport: 'f1' },
{ kw: ['Wimbledon', 'Roland Garros', 'Australian Open'], event: 'tennis', sport: 'tennis' },
{ kw: ['boxing', 'bout'], event: 'boxing', sport: 'boxing' }
];
var text = (desc + ' ' + (o.name || '')).toLowerCase();
for (var i = 0; i < sports.length; i++) {
for (var j = 0; j < sports[i].kw.length; j++) {
if (text.indexOf(sports[i].kw[j].toLowerCase()) >= 0) return sports[i];
}
}
var genericSides = ['yes', 'no', 'above', 'below', 'exactly', 'change', 'no change'];
var sideNames = o.sides.map(function(s) { return s.name.toLowerCase(); });
var hasGeneric = false;
for (var k = 0; k < sideNames.length; k++) {
if (genericSides.indexOf(sideNames[k]) >= 0) { hasGeneric = true; break; }
}
if (!hasGeneric && sideNames.length >= 2) {
return { kw: [], event: o.name || desc.substring(0, 50), sport: 'unknown_sport' };
}
return null;
}
function parseSports(desc, o, sportInfo) {
var sideNames = o.sides.map(function(s) { return s.name; });
var perSide = [];
for (var i = 0; i < sideNames.length; i++) {
perSide.push({
name: sportInfo.event + ': ' + sideNames[i],
sideName: sideNames[i],
query: sideNames[i] + ' ' + sportInfo.event,
criteria: {
metricType: 'sports_side',
eventKeywords: sportInfo.kw,
sport: sportInfo.sport,
event: sportInfo.event,
minLiquidity: 1000
}
});
}
return { perSide: perSide };
}
function parseCPI(desc, o) {
var isHeadline = desc.indexOf('BLS CPI') >= 0 || desc.indexOf('headline') >= 0;
var metricLabel = isHeadline ? 'headline CPI' : 'CPI';
var threshMatch = desc.match(/(below|above|exactly|is)\s+([\d.]+)%/i);
var threshold = threshMatch ? parseFloat(threshMatch[2]) : null;
var direction = 'unknown';
var nl = o.name.toLowerCase();
if (nl.indexOf('below') >= 0 || desc.indexOf('is below') >= 0) direction = 'below';
else if (nl.indexOf('above') >= 0 || desc.indexOf('is above') >= 0) direction = 'above';
else if (nl.indexOf('exactly') >= 0 || desc.indexOf('is exactly') >= 0) direction = 'exactly';
var monthMatch = desc.match(/(January|February|March|April|May|June|July|August|September|October|November|December)\s+(\d{4})/i);
var month = monthMatch ? monthMatch[1] : '';
var year = monthMatch ? monthMatch[2] : '';
var query = metricLabel + ' YoY ' + (threshold ? threshold + ' percent ' : '') + month + ' ' + year;
return {
name: 'CPI: ' + o.name + ' (' + metricLabel + (threshold ? ' ' + threshold + '%' : '') + ')',
query: query.trim(),
marketType: 'cpi',
criteria: {
requiredKeywords: ['CPI'],
rejectedKeywords: isHeadline ? ['Core'] : [],
metricType: isHeadline ? 'headline_cpi' : 'core_cpi',
threshold: threshold,
direction: direction,
month: month,
year: year,
minLiquidity: 100,
exactlyPenalty: direction === 'exactly'
}
};
}
function parseFed(desc, o) {
var meetingMatch = desc.match(/(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d+(?:[\u2013-]\d+)?,?\s*(\d{4})/i);
var month = meetingMatch ? meetingMatch[1] : '';
var year = meetingMatch ? meetingMatch[2] : '';
var sideNames = o.sides.map(function(s) { return s.name.toLowerCase(); });
var isChange = sideNames.indexOf('change') >= 0;
return {
name: 'Fed: ' + o.name,
query: 'Fed rate ' + month + ' ' + year,
marketType: 'fed_rate',
criteria: {
requiredKeywords: ['Fed', 'rate'],
rejectedKeywords: [],
metricType: 'fed_rate',
threshold: null,
direction: isChange ? 'change' : 'no_change',
month: month,
year: year,
minLiquidity: 5000
}
};
}
function parsePriceBinary(desc, o) {
var underlying = o.underlying || '';
var target = o.targetPrice || 0;
var period = o.period || '';
return {
name: underlying + ' >= $' + (target || '?') + (period === '1d' ? ' (daily)' : ''),
query: underlying + ' price prediction',
marketType: 'price_binary',
criteria: {
requiredKeywords: [underlying],
rejectedKeywords: [],
metricType: 'price_binary',
threshold: target,
direction: 'above',
underlying: underlying,
period: period,
minLiquidity: 1000,
dailyBinaryPenalty: period === '1d'
}
};
}
Input:{"outcomes":"{{get_outcomes.result.outcomes}}"}