diff --git a/index.html b/index.html
index 99944e2..ded86e6 100644
--- a/index.html
+++ b/index.html
@@ -37,6 +37,33 @@
+
Daisy Mae
@@ -152,6 +179,7 @@
Pattern |
+ % Chance |
Sunday |
Monday |
Tuesday |
diff --git a/js/predictions.js b/js/predictions.js
index 3b3e4ae..5fa5a48 100644
--- a/js/predictions.js
+++ b/js/predictions.js
@@ -1,3 +1,37 @@
+const PATTERN = {
+ ROLLERCOASTER: 0,
+ LARGE_SPIKE: 1,
+ DECREASING: 2,
+ SMALL_SPIKE: 3,
+};
+
+const PROBABILITY_MATRIX = {
+ [PATTERN.ROLLERCOASTER]: {
+ [PATTERN.ROLLERCOASTER]: 0.20,
+ [PATTERN.LARGE_SPIKE]: 0.30,
+ [PATTERN.DECREASING]: 0.15,
+ [PATTERN.SMALL_SPIKE]: 0.35,
+ },
+ [PATTERN.LARGE_SPIKE]: {
+ [PATTERN.ROLLERCOASTER]: 0.50,
+ [PATTERN.LARGE_SPIKE]: 0.05,
+ [PATTERN.DECREASING]: 0.20,
+ [PATTERN.SMALL_SPIKE]: 0.25,
+ },
+ [PATTERN.DECREASING]: {
+ [PATTERN.ROLLERCOASTER]: 0.25,
+ [PATTERN.LARGE_SPIKE]: 0.45,
+ [PATTERN.DECREASING]: 0.05,
+ [PATTERN.SMALL_SPIKE]: 0.25,
+ },
+ [PATTERN.SMALL_SPIKE]: {
+ [PATTERN.ROLLERCOASTER]: 0.45,
+ [PATTERN.LARGE_SPIKE]: 0.25,
+ [PATTERN.DECREASING]: 0.15,
+ [PATTERN.SMALL_SPIKE]: 0.15,
+ },
+};
+
function minimum_rate_from_given_and_base(given_price, buy_price) {
return 10000 * (given_price - 1) / buy_price;
}
@@ -177,7 +211,7 @@ function* generate_pattern_0_with_lengths(given_prices, high_phase_1_len, dec_ph
});
}
yield {
- pattern_description: "high, decreasing, high, decreasing, high",
+ pattern_description: "Rollercoaster",
pattern_number: 0,
prices: predicted_prices
};
@@ -285,7 +319,7 @@ function* generate_pattern_1_with_peak(given_prices, peak_start) {
});
}
yield {
- pattern_description: "decreasing middle, high spike, random low",
+ pattern_description: "Large spike",
pattern_number: 1,
prices: predicted_prices
};
@@ -351,7 +385,7 @@ function* generate_pattern_2(given_prices) {
max_rate -= 300;
}
yield {
- pattern_description: "consistently decreasing",
+ pattern_description: "Decreasing",
pattern_number: 2,
prices: predicted_prices
};
@@ -531,7 +565,7 @@ function* generate_pattern_3_with_peak(given_prices, peak_start) {
}
yield {
- pattern_description: "decreasing, spike, decreasing",
+ pattern_description: "Small spike",
pattern_number: 3,
prices: predicted_prices
};
@@ -564,8 +598,31 @@ function* generate_possibilities(sell_prices, first_buy) {
}
}
-function analyze_possibilities(sell_prices, first_buy) {
+function get_probabilities(possibilities, previous_pattern) {
+ if (typeof previous_pattern === 'undefined' || Number.isNaN(previous_pattern) || previous_pattern === null || previous_pattern < 0 || previous_pattern > 3) {
+ return possibilities
+ }
+
+ var unique = (value, index, self) => {
+ return self.indexOf(value) === index;
+ }
+ var max_percent = possibilities.map(function (poss) {
+ return poss.pattern_number;
+ }).filter(unique).map(function(poss) {
+ return PROBABILITY_MATRIX[previous_pattern][poss];
+ }).reduce(function (prev, current) {
+ return prev + current;
+ }, 0);
+
+ return possibilities.map(function (poss) {
+ poss.probability = PROBABILITY_MATRIX[previous_pattern][poss.pattern_number] / max_percent;
+ return poss;
+ });
+}
+
+function analyze_possibilities(sell_prices, first_buy, previous_pattern) {
generated_possibilities = Array.from(generate_possibilities(sell_prices, first_buy));
+ generated_possibilities = get_probabilities(generated_possibilities, previous_pattern);
global_min_max = [];
for (var day = 0; day < 14; day++) {
@@ -585,7 +642,7 @@ function analyze_possibilities(sell_prices, first_buy) {
}
generated_possibilities.push({
- pattern_description: "predicted min/max across all patterns",
+ pattern_description: "All patterns",
pattern_number: 4,
prices: global_min_max,
});
diff --git a/js/scripts.js b/js/scripts.js
index 4a99fbe..7dd9bf6 100644
--- a/js/scripts.js
+++ b/js/scripts.js
@@ -10,10 +10,12 @@ const getSellFields = function () {
const sell_inputs = getSellFields()
const buy_input = $("#buy")
const first_buy_field = $("#first_buy");
+const previous_pattern_input = $("#previous_pattern");
//Functions
-const fillFields = function (prices, first_buy) {
+const fillFields = function (prices, first_buy, previous_pattern) {
first_buy_field.prop("checked", first_buy);
+ previous_pattern_input.val(previous_pattern);
buy_input.focus();
buy_input.val(prices[0] || '')
@@ -36,10 +38,11 @@ const initialize = function () {
try {
const prices = getPrices()
const first_buy = getFirstBuyState();
+ const previous_pattern = getPreviousPatternState();
if (prices === null) {
- fillFields([], first_buy)
+ fillFields([], first_buy, previous_pattern)
} else {
- fillFields(prices, first_buy)
+ fillFields(prices, first_buy, previous_pattern)
}
$(document).trigger("input");
} catch (e) {
@@ -48,15 +51,19 @@ const initialize = function () {
$("#reset").on("click", function () {
first_buy_field.prop('checked', false);
+ $("select").val(null);
$("input").val(null).trigger("input");
})
+
+ $('select').formSelect();
}
-const updateLocalStorage = function (prices, first_buy) {
+const updateLocalStorage = function (prices, first_buy, previous_pattern) {
try {
if (prices.length !== 14) throw "The data array needs exactly 14 elements to be valid"
localStorage.setItem("sell_prices", JSON.stringify(prices))
localStorage.setItem("first_buy", JSON.stringify(first_buy));
+ localStorage.setItem("previous_pattern", JSON.stringify(previous_pattern));
} catch (e) {
console.error(e)
}
@@ -71,6 +78,10 @@ const getFirstBuyState = function () {
return JSON.parse(localStorage.getItem('first_buy'))
}
+const getPreviousPatternState = function () {
+ return JSON.parse(localStorage.getItem('previous_pattern'))
+}
+
const getPricesFromLocalstorage = function () {
try {
const sell_prices = JSON.parse(localStorage.getItem("sell_prices"));
@@ -112,14 +123,15 @@ const getSellPrices = function () {
})
}
-const calculateOutput = function (data, first_buy) {
+const calculateOutput = function (data, first_buy, previous_pattern) {
if (isEmpty(data)) {
$("#output").html("");
return;
}
let output_possibilities = "";
- for (let poss of analyze_possibilities(data, first_buy)) {
+ for (let poss of analyze_possibilities(data, first_buy, previous_pattern)) {
var out_line = "
" + poss.pattern_description + " | "
+ out_line += `${Number.isFinite(poss.probability) ? ((poss.probability * 100).toPrecision(3) + '%') : '—'} | `;
for (let day of poss.prices.slice(1)) {
if (day.min !== day.max) {
out_line += `${day.min}..${day.max} | `;
@@ -138,15 +150,17 @@ const update = function () {
const sell_prices = getSellPrices();
const buy_price = parseInt(buy_input.val());
const first_buy = first_buy_field.is(":checked");
+ const previous_pattern = parseInt(previous_pattern_input.val());
buy_input.prop('disabled', first_buy);
const prices = [buy_price, buy_price, ...sell_prices];
if (!window.price_from_query) {
- updateLocalStorage(prices, first_buy);
+ updateLocalStorage(prices, first_buy, previous_pattern);
}
- calculateOutput(prices, first_buy);
+ calculateOutput(prices, first_buy, previous_pattern);
}
$(document).ready(initialize);
$(document).on("input", update);
+$(previous_pattern_input).on("change", update);