diff --git a/index.html b/index.html index e61b054..21adaf9 100644 --- a/index.html +++ b/index.html @@ -146,6 +146,7 @@

+ diff --git a/js/predictions.js b/js/predictions.js new file mode 100644 index 0000000..1ca0c2a --- /dev/null +++ b/js/predictions.js @@ -0,0 +1,604 @@ +function minimum_rate_from_given_and_base(given_price, buy_price) { + return 10000 * (given_price - 1) / buy_price; +} + +function maximum_rate_from_given_and_base(given_price, buy_price) { + return 10000 * given_price / buy_price; +} + +function* generate_pattern_0_with_lengths(given_prices, high_phase_1_len, dec_phase_1_len, high_phase_2_len, dec_phase_2_len, high_phase_3_len) { + /* + // PATTERN 0: high, decreasing, high, decreasing, high + work = 2; + + + // high phase 1 + for (int i = 0; i < hiPhaseLen1; i++) + { + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); + } + + // decreasing phase 1 + rate = randfloat(0.8, 0.6); + for (int i = 0; i < decPhaseLen1; i++) + { + sellPrices[work++] = intceil(rate * basePrice); + rate -= 0.04; + rate -= randfloat(0, 0.06); + } + + // high phase 2 + for (int i = 0; i < (hiPhaseLen2and3 - hiPhaseLen3); i++) + { + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); + } + + // decreasing phase 2 + rate = randfloat(0.8, 0.6); + for (int i = 0; i < decPhaseLen2; i++) + { + sellPrices[work++] = intceil(rate * basePrice); + rate -= 0.04; + rate -= randfloat(0, 0.06); + } + + // high phase 3 + for (int i = 0; i < hiPhaseLen3; i++) + { + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); + } + */ + + buy_price = given_prices[0]; + var predicted_prices = [ + { + min: buy_price, + max: buy_price, + }, + { + min: buy_price, + max: buy_price, + }, + ]; + + // High Phase 1 + for (var i = 2; i < 2 + high_phase_1_len; i++) { + min_pred = Math.floor(0.9 * buy_price); + max_pred = Math.ceil(1.4 * buy_price); + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + } + + // Dec Phase 1 + var min_rate = 6000; + var max_rate = 8000; + for (var i = 2 + high_phase_1_len; i < 2 + high_phase_1_len + dec_phase_1_len; i++) { + min_pred = Math.floor(min_rate * buy_price / 10000); + max_pred = Math.ceil(max_rate * buy_price / 10000); + + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); + max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + min_rate -= 1000; + max_rate -= 400; + } + + // High Phase 2 + for (var i = 2 + high_phase_1_len + dec_phase_1_len; i < 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len; i++) { + min_pred = Math.floor(0.9 * buy_price); + max_pred = Math.ceil(1.4 * buy_price); + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + } + + // Dec Phase 2 + var min_rate = 6000; + var max_rate = 8000; + for (var i = 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len; i < 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len + dec_phase_2_len; i++) { + min_pred = Math.floor(min_rate * buy_price / 10000); + max_pred = Math.ceil(max_rate * buy_price / 10000); + + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); + max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + min_rate -= 1000; + max_rate -= 400; + } + + // High Phase 3 + if (2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len + dec_phase_2_len + high_phase_3_len != 14) { + throw new Error("Phase lengths don't add up"); + } + for (var i = 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len + dec_phase_2_len; i < 14; i++) { + min_pred = Math.floor(0.9 * buy_price); + max_pred = Math.ceil(1.4 * buy_price); + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + } + yield { + pattern_description: "high, decreasing, high, decreasing, high", + pattern_number: 0, + prices: predicted_prices + }; +} + +function* generate_pattern_0(given_prices) { + /* + decPhaseLen1 = randbool() ? 3 : 2; + decPhaseLen2 = 5 - decPhaseLen1; + + hiPhaseLen1 = randint(0, 6); + hiPhaseLen2and3 = 7 - hiPhaseLen1; + hiPhaseLen3 = randint(0, hiPhaseLen2and3 - 1); + */ + for (var dec_phase_1_len = 2; dec_phase_1_len < 4; dec_phase_1_len++) { + for (var high_phase_1_len = 0; high_phase_1_len < 7; high_phase_1_len++) { + for (var high_phase_3_len = 0; high_phase_3_len < (7 - high_phase_1_len - 1 + 1); high_phase_3_len++) { + yield* generate_pattern_0_with_lengths(given_prices, high_phase_1_len, dec_phase_1_len, 7 - high_phase_1_len - high_phase_3_len, 5 - dec_phase_1_len, high_phase_3_len); + } + } + } +} + +function* generate_pattern_1_with_peak(given_prices, peak_start) { + /* + // PATTERN 1: decreasing middle, high spike, random low + peakStart = randint(3, 9); + rate = randfloat(0.9, 0.85); + for (work = 2; work < peakStart; work++) + { + sellPrices[work] = intceil(rate * basePrice); + rate -= 0.03; + rate -= randfloat(0, 0.02); + } + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); + sellPrices[work++] = intceil(randfloat(1.4, 2.0) * basePrice); + sellPrices[work++] = intceil(randfloat(2.0, 6.0) * basePrice); + sellPrices[work++] = intceil(randfloat(1.4, 2.0) * basePrice); + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); + for (; work < 14; work++) + { + sellPrices[work] = intceil(randfloat(0.4, 0.9) * basePrice); + } + */ + + buy_price = given_prices[0]; + var predicted_prices = [ + { + min: buy_price, + max: buy_price, + }, + { + min: buy_price, + max: buy_price, + }, + ]; + + var min_rate = 8500; + var max_rate = 9000; + + for (var i = 2; i < peak_start; i++) { + min_pred = Math.floor(min_rate * buy_price / 10000); + max_pred = Math.ceil(max_rate * buy_price / 10000); + + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); + max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + min_rate -= 500; + max_rate -= 300; + } + + // Now each day is independent of next + min_randoms = [0.9, 1.4, 2.0, 1.4, 0.9, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4] + max_randoms = [1.4, 2.0, 6.0, 2.0, 1.4, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9] + for (var i = peak_start; i < 14; i++) { + min_pred = Math.floor(min_randoms[i - peak_start] * buy_price); + max_pred = Math.ceil(max_randoms[i - peak_start] * buy_price); + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + } + yield { + pattern_description: "decreasing, high spike, random lows", + pattern_number: 1, + prices: predicted_prices + }; +} + +function* generate_pattern_1(given_prices) { + for (var peak_start = 3; peak_start < 10; peak_start++) { + yield* generate_pattern_1_with_peak(given_prices, peak_start); + } +} + +function* generate_pattern_2(given_prices) { + /* + // PATTERN 2: consistently decreasing + rate = 0.9; + rate -= randfloat(0, 0.05); + for (work = 2; work < 14; work++) + { + sellPrices[work] = intceil(rate * basePrice); + rate -= 0.03; + rate -= randfloat(0, 0.02); + } + break; + */ + + + buy_price = given_prices[0]; + var predicted_prices = [ + { + min: buy_price, + max: buy_price, + }, + { + min: buy_price, + max: buy_price, + }, + ]; + + var min_rate = 8500; + var max_rate = 9000; + for (var i = 2; i < 14; i++) { + min_pred = Math.floor(min_rate * buy_price / 10000); + max_pred = Math.ceil(max_rate * buy_price / 10000); + + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); + max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + min_rate -= 500; + max_rate -= 300; + } + yield { + pattern_description: "always decreasing", + pattern_number: 2, + prices: predicted_prices + }; +} + +function* generate_pattern_3_with_peak(given_prices, peak_start) { + + /* + // PATTERN 3: decreasing, spike, decreasing + peakStart = randint(2, 9); + + // decreasing phase before the peak + rate = randfloat(0.9, 0.4); + for (work = 2; work < peakStart; work++) + { + sellPrices[work] = intceil(rate * basePrice); + rate -= 0.03; + rate -= randfloat(0, 0.02); + } + + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * (float)basePrice); + sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); + rate = randfloat(1.4, 2.0); + sellPrices[work++] = intceil(randfloat(1.4, rate) * basePrice) - 1; + sellPrices[work++] = intceil(rate * basePrice); + sellPrices[work++] = intceil(randfloat(1.4, rate) * basePrice) - 1; + + // decreasing phase after the peak + if (work < 14) + { + rate = randfloat(0.9, 0.4); + for (; work < 14; work++) + { + sellPrices[work] = intceil(rate * basePrice); + rate -= 0.03; + rate -= randfloat(0, 0.02); + } + } + */ + + buy_price = given_prices[0]; + var predicted_prices = [ + { + min: buy_price, + max: buy_price, + }, + { + min: buy_price, + max: buy_price, + }, + ]; + + var min_rate = 4000; + var max_rate = 9000; + + for (var i = 2; i < peak_start; i++) { + min_pred = Math.floor(min_rate * buy_price / 10000); + max_pred = Math.ceil(max_rate * buy_price / 10000); + + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); + max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + min_rate -= 500; + max_rate -= 300; + } + + // The peak + + for (var i = peak_start; i < peak_start+2; i++) { + min_pred = Math.floor(0.9 * buy_price); + max_pred = Math.ceil(1.4 * buy_price); + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + } + + // Main spike 1 + min_pred = Math.floor(1.4 * buy_price) - 1; + max_pred = Math.ceil(2.0 * buy_price) - 1; + if (!isNaN(given_prices[peak_start+2])) { + if (given_prices[peak_start+2] < min_pred || given_prices[peak_start+2] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[peak_start+2]; + max_pred = given_prices[peak_start+2]; + } + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + // Main spike 2 + min_pred = predicted_prices[peak_start+2].min; + max_pred = Math.ceil(2.0 * buy_price); + if (!isNaN(given_prices[peak_start+3])) { + if (given_prices[peak_start+3] < min_pred || given_prices[peak_start+3] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[peak_start+3]; + max_pred = given_prices[peak_start+3]; + } + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + // Main spike 3 + min_pred = Math.floor(1.4 * buy_price) - 1; + max_pred = predicted_prices[peak_start+3].max - 1; + if (!isNaN(given_prices[peak_start+4])) { + if (given_prices[peak_start+4] < min_pred || given_prices[peak_start+4] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[peak_start+4]; + max_pred = given_prices[peak_start+4]; + } + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + if (peak_start+5 < 14) { + var min_rate = 4000; + var max_rate = 9000; + + for (var i = peak_start+5; i < 14; i++) { + min_pred = Math.floor(min_rate * buy_price / 10000); + max_pred = Math.ceil(max_rate * buy_price / 10000); + + + if (!isNaN(given_prices[i])) { + if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { + // Given price is out of predicted range, so this is the wrong pattern + return; + } + min_pred = given_prices[i]; + max_pred = given_prices[i]; + min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); + max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); + } + + predicted_prices.push({ + min: min_pred, + max: max_pred, + }); + + min_rate -= 500; + max_rate -= 300; + } + } + + yield { + pattern_description: "decreasing, spike, decreasing", + pattern_number: 3, + prices: predicted_prices + }; +} + +function* generate_pattern_3(given_prices) { + for (var peak_start = 2; peak_start < 10; peak_start++) { + yield* generate_pattern_3_with_peak(given_prices, peak_start); + } +} + + +function* generate_possibilities(sell_prices) { + if (!isNaN(sell_prices[0])) { + yield* generate_pattern_0(sell_prices); + yield* generate_pattern_1(sell_prices); + yield* generate_pattern_2(sell_prices); + yield* generate_pattern_3(sell_prices); + } else { + for (var buy_price = 90; buy_price < 110; buy_price++) { + sell_prices[0] = sell_prices[1] = buy_price; + yield* generate_pattern_0(sell_prices); + yield* generate_pattern_1(sell_prices); + yield* generate_pattern_2(sell_prices); + yield* generate_pattern_3(sell_prices); + } + } +} + +function analyze_possibilities(sell_prices) { + generated_possibilities = Array.from(generate_possibilities(sell_prices)); + + global_min_max = []; + for (var day = 0; day < 14; day++) { + prices = { + min: 999, + max: 0, + } + for (let poss of generated_possibilities) { + if (poss.prices[day].min < prices.min) { + prices.min = poss.prices[day].min; + } + if (poss.prices[day].max > prices.max) { + prices.max = poss.prices[day].max; + } + } + global_min_max.push(prices); + } + + generated_possibilities.push({ + pattern_description: "predicted min/max across all patterns", + pattern_number: 4, + prices: global_min_max, + }); + + for (let poss of generated_possibilities) { + var weekMins = []; + var weekMaxes = []; + for (let day of poss.prices.slice(1)) { + weekMins.push(day.min); + weekMaxes.push(day.max); + } + poss.weekMin = Math.min(...weekMins); + poss.weekMax = Math.max(...weekMaxes); + } + + generated_possibilities.sort((a, b) => a.weekMax < b.weekMax); + + return generated_possibilities; +} diff --git a/js/scripts.js b/js/scripts.js index aaf46b5..b6221df 100644 --- a/js/scripts.js +++ b/js/scripts.js @@ -1,608 +1,3 @@ -function minimum_rate_from_given_and_base(given_price, buy_price) { - return 10000 * (given_price - 1) / buy_price; -} - -function maximum_rate_from_given_and_base(given_price, buy_price) { - return 10000 * given_price / buy_price; -} - -function* generate_pattern_0_with_lengths(given_prices, high_phase_1_len, dec_phase_1_len, high_phase_2_len, dec_phase_2_len, high_phase_3_len) { - /* - // PATTERN 0: high, decreasing, high, decreasing, high - work = 2; - - - // high phase 1 - for (int i = 0; i < hiPhaseLen1; i++) - { - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); - } - - // decreasing phase 1 - rate = randfloat(0.8, 0.6); - for (int i = 0; i < decPhaseLen1; i++) - { - sellPrices[work++] = intceil(rate * basePrice); - rate -= 0.04; - rate -= randfloat(0, 0.06); - } - - // high phase 2 - for (int i = 0; i < (hiPhaseLen2and3 - hiPhaseLen3); i++) - { - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); - } - - // decreasing phase 2 - rate = randfloat(0.8, 0.6); - for (int i = 0; i < decPhaseLen2; i++) - { - sellPrices[work++] = intceil(rate * basePrice); - rate -= 0.04; - rate -= randfloat(0, 0.06); - } - - // high phase 3 - for (int i = 0; i < hiPhaseLen3; i++) - { - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); - } - */ - - buy_price = given_prices[0]; - var predicted_prices = [ - { - min: buy_price, - max: buy_price, - }, - { - min: buy_price, - max: buy_price, - }, - ]; - - // High Phase 1 - for (var i = 2; i < 2 + high_phase_1_len; i++) { - min_pred = Math.floor(0.9 * buy_price); - max_pred = Math.ceil(1.4 * buy_price); - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - } - - // Dec Phase 1 - var min_rate = 6000; - var max_rate = 8000; - for (var i = 2 + high_phase_1_len; i < 2 + high_phase_1_len + dec_phase_1_len; i++) { - min_pred = Math.floor(min_rate * buy_price / 10000); - max_pred = Math.ceil(max_rate * buy_price / 10000); - - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); - max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - min_rate -= 1000; - max_rate -= 400; - } - - // High Phase 2 - for (var i = 2 + high_phase_1_len + dec_phase_1_len; i < 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len; i++) { - min_pred = Math.floor(0.9 * buy_price); - max_pred = Math.ceil(1.4 * buy_price); - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - } - - // Dec Phase 2 - var min_rate = 6000; - var max_rate = 8000; - for (var i = 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len; i < 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len + dec_phase_2_len; i++) { - min_pred = Math.floor(min_rate * buy_price / 10000); - max_pred = Math.ceil(max_rate * buy_price / 10000); - - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); - max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - min_rate -= 1000; - max_rate -= 400; - } - - // High Phase 3 - if (2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len + dec_phase_2_len + high_phase_3_len != 14) { - throw new Error("Phase lengths don't add up"); - } - for (var i = 2 + high_phase_1_len + dec_phase_1_len + high_phase_2_len + dec_phase_2_len; i < 14; i++) { - min_pred = Math.floor(0.9 * buy_price); - max_pred = Math.ceil(1.4 * buy_price); - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - } - yield { - pattern_description: "high, decreasing, high, decreasing, high", - pattern_number: 0, - prices: predicted_prices - }; -} - -function* generate_pattern_0(given_prices) { - /* - decPhaseLen1 = randbool() ? 3 : 2; - decPhaseLen2 = 5 - decPhaseLen1; - - hiPhaseLen1 = randint(0, 6); - hiPhaseLen2and3 = 7 - hiPhaseLen1; - hiPhaseLen3 = randint(0, hiPhaseLen2and3 - 1); - */ - for (var dec_phase_1_len = 2; dec_phase_1_len < 4; dec_phase_1_len++) { - for (var high_phase_1_len = 0; high_phase_1_len < 7; high_phase_1_len++) { - for (var high_phase_3_len = 0; high_phase_3_len < (7 - high_phase_1_len - 1 + 1); high_phase_3_len++) { - yield* generate_pattern_0_with_lengths(given_prices, high_phase_1_len, dec_phase_1_len, 7 - high_phase_1_len - high_phase_3_len, 5 - dec_phase_1_len, high_phase_3_len); - } - } - } -} - -function* generate_pattern_1_with_peak(given_prices, peak_start) { - /* - // PATTERN 1: decreasing middle, high spike, random low - peakStart = randint(3, 9); - rate = randfloat(0.9, 0.85); - for (work = 2; work < peakStart; work++) - { - sellPrices[work] = intceil(rate * basePrice); - rate -= 0.03; - rate -= randfloat(0, 0.02); - } - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); - sellPrices[work++] = intceil(randfloat(1.4, 2.0) * basePrice); - sellPrices[work++] = intceil(randfloat(2.0, 6.0) * basePrice); - sellPrices[work++] = intceil(randfloat(1.4, 2.0) * basePrice); - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); - for (; work < 14; work++) - { - sellPrices[work] = intceil(randfloat(0.4, 0.9) * basePrice); - } - */ - - buy_price = given_prices[0]; - var predicted_prices = [ - { - min: buy_price, - max: buy_price, - }, - { - min: buy_price, - max: buy_price, - }, - ]; - - var min_rate = 8500; - var max_rate = 9000; - - for (var i = 2; i < peak_start; i++) { - min_pred = Math.floor(min_rate * buy_price / 10000); - max_pred = Math.ceil(max_rate * buy_price / 10000); - - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); - max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - min_rate -= 500; - max_rate -= 300; - } - - // Now each day is independent of next - min_randoms = [0.9, 1.4, 2.0, 1.4, 0.9, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4] - max_randoms = [1.4, 2.0, 6.0, 2.0, 1.4, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9] - for (var i = peak_start; i < 14; i++) { - min_pred = Math.floor(min_randoms[i - peak_start] * buy_price); - max_pred = Math.ceil(max_randoms[i - peak_start] * buy_price); - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - } - yield { - pattern_description: "decreasing, high spike, random lows", - pattern_number: 1, - prices: predicted_prices - }; -} - -function* generate_pattern_1(given_prices) { - for (var peak_start = 3; peak_start < 10; peak_start++) { - yield* generate_pattern_1_with_peak(given_prices, peak_start); - } -} - -function* generate_pattern_2(given_prices) { - /* - // PATTERN 2: consistently decreasing - rate = 0.9; - rate -= randfloat(0, 0.05); - for (work = 2; work < 14; work++) - { - sellPrices[work] = intceil(rate * basePrice); - rate -= 0.03; - rate -= randfloat(0, 0.02); - } - break; - */ - - - buy_price = given_prices[0]; - var predicted_prices = [ - { - min: buy_price, - max: buy_price, - }, - { - min: buy_price, - max: buy_price, - }, - ]; - - var min_rate = 8500; - var max_rate = 9000; - for (var i = 2; i < 14; i++) { - min_pred = Math.floor(min_rate * buy_price / 10000); - max_pred = Math.ceil(max_rate * buy_price / 10000); - - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); - max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - min_rate -= 500; - max_rate -= 300; - } - yield { - pattern_description: "always decreasing", - pattern_number: 2, - prices: predicted_prices - }; -} - -function* generate_pattern_3_with_peak(given_prices, peak_start) { - - /* - // PATTERN 3: decreasing, spike, decreasing - peakStart = randint(2, 9); - - // decreasing phase before the peak - rate = randfloat(0.9, 0.4); - for (work = 2; work < peakStart; work++) - { - sellPrices[work] = intceil(rate * basePrice); - rate -= 0.03; - rate -= randfloat(0, 0.02); - } - - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * (float)basePrice); - sellPrices[work++] = intceil(randfloat(0.9, 1.4) * basePrice); - rate = randfloat(1.4, 2.0); - sellPrices[work++] = intceil(randfloat(1.4, rate) * basePrice) - 1; - sellPrices[work++] = intceil(rate * basePrice); - sellPrices[work++] = intceil(randfloat(1.4, rate) * basePrice) - 1; - - // decreasing phase after the peak - if (work < 14) - { - rate = randfloat(0.9, 0.4); - for (; work < 14; work++) - { - sellPrices[work] = intceil(rate * basePrice); - rate -= 0.03; - rate -= randfloat(0, 0.02); - } - } - */ - - buy_price = given_prices[0]; - var predicted_prices = [ - { - min: buy_price, - max: buy_price, - }, - { - min: buy_price, - max: buy_price, - }, - ]; - - var min_rate = 4000; - var max_rate = 9000; - - for (var i = 2; i < peak_start; i++) { - min_pred = Math.floor(min_rate * buy_price / 10000); - max_pred = Math.ceil(max_rate * buy_price / 10000); - - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); - max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - min_rate -= 500; - max_rate -= 300; - } - - // The peak - - for (var i = peak_start; i < peak_start+2; i++) { - min_pred = Math.floor(0.9 * buy_price); - max_pred = Math.ceil(1.4 * buy_price); - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - } - - // Main spike 1 - min_pred = Math.floor(1.4 * buy_price) - 1; - max_pred = Math.ceil(2.0 * buy_price) - 1; - if (!isNaN(given_prices[peak_start+2])) { - if (given_prices[peak_start+2] < min_pred || given_prices[peak_start+2] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[peak_start+2]; - max_pred = given_prices[peak_start+2]; - } - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - // Main spike 2 - min_pred = predicted_prices[peak_start+2].min; - max_pred = Math.ceil(2.0 * buy_price); - if (!isNaN(given_prices[peak_start+3])) { - if (given_prices[peak_start+3] < min_pred || given_prices[peak_start+3] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[peak_start+3]; - max_pred = given_prices[peak_start+3]; - } - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - // Main spike 3 - min_pred = Math.floor(1.4 * buy_price) - 1; - max_pred = predicted_prices[peak_start+3].max - 1; - if (!isNaN(given_prices[peak_start+4])) { - if (given_prices[peak_start+4] < min_pred || given_prices[peak_start+4] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[peak_start+4]; - max_pred = given_prices[peak_start+4]; - } - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - if (peak_start+5 < 14) { - var min_rate = 4000; - var max_rate = 9000; - - for (var i = peak_start+5; i < 14; i++) { - min_pred = Math.floor(min_rate * buy_price / 10000); - max_pred = Math.ceil(max_rate * buy_price / 10000); - - - if (!isNaN(given_prices[i])) { - if (given_prices[i] < min_pred || given_prices[i] > max_pred ) { - // Given price is out of predicted range, so this is the wrong pattern - return; - } - min_pred = given_prices[i]; - max_pred = given_prices[i]; - min_rate = minimum_rate_from_given_and_base(given_prices[i], buy_price); - max_rate = maximum_rate_from_given_and_base(given_prices[i], buy_price); - } - - predicted_prices.push({ - min: min_pred, - max: max_pred, - }); - - min_rate -= 500; - max_rate -= 300; - } - } - - yield { - pattern_description: "decreasing, spike, decreasing", - pattern_number: 3, - prices: predicted_prices - }; -} - -function* generate_pattern_3(given_prices) { - for (var peak_start = 2; peak_start < 10; peak_start++) { - yield* generate_pattern_3_with_peak(given_prices, peak_start); - } -} - - -function* generate_possibilities(sell_prices) { - if (!isNaN(sell_prices[0])) { - yield* generate_pattern_0(sell_prices); - yield* generate_pattern_1(sell_prices); - yield* generate_pattern_2(sell_prices); - yield* generate_pattern_3(sell_prices); - } else { - for (var buy_price = 90; buy_price < 110; buy_price++) { - sell_prices[0] = sell_prices[1] = buy_price; - yield* generate_pattern_0(sell_prices); - yield* generate_pattern_1(sell_prices); - yield* generate_pattern_2(sell_prices); - yield* generate_pattern_3(sell_prices); - } - } -} - -function analyze_possibilities(sell_prices) { - generated_possibilities = Array.from(generate_possibilities(sell_prices)); - - global_min_max = []; - for (var day = 0; day < 14; day++) { - prices = { - min: 999, - max: 0, - } - for (let poss of generated_possibilities) { - if (poss.prices[day].min < prices.min) { - prices.min = poss.prices[day].min; - } - if (poss.prices[day].max > prices.max) { - prices.max = poss.prices[day].max; - } - } - global_min_max.push(prices); - } - - generated_possibilities.push({ - pattern_description: "predicted min/max across all patterns", - pattern_number: 4, - prices: global_min_max, - }); - - for (let poss of generated_possibilities) { - var weekMins = []; - var weekMaxes = []; - for (let day of poss.prices.slice(1)) { - weekMins.push(day.min); - weekMaxes.push(day.max); - } - poss.weekMin = Math.min(...weekMins); - poss.weekMax = Math.max(...weekMaxes); - } - - generated_possibilities.sort((a, b) => a.weekMax < b.weekMax); - - return generated_possibilities; -} - $(document).ready(function () { // load sell_prices from local storage try {