refactor: stars calculation moved to platforms
This commit is contained in:
parent
ac7b541896
commit
da03fa8804
|
@ -1,7 +1,6 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -26,7 +25,7 @@ async function processPredictions(predictions) {
|
||||||
let results = await predictions.map((prediction) => {
|
let results = await predictions.map((prediction) => {
|
||||||
const id = `${platformName}-${prediction.id}`;
|
const id = `${platformName}-${prediction.id}`;
|
||||||
const probability = prediction.probability;
|
const probability = prediction.probability;
|
||||||
const options = [
|
const options: FetchedQuestion["options"] = [
|
||||||
{
|
{
|
||||||
name: "Yes",
|
name: "Yes",
|
||||||
probability: probability,
|
probability: probability,
|
||||||
|
@ -45,9 +44,6 @@ async function processPredictions(predictions) {
|
||||||
description: prediction.description,
|
description: prediction.description,
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
stars: calculateStars(platformName, {
|
|
||||||
/* some: somex, factors: factors */
|
|
||||||
}),
|
|
||||||
// other: prediction.otherx,
|
// other: prediction.otherx,
|
||||||
// indicators: prediction.indicatorx,
|
// indicators: prediction.indicatorx,
|
||||||
},
|
},
|
||||||
|
@ -68,4 +64,7 @@ export const example: Platform = {
|
||||||
let results = await processPredictions(data); // somehow needed
|
let results = await processPredictions(data); // somehow needed
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
return 2;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import https from "https";
|
import https from "https";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
const platformName = "betfair";
|
const platformName = "betfair";
|
||||||
|
@ -121,17 +121,13 @@ async function processPredictions(data) {
|
||||||
if (title.includes("of the named")) {
|
if (title.includes("of the named")) {
|
||||||
title = prediction.marketName + ": " + title;
|
title = prediction.marketName + ": " + title;
|
||||||
}
|
}
|
||||||
const result = {
|
const result: FetchedQuestion = {
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
url: `https://www.betfair.com/exchange/plus/politics/market/${prediction.marketId}`,
|
url: `https://www.betfair.com/exchange/plus/politics/market/${prediction.marketId}`,
|
||||||
platform: platformName,
|
|
||||||
description,
|
description,
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
stars: calculateStars(platformName, {
|
|
||||||
volume: prediction.totalMatched,
|
|
||||||
}),
|
|
||||||
volume: prediction.totalMatched,
|
volume: prediction.totalMatched,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -149,4 +145,25 @@ export const betfair: Platform = {
|
||||||
const results = await processPredictions(data); // somehow needed
|
const results = await processPredictions(data); // somehow needed
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
const volume = data.qualityindicators.volume || 0;
|
||||||
|
let nuno = () => (volume > 10000 ? 4 : volume > 1000 ? 3 : 2);
|
||||||
|
let eli = () => (volume > 10000 ? null : null);
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
|
||||||
|
const firstOption = data.options[0];
|
||||||
|
|
||||||
|
// Substract 1 star if probability is above 90% or below 10%
|
||||||
|
if (
|
||||||
|
firstOption &&
|
||||||
|
((firstOption.probability || 0) < 0.1 ||
|
||||||
|
(firstOption.probability || 0) > 0.9)
|
||||||
|
) {
|
||||||
|
starsDecimal = starsDecimal - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
const platformName = "fantasyscotus";
|
const platformName = "fantasyscotus";
|
||||||
|
@ -100,7 +99,6 @@ async function processData(data) {
|
||||||
],
|
],
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
numforecasts: Number(predictionData.numForecasts),
|
numforecasts: Number(predictionData.numForecasts),
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
results.push(eventObject);
|
results.push(eventObject);
|
||||||
|
@ -120,4 +118,7 @@ export const fantasyscotus: Platform = {
|
||||||
let results = await processData(rawData);
|
let results = await processData(rawData);
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
return 2;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -68,7 +68,8 @@ export const foretold: Platform = {
|
||||||
questions = questions.filter((question) => question.previousAggregate); // Questions without any predictions
|
questions = questions.filter((question) => question.previousAggregate); // Questions without any predictions
|
||||||
questions.forEach((question) => {
|
questions.forEach((question) => {
|
||||||
let id = `${platformName}-${question.id}`;
|
let id = `${platformName}-${question.id}`;
|
||||||
let options = [];
|
|
||||||
|
let options: FetchedQuestion["options"] = [];
|
||||||
if (question.valueType == "PERCENTAGE") {
|
if (question.valueType == "PERCENTAGE") {
|
||||||
let probability = question.previousAggregate.value.percentage;
|
let probability = question.previousAggregate.value.percentage;
|
||||||
options = [
|
options = [
|
||||||
|
@ -84,6 +85,7 @@ export const foretold: Platform = {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: FetchedQuestion = {
|
const result: FetchedQuestion = {
|
||||||
id,
|
id,
|
||||||
title: question.name,
|
title: question.name,
|
||||||
|
@ -92,7 +94,6 @@ export const foretold: Platform = {
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
numforecasts: Math.floor(Number(question.measurementCount) / 2),
|
numforecasts: Math.floor(Number(question.measurementCount) / 2),
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
},
|
},
|
||||||
/*liquidity: liquidity.toFixed(2),
|
/*liquidity: liquidity.toFixed(2),
|
||||||
tradevolume: tradevolume.toFixed(2),
|
tradevolume: tradevolume.toFixed(2),
|
||||||
|
@ -104,4 +105,12 @@ export const foretold: Platform = {
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 2;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { Platform } from "./";
|
import { Platform } from "./";
|
||||||
|
|
||||||
const platformName = "givewellopenphil";
|
const platformName = "givewellopenphil";
|
||||||
|
@ -53,9 +53,7 @@ async function main1() {
|
||||||
platform: platformName,
|
platform: platformName,
|
||||||
description,
|
description,
|
||||||
options: [],
|
options: [],
|
||||||
qualityindicators: {
|
qualityindicators: {},
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
},
|
|
||||||
}; // Note: This requires some processing afterwards
|
}; // Note: This requires some processing afterwards
|
||||||
// console.log(result)
|
// console.log(result)
|
||||||
results.push(result);
|
results.push(result);
|
||||||
|
@ -84,4 +82,12 @@ export const givewellopenphil: Platform = {
|
||||||
}));
|
}));
|
||||||
return dataWithDate;
|
return dataWithDate;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 2;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,8 +3,8 @@ import axios from "axios";
|
||||||
import { Tabletojson } from "tabletojson";
|
import { Tabletojson } from "tabletojson";
|
||||||
import tunnel from "tunnel";
|
import tunnel from "tunnel";
|
||||||
|
|
||||||
|
import { average } from "../../utils";
|
||||||
import { hash } from "../utils/hash";
|
import { hash } from "../utils/hash";
|
||||||
import { calculateStars } from "../utils/stars";
|
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -103,9 +103,7 @@ export const goodjudgment: Platform = {
|
||||||
url: endpoint,
|
url: endpoint,
|
||||||
description,
|
description,
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {},
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
},
|
|
||||||
extra: {
|
extra: {
|
||||||
superforecastercommentary: analysis || "",
|
superforecastercommentary: analysis || "",
|
||||||
},
|
},
|
||||||
|
@ -120,4 +118,12 @@ export const goodjudgment: Platform = {
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 4;
|
||||||
|
let eli = () => 4;
|
||||||
|
let misha = () => 3.5;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { Tabletojson } from "tabletojson";
|
import { Tabletojson } from "tabletojson";
|
||||||
|
|
||||||
|
import { average } from "../../utils";
|
||||||
import { applyIfSecretExists } from "../utils/getSecrets";
|
import { applyIfSecretExists } from "../utils/getSecrets";
|
||||||
import { calculateStars } from "../utils/stars";
|
|
||||||
import toMarkdown from "../utils/toMarkdown";
|
import toMarkdown from "../utils/toMarkdown";
|
||||||
import { Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
const platformName = "goodjudgmentopen";
|
const platformName = "goodjudgmentopen";
|
||||||
|
|
||||||
let htmlEndPoint = "https://www.gjopen.com/questions?page=";
|
const htmlEndPoint = "https://www.gjopen.com/questions?page=";
|
||||||
let annoyingPromptUrls = [
|
const annoyingPromptUrls = [
|
||||||
"https://www.gjopen.com/questions/1933-what-forecasting-questions-should-we-ask-what-questions-would-you-like-to-forecast-on-gjopen",
|
"https://www.gjopen.com/questions/1933-what-forecasting-questions-should-we-ask-what-questions-would-you-like-to-forecast-on-gjopen",
|
||||||
"https://www.gjopen.com/questions/1779-are-there-any-forecasting-tips-tricks-and-experiences-you-would-like-to-share-and-or-discuss-with-your-fellow-forecasters",
|
"https://www.gjopen.com/questions/1779-are-there-any-forecasting-tips-tricks-and-experiences-you-would-like-to-share-and-or-discuss-with-your-fellow-forecasters",
|
||||||
"https://www.gjopen.com/questions/2246-are-there-any-forecasting-tips-tricks-and-experiences-you-would-like-to-share-and-or-discuss-with-your-fellow-forecasters-2022-thread",
|
"https://www.gjopen.com/questions/2246-are-there-any-forecasting-tips-tricks-and-experiences-you-would-like-to-share-and-or-discuss-with-your-fellow-forecasters-2022-thread",
|
||||||
|
@ -22,7 +22,7 @@ const id = () => 0;
|
||||||
|
|
||||||
/* Support functions */
|
/* Support functions */
|
||||||
|
|
||||||
async function fetchPage(page, cookie) {
|
async function fetchPage(page: number, cookie: string) {
|
||||||
let response = await axios({
|
let response = await axios({
|
||||||
url: htmlEndPoint + page,
|
url: htmlEndPoint + page,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
@ -35,7 +35,7 @@ async function fetchPage(page, cookie) {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchStats(questionUrl, cookie) {
|
async function fetchStats(questionUrl: string, cookie: string) {
|
||||||
let response = await axios({
|
let response = await axios({
|
||||||
url: questionUrl + "/stats",
|
url: questionUrl + "/stats",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
@ -50,7 +50,7 @@ async function fetchStats(questionUrl, cookie) {
|
||||||
// Is binary?
|
// Is binary?
|
||||||
let isbinary = response.includes("binary?":true");
|
let isbinary = response.includes("binary?":true");
|
||||||
|
|
||||||
let options = [];
|
let options: FetchedQuestion["options"] = [];
|
||||||
if (isbinary) {
|
if (isbinary) {
|
||||||
// Crowd percentage
|
// Crowd percentage
|
||||||
let htmlElements = response.split("\n");
|
let htmlElements = response.split("\n");
|
||||||
|
@ -107,21 +107,12 @@ async function fetchStats(questionUrl, cookie) {
|
||||||
.split(",")[0];
|
.split(",")[0];
|
||||||
//console.log(numpredictors)
|
//console.log(numpredictors)
|
||||||
|
|
||||||
// Calculate the stars
|
|
||||||
let minProbability = Math.min(...options.map((option) => option.probability));
|
|
||||||
let maxProbability = Math.max(...options.map((option) => option.probability));
|
|
||||||
|
|
||||||
let result = {
|
let result = {
|
||||||
description: description,
|
description,
|
||||||
options: options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
numforecasts: Number(numforecasts),
|
numforecasts: Number(numforecasts),
|
||||||
numforecasters: Number(numforecasters),
|
numforecasters: Number(numforecasters),
|
||||||
stars: calculateStars("Good Judgment Open", {
|
|
||||||
numforecasts,
|
|
||||||
minProbability,
|
|
||||||
maxProbability,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
// this mismatches the code below, and needs to be fixed, but I'm doing typescript conversion and don't want to touch any logic for now
|
// this mismatches the code below, and needs to be fixed, but I'm doing typescript conversion and don't want to touch any logic for now
|
||||||
} as any;
|
} as any;
|
||||||
|
@ -129,7 +120,7 @@ async function fetchStats(questionUrl, cookie) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSignedIn(html) {
|
function isSignedIn(html: string) {
|
||||||
let isSignedInBool = !(
|
let isSignedInBool = !(
|
||||||
html.includes("You need to sign in or sign up before continuing") ||
|
html.includes("You need to sign in or sign up before continuing") ||
|
||||||
html.includes("Sign up")
|
html.includes("Sign up")
|
||||||
|
@ -157,7 +148,7 @@ function sleep(ms: number) {
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
|
|
||||||
async function goodjudgmentopen_inner(cookie) {
|
async function goodjudgmentopen_inner(cookie: string) {
|
||||||
let i = 1;
|
let i = 1;
|
||||||
let response = await fetchPage(i, cookie);
|
let response = await fetchPage(i, cookie);
|
||||||
|
|
||||||
|
@ -243,6 +234,23 @@ export const goodjudgmentopen: Platform = {
|
||||||
color: "#002455",
|
color: "#002455",
|
||||||
async fetcher() {
|
async fetcher() {
|
||||||
let cookie = process.env.GOODJUDGMENTOPENCOOKIE;
|
let cookie = process.env.GOODJUDGMENTOPENCOOKIE;
|
||||||
return await applyIfSecretExists(cookie, goodjudgmentopen_inner);
|
return (await applyIfSecretExists(cookie, goodjudgmentopen_inner)) || null;
|
||||||
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let minProbability = Math.min(
|
||||||
|
...data.options.map((option) => option.probability || 0)
|
||||||
|
);
|
||||||
|
let maxProbability = Math.max(
|
||||||
|
...data.options.map((option) => option.probability || 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
let nuno = () => ((data.qualityindicators.numforecasts || 0) > 100 ? 3 : 2);
|
||||||
|
let eli = () => 3;
|
||||||
|
let misha = () =>
|
||||||
|
minProbability > 0.1 || maxProbability < 0.9 ? 3.1 : 2.5;
|
||||||
|
|
||||||
|
let starsDecimal = average([nuno(), eli(), misha()]);
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { parseISO } from "date-fns";
|
|
||||||
|
|
||||||
/* Imports */
|
|
||||||
import { Question } from "@prisma/client";
|
import { Question } from "@prisma/client";
|
||||||
|
|
||||||
import { AlgoliaQuestion } from "../../backend/utils/algolia";
|
import { AlgoliaQuestion } from "../../backend/utils/algolia";
|
||||||
import { prisma } from "../database/prisma";
|
import { prisma } from "../database/prisma";
|
||||||
import { Platform } from "./";
|
import { FetchedQuestion, Platform, prepareQuestion } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
const searchEndpoint =
|
const searchEndpoint =
|
||||||
|
@ -14,25 +12,20 @@ const searchEndpoint =
|
||||||
|
|
||||||
const apiEndpoint = "https://guesstimate.herokuapp.com";
|
const apiEndpoint = "https://guesstimate.herokuapp.com";
|
||||||
|
|
||||||
/* Body */
|
|
||||||
|
|
||||||
const modelToQuestion = (model: any): Question => {
|
const modelToQuestion = (model: any): Question => {
|
||||||
const { description } = model;
|
const { description } = model;
|
||||||
// const description = model.description
|
// const description = model.description
|
||||||
// ? model.description.replace(/\n/g, " ").replace(/ /g, " ")
|
// ? model.description.replace(/\n/g, " ").replace(/ /g, " ")
|
||||||
// : "";
|
// : "";
|
||||||
const stars = description.length > 250 ? 2 : 1;
|
// const timestamp = parseISO(model.created_at);
|
||||||
const timestamp = parseISO(model.created_at);
|
const fq: FetchedQuestion = {
|
||||||
const q: Question = {
|
|
||||||
id: `guesstimate-${model.id}`,
|
id: `guesstimate-${model.id}`,
|
||||||
title: model.name,
|
title: model.name,
|
||||||
url: `https://www.getguesstimate.com/models/${model.id}`,
|
url: `https://www.getguesstimate.com/models/${model.id}`,
|
||||||
timestamp,
|
// timestamp,
|
||||||
platform: "guesstimate",
|
|
||||||
description,
|
description,
|
||||||
options: [],
|
options: [],
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
stars,
|
|
||||||
numforecasts: 1,
|
numforecasts: 1,
|
||||||
numforecasters: 1,
|
numforecasters: 1,
|
||||||
},
|
},
|
||||||
|
@ -41,6 +34,7 @@ const modelToQuestion = (model: any): Question => {
|
||||||
},
|
},
|
||||||
// ranking: 10 * (index + 1) - 0.5, //(model._rankingInfo - 1*index)// hack
|
// ranking: 10 * (index + 1) - 0.5, //(model._rankingInfo - 1*index)// hack
|
||||||
};
|
};
|
||||||
|
const q = prepareQuestion(fq, guesstimate);
|
||||||
return q;
|
return q;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,7 +62,7 @@ async function search(query: string): Promise<AlgoliaQuestion[]> {
|
||||||
});
|
});
|
||||||
|
|
||||||
// filter for duplicates. Surprisingly common.
|
// filter for duplicates. Surprisingly common.
|
||||||
let uniqueTitles = [];
|
let uniqueTitles: string[] = [];
|
||||||
let uniqueModels: AlgoliaQuestion[] = [];
|
let uniqueModels: AlgoliaQuestion[] = [];
|
||||||
for (let model of mappedModels) {
|
for (let model of mappedModels) {
|
||||||
if (!uniqueTitles.includes(model.title) && !model.title.includes("copy")) {
|
if (!uniqueTitles.includes(model.title) && !model.title.includes("copy")) {
|
||||||
|
@ -100,4 +94,5 @@ export const guesstimate: Platform & {
|
||||||
color: "#223900",
|
color: "#223900",
|
||||||
search,
|
search,
|
||||||
fetchQuestion,
|
fetchQuestion,
|
||||||
|
calculateStars: (q) => (q.description.length > 250 ? 2 : 1),
|
||||||
};
|
};
|
||||||
|
|
|
@ -41,11 +41,16 @@ export interface QualityIndicators {
|
||||||
|
|
||||||
export type FetchedQuestion = Omit<
|
export type FetchedQuestion = Omit<
|
||||||
Question,
|
Question,
|
||||||
"extra" | "qualityindicators" | "timestamp" | "platform"
|
"extra" | "qualityindicators" | "timestamp" | "platform" | "options"
|
||||||
> & {
|
> & {
|
||||||
timestamp?: Date;
|
timestamp?: Date;
|
||||||
extra?: object; // required in DB but annoying to return empty; also this is slightly stricter than Prisma's JsonValue
|
extra?: object; // required in DB but annoying to return empty; also this is slightly stricter than Prisma's JsonValue
|
||||||
qualityindicators: QualityIndicators; // slightly stronger type than Prisma's JsonValue
|
options: {
|
||||||
|
name?: string;
|
||||||
|
probability?: number;
|
||||||
|
type: "PROBABILITY";
|
||||||
|
}[]; // stronger type than Prisma's JsonValue
|
||||||
|
qualityindicators: Omit<QualityIndicators, "stars">; // slightly stronger type than Prisma's JsonValue
|
||||||
};
|
};
|
||||||
|
|
||||||
// fetcher should return null if platform failed to fetch questions for some reason
|
// fetcher should return null if platform failed to fetch questions for some reason
|
||||||
|
@ -56,6 +61,7 @@ export interface Platform {
|
||||||
label: string; // longer name for displaying on frontend etc., e.g. "X-risk estimates"
|
label: string; // longer name for displaying on frontend etc., e.g. "X-risk estimates"
|
||||||
color: string; // used on frontend
|
color: string; // used on frontend
|
||||||
fetcher?: PlatformFetcher;
|
fetcher?: PlatformFetcher;
|
||||||
|
calculateStars: (question: FetchedQuestion) => number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draft for the future callback-based streaming/chunking API:
|
// draft for the future callback-based streaming/chunking API:
|
||||||
|
@ -86,6 +92,22 @@ export const platforms: Platform[] = [
|
||||||
xrisk,
|
xrisk,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const prepareQuestion = (
|
||||||
|
q: FetchedQuestion,
|
||||||
|
platform: Platform
|
||||||
|
): Question => {
|
||||||
|
return {
|
||||||
|
extra: {},
|
||||||
|
timestamp: new Date(),
|
||||||
|
...q,
|
||||||
|
platform: platform.name,
|
||||||
|
qualityindicators: {
|
||||||
|
...q.qualityindicators,
|
||||||
|
stars: platform.calculateStars(q),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const processPlatform = async (platform: Platform) => {
|
export const processPlatform = async (platform: Platform) => {
|
||||||
if (!platform.fetcher) {
|
if (!platform.fetcher) {
|
||||||
console.log(`Platform ${platform.name} doesn't have a fetcher, skipping`);
|
console.log(`Platform ${platform.name} doesn't have a fetcher, skipping`);
|
||||||
|
@ -97,16 +119,6 @@ export const processPlatform = async (platform: Platform) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepareQuestion = (q: FetchedQuestion): Question => {
|
|
||||||
return {
|
|
||||||
extra: {},
|
|
||||||
timestamp: new Date(),
|
|
||||||
...q,
|
|
||||||
platform: platform.name,
|
|
||||||
qualityindicators: q.qualityindicators as object, // fighting typescript
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const oldQuestions = await prisma.question.findMany({
|
const oldQuestions = await prisma.question.findMany({
|
||||||
where: {
|
where: {
|
||||||
platform: platform.name,
|
platform: platform.name,
|
||||||
|
@ -123,7 +135,7 @@ export const processPlatform = async (platform: Platform) => {
|
||||||
const updatedQuestions: Question[] = [];
|
const updatedQuestions: Question[] = [];
|
||||||
const deletedIds = oldIds.filter((id) => !fetchedIdsSet.has(id));
|
const deletedIds = oldIds.filter((id) => !fetchedIdsSet.has(id));
|
||||||
|
|
||||||
for (const q of fetchedQuestions.map((q) => prepareQuestion(q))) {
|
for (const q of fetchedQuestions.map((q) => prepareQuestion(q, platform))) {
|
||||||
if (oldIdsSet.has(q.id)) {
|
if (oldIdsSet.has(q.id)) {
|
||||||
updatedQuestions.push(q);
|
updatedQuestions.push(q);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
import { average } from "../../utils";
|
||||||
import { applyIfSecretExists } from "../utils/getSecrets";
|
import { applyIfSecretExists } from "../utils/getSecrets";
|
||||||
import { measureTime } from "../utils/measureTime";
|
import { measureTime } from "../utils/measureTime";
|
||||||
import { calculateStars } from "../utils/stars";
|
|
||||||
import toMarkdown from "../utils/toMarkdown";
|
import toMarkdown from "../utils/toMarkdown";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
|
@ -106,7 +106,6 @@ async function fetchStats(questionUrl, cookie) {
|
||||||
numforecasts: Number(numforecasts),
|
numforecasts: Number(numforecasts),
|
||||||
numforecasters: Number(numforecasters),
|
numforecasters: Number(numforecasters),
|
||||||
comments_count: Number(comments_count),
|
comments_count: Number(comments_count),
|
||||||
stars: calculateStars(platformName, { numforecasts }),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// console.log(JSON.stringify(result, null, 4));
|
// console.log(JSON.stringify(result, null, 4));
|
||||||
|
@ -177,9 +176,7 @@ async function infer_inner(cookie: string) {
|
||||||
let question: FetchedQuestion = {
|
let question: FetchedQuestion = {
|
||||||
id: id,
|
id: id,
|
||||||
title: title,
|
title: title,
|
||||||
description: moreinfo.description,
|
|
||||||
url: url,
|
url: url,
|
||||||
options: moreinfo.options,
|
|
||||||
...moreinfo,
|
...moreinfo,
|
||||||
};
|
};
|
||||||
console.log(JSON.stringify(question, null, 4));
|
console.log(JSON.stringify(question, null, 4));
|
||||||
|
@ -236,4 +233,12 @@ export const infer: Platform = {
|
||||||
let cookie = process.env.INFER_COOKIE;
|
let cookie = process.env.INFER_COOKIE;
|
||||||
return await applyIfSecretExists(cookie, infer_inner);
|
return await applyIfSecretExists(cookie, infer_inner);
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 2;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -23,7 +23,7 @@ async function processMarkets(markets) {
|
||||||
markets = markets.filter((market) => market.close_date > dateNow);
|
markets = markets.filter((market) => market.close_date > dateNow);
|
||||||
let results = await markets.map((market) => {
|
let results = await markets.map((market) => {
|
||||||
const probability = market.last_price / 100;
|
const probability = market.last_price / 100;
|
||||||
const options = [
|
const options: FetchedQuestion["options"] = [
|
||||||
{
|
{
|
||||||
name: "Yes",
|
name: "Yes",
|
||||||
probability: probability,
|
probability: probability,
|
||||||
|
@ -43,29 +43,26 @@ async function processMarkets(markets) {
|
||||||
description: `${market.settle_details}. The resolution source is: ${market.ranged_group_name} (${market.settle_source_url})`,
|
description: `${market.settle_details}. The resolution source is: ${market.ranged_group_name} (${market.settle_source_url})`,
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
stars: calculateStars(platformName, {
|
|
||||||
shares_volume: market.volume,
|
|
||||||
interest: market.open_interest,
|
|
||||||
}),
|
|
||||||
yes_bid: market.yes_bid,
|
yes_bid: market.yes_bid,
|
||||||
yes_ask: market.yes_ask,
|
yes_ask: market.yes_ask,
|
||||||
spread: Math.abs(market.yes_bid - market.yes_ask),
|
spread: Math.abs(market.yes_bid - market.yes_ask),
|
||||||
shares_volume: market.volume, // Assuming that half of all buys are for yes and half for no, which is a big if.
|
shares_volume: market.volume, // Assuming that half of all buys are for yes and half for no, which is a big if.
|
||||||
// "open_interest": market.open_interest, also in shares
|
// "open_interest": market.open_interest, also in shares
|
||||||
},
|
},
|
||||||
|
extra: {
|
||||||
|
open_interest: market.open_interest,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
//console.log(results.length)
|
|
||||||
// console.log(results.map(result => result.title))
|
|
||||||
// console.log(results.map(result => result.title).length)
|
|
||||||
console.log([...new Set(results.map((result) => result.title))]);
|
console.log([...new Set(results.map((result) => result.title))]);
|
||||||
console.log(
|
console.log(
|
||||||
"Number of unique questions: ",
|
"Number of unique questions: ",
|
||||||
[...new Set(results.map((result) => result.title))].length
|
[...new Set(results.map((result) => result.title))].length
|
||||||
);
|
);
|
||||||
// console.log([...new Set(results.map(result => result.title))].length)
|
|
||||||
return results; //resultsProcessed
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const kalshi: Platform = {
|
export const kalshi: Platform = {
|
||||||
|
@ -76,4 +73,29 @@ export const kalshi: Platform = {
|
||||||
let markets = await fetchAllMarkets();
|
let markets = await fetchAllMarkets();
|
||||||
return await processMarkets(markets);
|
return await processMarkets(markets);
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () =>
|
||||||
|
((data.extra as any)?.open_interest || 0) > 500 &&
|
||||||
|
data.qualityindicators.shares_volume > 10000
|
||||||
|
? 4
|
||||||
|
: data.qualityindicators.shares_volume > 2000
|
||||||
|
? 3
|
||||||
|
: 2;
|
||||||
|
// let eli = (data) => data.interest > 10000 ? 5 : 4
|
||||||
|
// let misha = (data) => 4
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(data), misha(data)])
|
||||||
|
|
||||||
|
// Substract 1 star if probability is above 90% or below 10%
|
||||||
|
if (
|
||||||
|
data.options instanceof Array &&
|
||||||
|
data.options[0] &&
|
||||||
|
((data.options[0].probability || 0) < 0.1 ||
|
||||||
|
(data.options[0].probability || 0) > 0.9)
|
||||||
|
) {
|
||||||
|
starsDecimal = starsDecimal - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -25,16 +25,16 @@ async function fetchData() {
|
||||||
|
|
||||||
function showStatistics(results: FetchedQuestion[]) {
|
function showStatistics(results: FetchedQuestion[]) {
|
||||||
console.log(`Num unresolved markets: ${results.length}`);
|
console.log(`Num unresolved markets: ${results.length}`);
|
||||||
let sum = (arr) => arr.reduce((tally, a) => tally + a, 0);
|
let sum = (arr: number[]) => arr.reduce((tally, a) => tally + a, 0);
|
||||||
let num2StarsOrMore = results.filter(
|
let num2StarsOrMore = results.filter(
|
||||||
(result) => result.qualityindicators.stars >= 2
|
(result) => manifold.calculateStars(result) >= 2
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
`Manifold has ${num2StarsOrMore.length} markets with 2 stars or more`
|
`Manifold has ${num2StarsOrMore.length} markets with 2 stars or more`
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
`Mean volume: ${
|
`Mean volume: ${
|
||||||
sum(results.map((result) => result.qualityindicators.volume7Days)) /
|
sum(results.map((result) => result.qualityindicators.volume7Days || 0)) /
|
||||||
results.length
|
results.length
|
||||||
}; mean pool: ${
|
}; mean pool: ${
|
||||||
sum(results.map((result) => result.qualityindicators.pool)) /
|
sum(results.map((result) => result.qualityindicators.pool)) /
|
||||||
|
@ -47,7 +47,7 @@ async function processPredictions(predictions) {
|
||||||
let results: FetchedQuestion[] = await predictions.map((prediction) => {
|
let results: FetchedQuestion[] = await predictions.map((prediction) => {
|
||||||
let id = `${platformName}-${prediction.id}`; // oops, doesn't match platform name
|
let id = `${platformName}-${prediction.id}`; // oops, doesn't match platform name
|
||||||
let probability = prediction.probability;
|
let probability = prediction.probability;
|
||||||
let options = [
|
let options: FetchedQuestion["options"] = [
|
||||||
{
|
{
|
||||||
name: "Yes",
|
name: "Yes",
|
||||||
probability: probability,
|
probability: probability,
|
||||||
|
@ -64,13 +64,8 @@ async function processPredictions(predictions) {
|
||||||
title: prediction.question,
|
title: prediction.question,
|
||||||
url: prediction.url,
|
url: prediction.url,
|
||||||
description: prediction.description,
|
description: prediction.description,
|
||||||
options: options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
stars: calculateStars(platformName, {
|
|
||||||
volume7Days: prediction.volume7Days,
|
|
||||||
volume24Hours: prediction.volume24Hours,
|
|
||||||
pool: prediction.pool,
|
|
||||||
}),
|
|
||||||
createdTime: prediction.createdTime,
|
createdTime: prediction.createdTime,
|
||||||
volume7Days: prediction.volume7Days,
|
volume7Days: prediction.volume7Days,
|
||||||
volume24Hours: prediction.volume24Hours,
|
volume24Hours: prediction.volume24Hours,
|
||||||
|
@ -99,4 +94,17 @@ export const manifold: Platform = {
|
||||||
showStatistics(results);
|
showStatistics(results);
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () =>
|
||||||
|
(data.qualityindicators.volume7Days || 0) > 250 ||
|
||||||
|
((data.qualityindicators.pool || 0) > 500 &&
|
||||||
|
(data.qualityindicators.volume7Days || 0) > 100)
|
||||||
|
? 2
|
||||||
|
: 1;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(data), misha(data)])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import toMarkdown from "../utils/toMarkdown";
|
import toMarkdown from "../utils/toMarkdown";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ export const metaculus: Platform = {
|
||||||
let description = descriptionprocessed2;
|
let description = descriptionprocessed2;
|
||||||
|
|
||||||
let isbinary = result.possibilities.type == "binary";
|
let isbinary = result.possibilities.type == "binary";
|
||||||
let options = [];
|
let options: FetchedQuestion["options"] = [];
|
||||||
if (isbinary) {
|
if (isbinary) {
|
||||||
let probability = Number(result.community_prediction.full.q2);
|
let probability = Number(result.community_prediction.full.q2);
|
||||||
options = [
|
options = [
|
||||||
|
@ -156,9 +156,6 @@ export const metaculus: Platform = {
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
numforecasts: Number(result.number_of_predictions),
|
numforecasts: Number(result.number_of_predictions),
|
||||||
stars: calculateStars(platformName, {
|
|
||||||
numforecasts: result.number_of_predictions,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
extra: {
|
extra: {
|
||||||
resolution_data: {
|
resolution_data: {
|
||||||
|
@ -193,4 +190,14 @@ export const metaculus: Platform = {
|
||||||
|
|
||||||
return all_questions;
|
return all_questions;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
const { numforecasts } = data.qualityindicators;
|
||||||
|
let nuno = () =>
|
||||||
|
(numforecasts || 0) > 300 ? 4 : (numforecasts || 0) > 100 ? 3 : 2;
|
||||||
|
let eli = () => 3;
|
||||||
|
let misha = () => 3;
|
||||||
|
let starsDecimal = average([nuno(), eli(), misha()]);
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -96,8 +96,8 @@ export const polymarket: Platform = {
|
||||||
let options = [];
|
let options = [];
|
||||||
for (let outcome in moreMarketInfo.outcomeTokenPrices) {
|
for (let outcome in moreMarketInfo.outcomeTokenPrices) {
|
||||||
options.push({
|
options.push({
|
||||||
name: marketInfo.outcomes[outcome],
|
name: String(marketInfo.outcomes[outcome]),
|
||||||
probability: moreMarketInfo.outcomeTokenPrices[outcome],
|
probability: Number(moreMarketInfo.outcomeTokenPrices[outcome]),
|
||||||
type: "PROBABILITY",
|
type: "PROBABILITY",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,6 @@ export const polymarket: Platform = {
|
||||||
numforecasts: numforecasts.toFixed(0),
|
numforecasts: numforecasts.toFixed(0),
|
||||||
liquidity: liquidity.toFixed(2),
|
liquidity: liquidity.toFixed(2),
|
||||||
tradevolume: tradevolume.toFixed(2),
|
tradevolume: tradevolume.toFixed(2),
|
||||||
stars: calculateStars(platformName, {
|
|
||||||
liquidity,
|
|
||||||
option: options[0],
|
|
||||||
volume: tradevolume,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
extra: {
|
extra: {
|
||||||
address: marketInfo.address,
|
address: marketInfo.address,
|
||||||
|
@ -132,4 +127,33 @@ export const polymarket: Platform = {
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
// let nuno = (data) => (data.volume > 10000 ? 4 : data.volume > 1000 ? 3 : 2);
|
||||||
|
// let eli = (data) => data.liquidity > 10000 ? 5 : 4
|
||||||
|
// let misha = (data) => 4
|
||||||
|
|
||||||
|
const liquidity = data.qualityindicators.liquidity || 0;
|
||||||
|
const volume = data.qualityindicators.tradevolume || 0;
|
||||||
|
|
||||||
|
let nuno = () =>
|
||||||
|
liquidity > 1000 && volume > 10000
|
||||||
|
? 4
|
||||||
|
: liquidity > 500 && volume > 1000
|
||||||
|
? 3
|
||||||
|
: 2;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(data), misha(data)])
|
||||||
|
|
||||||
|
// Substract 1 star if probability is above 90% or below 10%
|
||||||
|
if (
|
||||||
|
data.options instanceof Array &&
|
||||||
|
data.options[0] &&
|
||||||
|
((data.options[0].probability || 0) < 0.1 ||
|
||||||
|
(data.options[0].probability || 0) > 0.9)
|
||||||
|
) {
|
||||||
|
starsDecimal = starsDecimal - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import toMarkdown from "../utils/toMarkdown";
|
import toMarkdown from "../utils/toMarkdown";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
|
@ -103,7 +103,6 @@ export const predictit: Platform = {
|
||||||
description,
|
description,
|
||||||
options,
|
options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
shares_volume,
|
shares_volume,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -113,4 +112,12 @@ export const predictit: Platform = {
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 3;
|
||||||
|
let eli = () => 3.5;
|
||||||
|
let misha = () => 2.5;
|
||||||
|
let starsDecimal = average([nuno(), eli(), misha()]);
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import toMarkdown from "../utils/toMarkdown";
|
import toMarkdown from "../utils/toMarkdown";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
|
@ -79,11 +79,18 @@ export const rootclaim: Platform = {
|
||||||
options: options,
|
options: options,
|
||||||
qualityindicators: {
|
qualityindicators: {
|
||||||
numforecasts: 1,
|
numforecasts: 1,
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
results.push(obj);
|
results.push(obj);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 4;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno() /*, eli(data), misha(data)*/]);
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
import { calculateStars } from "../utils/stars";
|
import { average } from "../../utils";
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -166,9 +166,7 @@ export const smarkets: Platform = {
|
||||||
description: market.description,
|
description: market.description,
|
||||||
options: options,
|
options: options,
|
||||||
timestamp: new Date(),
|
timestamp: new Date(),
|
||||||
qualityindicators: {
|
qualityindicators: {},
|
||||||
stars: calculateStars(platformName, {}),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
VERBOSE ? console.log(result) : empty();
|
VERBOSE ? console.log(result) : empty();
|
||||||
results.push(result);
|
results.push(result);
|
||||||
|
@ -176,4 +174,12 @@ export const smarkets: Platform = {
|
||||||
VERBOSE ? console.log(results) : empty();
|
VERBOSE ? console.log(results) : empty();
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 2;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import { GoogleSpreadsheet } from "google-spreadsheet";
|
import { GoogleSpreadsheet } from "google-spreadsheet";
|
||||||
|
|
||||||
|
import { average } from "../../utils";
|
||||||
import { applyIfSecretExists } from "../utils/getSecrets";
|
import { applyIfSecretExists } from "../utils/getSecrets";
|
||||||
import { hash } from "../utils/hash";
|
import { hash } from "../utils/hash";
|
||||||
import { calculateStars } from "../utils/stars";
|
|
||||||
import { FetchedQuestion, Platform } from "./";
|
import { FetchedQuestion, Platform } from "./";
|
||||||
|
|
||||||
/* Definitions */
|
/* Definitions */
|
||||||
|
@ -76,7 +76,7 @@ async function processPredictions(predictions) {
|
||||||
let title = prediction["Prediction"].replace(" [update]", "");
|
let title = prediction["Prediction"].replace(" [update]", "");
|
||||||
let id = `${platformName}-${hash(title)}`;
|
let id = `${platformName}-${hash(title)}`;
|
||||||
let probability = Number(prediction["Odds"].replace("%", "")) / 100;
|
let probability = Number(prediction["Odds"].replace("%", "")) / 100;
|
||||||
let options = [
|
let options: FetchedQuestion["options"] = [
|
||||||
{
|
{
|
||||||
name: "Yes",
|
name: "Yes",
|
||||||
probability: probability,
|
probability: probability,
|
||||||
|
@ -95,9 +95,7 @@ async function processPredictions(predictions) {
|
||||||
description: prediction["Notes"] || "",
|
description: prediction["Notes"] || "",
|
||||||
options,
|
options,
|
||||||
timestamp: new Date(Date.parse(prediction["Prediction Date"] + "Z")),
|
timestamp: new Date(Date.parse(prediction["Prediction Date"] + "Z")),
|
||||||
qualityindicators: {
|
qualityindicators: {},
|
||||||
stars: calculateStars(platformName, null),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
@ -125,4 +123,12 @@ export const wildeford: Platform = {
|
||||||
const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY; // See: https://developers.google.com/sheets/api/guides/authorizing#APIKey
|
const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY; // See: https://developers.google.com/sheets/api/guides/authorizing#APIKey
|
||||||
return await applyIfSecretExists(GOOGLE_API_KEY, wildeford_inner);
|
return await applyIfSecretExists(GOOGLE_API_KEY, wildeford_inner);
|
||||||
},
|
},
|
||||||
|
calculateStars(data) {
|
||||||
|
let nuno = () => 3;
|
||||||
|
let eli = () => null;
|
||||||
|
let misha = () => null;
|
||||||
|
let starsDecimal = average([nuno()]); //, eli(), misha()])
|
||||||
|
let starsInteger = Math.round(starsDecimal);
|
||||||
|
return starsInteger;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,4 +25,5 @@ export const xrisk: Platform = {
|
||||||
});
|
});
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
calculateStars: () => 2,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export async function applyIfSecretExists<T>(
|
export async function applyIfSecretExists<T>(
|
||||||
cookie: string,
|
cookie: string | undefined,
|
||||||
fun: (cookie: string) => T
|
fun: (cookie: string) => T
|
||||||
) {
|
) {
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
|
|
|
@ -1,330 +0,0 @@
|
||||||
let average = (array: number[]) =>
|
|
||||||
array.reduce((a, b) => a + b, 0) / array.length;
|
|
||||||
|
|
||||||
function calculateStarsAstralCodexTen(data) {
|
|
||||||
let nuno = (data) => 3;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsBetfair(data) {
|
|
||||||
let nuno = (data) => (data.volume > 10000 ? 4 : data.volume > 1000 ? 3 : 2);
|
|
||||||
let eli = (data) => (data.volume > 10000 ? null : null);
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
// Substract 1 star if probability is above 90% or below 10%
|
|
||||||
if (
|
|
||||||
data.option &&
|
|
||||||
(data.option.probability < 0.1 || data.option.probability > 0.9)
|
|
||||||
) {
|
|
||||||
starsDecimal = starsDecimal - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsCoupCast(data) {
|
|
||||||
let nuno = (data) => 3;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsCSETForetell(data) {
|
|
||||||
let nuno = (data) => (data.numforecasts > 100 ? 3 : 2);
|
|
||||||
let eli = (data) => 3;
|
|
||||||
let misha = (data) => 2;
|
|
||||||
let starsDecimal = average([nuno(data), eli(data), misha(data)]);
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsElicit(data) {
|
|
||||||
let nuno = (data) => 1;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsEstimize(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsForetold(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsGiveWellOpenPhil(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsGoodJudgment(data) {
|
|
||||||
let nuno = (data) => 4;
|
|
||||||
let eli = (data) => 4;
|
|
||||||
let misha = (data) => 3.5;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsGoodJudgmentOpen(data) {
|
|
||||||
let nuno = (data) => (data.numforecasts > 100 ? 3 : 2);
|
|
||||||
let eli = (data) => 3;
|
|
||||||
let misha = (data) =>
|
|
||||||
data.minProbability > 0.1 || data.maxProbability < 0.9 ? 3.1 : 2.5;
|
|
||||||
let starsDecimal = average([nuno(data), eli(data), misha(data)]);
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsHypermind(data) {
|
|
||||||
let nuno = (data) => 3;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsInfer(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsKalshi(data) {
|
|
||||||
let nuno = (data) =>
|
|
||||||
data.interest > 500 && data.shares_volume > 10000
|
|
||||||
? 4
|
|
||||||
: data.shares_volume > 2000
|
|
||||||
? 3
|
|
||||||
: 2;
|
|
||||||
// let eli = (data) => data.interest > 10000 ? 5 : 4
|
|
||||||
// let misha = (data) => 4
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
// Substract 1 star if probability is above 90% or below 10%
|
|
||||||
if (
|
|
||||||
data.option &&
|
|
||||||
(data.option.probability < 0.1 || data.option.probability > 0.9)
|
|
||||||
) {
|
|
||||||
starsDecimal = starsDecimal - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsLadbrokes(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsManifold(data) {
|
|
||||||
let nuno = (data) =>
|
|
||||||
data.volume7Days > 250 || (data.pool > 500 && data.volume7Days > 100)
|
|
||||||
? 2
|
|
||||||
: 1;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
// console.log(data);
|
|
||||||
// console.log(starsInteger);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsMetaculus(data) {
|
|
||||||
let nuno = (data) =>
|
|
||||||
data.numforecasts > 300 ? 4 : data.numforecasts > 100 ? 3 : 2;
|
|
||||||
let eli = (data) => 3;
|
|
||||||
let misha = (data) => 3;
|
|
||||||
let starsDecimal = average([nuno(data), eli(data), misha(data)]);
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsOmen(data) {
|
|
||||||
let nuno = (data) => 1;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsPolymarket(data) {
|
|
||||||
// let nuno = (data) => (data.volume > 10000 ? 4 : data.volume > 1000 ? 3 : 2);
|
|
||||||
// let eli = (data) => data.liquidity > 10000 ? 5 : 4
|
|
||||||
// let misha = (data) => 4
|
|
||||||
|
|
||||||
let nuno = (data) =>
|
|
||||||
data.liquidity > 1000 && data.volume > 10000
|
|
||||||
? 4
|
|
||||||
: data.liquidity > 500 && data.volume > 1000
|
|
||||||
? 3
|
|
||||||
: 2;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
// Substract 1 star if probability is above 90% or below 10%
|
|
||||||
if (
|
|
||||||
data.option &&
|
|
||||||
(data.option.probability < 0.1 || data.option.probability > 0.9)
|
|
||||||
) {
|
|
||||||
starsDecimal = starsDecimal - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsPredictIt(data) {
|
|
||||||
let nuno = (data) => 3;
|
|
||||||
let eli = (data) => 3.5;
|
|
||||||
let misha = (data) => 2.5;
|
|
||||||
let starsDecimal = average([nuno(data), eli(data), misha(data)]);
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsRootclaim(data) {
|
|
||||||
let nuno = (data) => 4;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data) /*, eli(data), misha(data)*/]);
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsSmarkets(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsWildeford(data) {
|
|
||||||
let nuno = (data) => 3;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStarsWilliamHill(data) {
|
|
||||||
let nuno = (data) => 2;
|
|
||||||
let eli = (data) => null;
|
|
||||||
let misha = (data) => null;
|
|
||||||
let starsDecimal = average([nuno(data)]); //, eli(data), misha(data)])
|
|
||||||
let starsInteger = Math.round(starsDecimal);
|
|
||||||
return starsInteger;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function calculateStars(platform: string, data) {
|
|
||||||
let stars = 2;
|
|
||||||
switch (platform) {
|
|
||||||
case "betfair":
|
|
||||||
stars = calculateStarsBetfair(data);
|
|
||||||
break;
|
|
||||||
case "infer":
|
|
||||||
stars = calculateStarsInfer(data);
|
|
||||||
break;
|
|
||||||
case "foretold":
|
|
||||||
stars = calculateStarsForetold(data);
|
|
||||||
break;
|
|
||||||
case "givewellopenphil":
|
|
||||||
stars = calculateStarsGiveWellOpenPhil(data);
|
|
||||||
break;
|
|
||||||
case "goodjudgment":
|
|
||||||
stars = calculateStarsGoodJudgment(data);
|
|
||||||
break;
|
|
||||||
case "goodjudgmentopen":
|
|
||||||
stars = calculateStarsGoodJudgmentOpen(data);
|
|
||||||
break;
|
|
||||||
case "kalshi":
|
|
||||||
stars = calculateStarsKalshi(data);
|
|
||||||
break;
|
|
||||||
case "manifold":
|
|
||||||
stars = calculateStarsManifold(data);
|
|
||||||
break;
|
|
||||||
case "metaculus":
|
|
||||||
stars = calculateStarsMetaculus(data);
|
|
||||||
break;
|
|
||||||
case "polymarket":
|
|
||||||
stars = calculateStarsPolymarket(data);
|
|
||||||
break;
|
|
||||||
case "predictit":
|
|
||||||
stars = calculateStarsPredictIt(data);
|
|
||||||
break;
|
|
||||||
case "rootclaim":
|
|
||||||
stars = calculateStarsRootclaim(data);
|
|
||||||
break;
|
|
||||||
case "smarkets":
|
|
||||||
stars = calculateStarsSmarkets(data);
|
|
||||||
break;
|
|
||||||
case "wildeford":
|
|
||||||
stars = calculateStarsWildeford(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// deprecated
|
|
||||||
case "AstralCodexTen":
|
|
||||||
stars = calculateStarsAstralCodexTen(data);
|
|
||||||
break;
|
|
||||||
case "CoupCast":
|
|
||||||
stars = calculateStarsCoupCast(data);
|
|
||||||
break;
|
|
||||||
case "CSET-foretell":
|
|
||||||
stars = calculateStarsCSETForetell(data);
|
|
||||||
break;
|
|
||||||
case "Elicit":
|
|
||||||
stars = calculateStarsElicit(data);
|
|
||||||
break;
|
|
||||||
case "Estimize":
|
|
||||||
stars = calculateStarsEstimize(data);
|
|
||||||
break;
|
|
||||||
case "Hypermind":
|
|
||||||
stars = calculateStarsHypermind(data);
|
|
||||||
break;
|
|
||||||
case "Ladbrokes":
|
|
||||||
stars = calculateStarsLadbrokes(data);
|
|
||||||
break;
|
|
||||||
case "Omen":
|
|
||||||
stars = calculateStarsOmen(data);
|
|
||||||
break;
|
|
||||||
case "WilliamHill":
|
|
||||||
stars = calculateStarsWilliamHill(data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
stars = 2;
|
|
||||||
}
|
|
||||||
return stars;
|
|
||||||
}
|
|
|
@ -6,3 +6,6 @@ export const shuffleArray = <T>(array: T[]): T[] => {
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const average = (array: number[]) =>
|
||||||
|
array.reduce((a, b) => a + b, 0) / array.length;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user