@ -1,7 +1,3 @@
// The reverse-engineered code is not perfectly accurate, especially as it's not
// 32-bit ARM floating point. So, be tolerant of slightly unexpected inputs
const FUDGE _FACTOR = 5 ;
const PATTERN = {
FLUCTUATING : 0 ,
LARGE _SPIKE : 1 ,
@ -38,43 +34,14 @@ const PROBABILITY_MATRIX = {
const RATE _MULTIPLIER = 10000 ;
function intceil ( val ) {
return Math . trunc ( val + 0.99999 ) ;
}
function minimum _rate _from _given _and _base ( given _price , buy _price ) {
return RATE _MULTIPLIER * ( given _price - 0.99999 ) / buy _price ;
}
function maximum _rate _from _given _and _base ( given _price , buy _price ) {
return RATE _MULTIPLIER * ( given _price + 0.00001 ) / buy _price ;
}
function rate _range _from _given _and _base ( given _price , buy _price ) {
return [
minimum _rate _from _given _and _base ( given _price , buy _price ) ,
maximum _rate _from _given _and _base ( given _price , buy _price )
] ;
}
function get _price ( rate , basePrice ) {
return intceil ( rate * basePrice / RATE _MULTIPLIER ) ;
}
function * multiply _generator _probability ( generator , probability ) {
for ( const it of generator ) {
yield { ... it , probability : it . probability * probability } ;
}
function range _length ( range ) {
return range [ 1 ] - range [ 0 ] ;
}
function clamp ( x , min , max ) {
return Math . min ( Math . max ( x , min ) , max ) ;
}
function range _length ( range ) {
return range [ 1 ] - range [ 0 ] ;
}
function range _intersect ( range1 , range2 ) {
if ( range1 [ 0 ] > range2 [ 1 ] || range1 [ 1 ] < range2 [ 0 ] ) {
return null ;
@ -89,54 +56,6 @@ function range_intersect_length(range1, range2) {
return range _length ( range _intersect ( range1 , range2 ) ) ;
}
/ *
* This corresponds to the code :
* for ( int i = start ; i < start + length ; i ++ )
* {
* sellPrices [ work ++ ] =
* intceil ( randfloat ( rate _min / RATE _MULTIPLIER , rate _max / RATE _MULTIPLIER ) * basePrice ) ;
* }
*
* Would return the conditional probability given the given _prices , and modify
* the predicted _prices array .
* If the given _prices won ' t match , returns 0.
* /
function generate _individual _random _price (
given _prices , predicted _prices , start , length , rate _min , rate _max ) {
rate _min *= RATE _MULTIPLIER ;
rate _max *= RATE _MULTIPLIER ;
const buy _price = given _prices [ 0 ] ;
const rate _range = [ rate _min , rate _max ] ;
let prob = 1 ;
for ( let i = start ; i < start + length ; i ++ ) {
let min _pred = get _price ( rate _min , buy _price ) ;
let max _pred = get _price ( rate _max , buy _price ) ;
if ( ! isNaN ( given _prices [ i ] ) ) {
if ( given _prices [ i ] < min _pred - FUDGE _FACTOR || given _prices [ i ] > max _pred + FUDGE _FACTOR ) {
// Given price is out of predicted range, so this is the wrong pattern
return 0 ;
}
// TODO: How to deal with probability when there's fudge factor?
// Clamp the value to be in range now so the probability won't be totally biased to fudged values.
const real _rate _range =
rate _range _from _given _and _base ( clamp ( given _prices [ i ] , min _pred , max _pred ) , buy _price ) ;
prob *= range _intersect _length ( rate _range , real _rate _range ) /
range _length ( rate _range ) ;
min _pred = given _prices [ i ] ;
max _pred = given _prices [ i ] ;
}
predicted _prices . push ( {
min : min _pred ,
max : max _pred ,
} ) ;
}
return prob ;
}
/ *
* Probability Density Function of rates .
* Since the PDF is continuous * , we approximate it by a discrete probability function :
@ -274,7 +193,94 @@ class PDF {
}
}
/ *
class Predictor {
constructor ( prices , first _buy , previous _pattern ) {
// The reverse-engineered code is not perfectly accurate, especially as it's not
// 32-bit ARM floating point. So, be tolerant of slightly unexpected inputs
this . fudge _factor = 0 ;
this . prices = prices ;
this . first _buy = first _buy ;
this . previous _pattern = previous _pattern ;
}
intceil ( val ) {
return Math . trunc ( val + 0.99999 ) ;
}
minimum _rate _from _given _and _base ( given _price , buy _price ) {
return RATE _MULTIPLIER * ( given _price - 0.99999 ) / buy _price ;
}
maximum _rate _from _given _and _base ( given _price , buy _price ) {
return RATE _MULTIPLIER * ( given _price + 0.00001 ) / buy _price ;
}
rate _range _from _given _and _base ( given _price , buy _price ) {
return [
this . minimum _rate _from _given _and _base ( given _price , buy _price ) ,
this . maximum _rate _from _given _and _base ( given _price , buy _price )
] ;
}
get _price ( rate , basePrice ) {
return this . intceil ( rate * basePrice / RATE _MULTIPLIER ) ;
}
* multiply _generator _probability ( generator , probability ) {
for ( const it of generator ) {
yield { ... it , probability : it . probability * probability } ;
}
}
/ *
* This corresponds to the code :
* for ( int i = start ; i < start + length ; i ++ )
* {
* sellPrices [ work ++ ] =
* intceil ( randfloat ( rate _min / RATE _MULTIPLIER , rate _max / RATE _MULTIPLIER ) * basePrice ) ;
* }
*
* Would return the conditional probability given the given _prices , and modify
* the predicted _prices array .
* If the given _prices won ' t match , returns 0.
* /
generate _individual _random _price (
given _prices , predicted _prices , start , length , rate _min , rate _max ) {
rate _min *= RATE _MULTIPLIER ;
rate _max *= RATE _MULTIPLIER ;
const buy _price = given _prices [ 0 ] ;
const rate _range = [ rate _min , rate _max ] ;
let prob = 1 ;
for ( let i = start ; i < start + length ; i ++ ) {
let min _pred = this . get _price ( rate _min , buy _price ) ;
let max _pred = this . get _price ( rate _max , buy _price ) ;
if ( ! isNaN ( given _prices [ i ] ) ) {
if ( given _prices [ i ] < min _pred - this . fudge _factor || given _prices [ i ] > max _pred + this . fudge _factor ) {
// Given price is out of predicted range, so this is the wrong pattern
return 0 ;
}
// TODO: How to deal with probability when there's fudge factor?
// Clamp the value to be in range now so the probability won't be totally biased to fudged values.
const real _rate _range =
this . rate _range _from _given _and _base ( clamp ( given _prices [ i ] , min _pred , max _pred ) , buy _price ) ;
prob *= range _intersect _length ( rate _range , real _rate _range ) /
range _length ( rate _range ) ;
min _pred = given _prices [ i ] ;
max _pred = given _prices [ i ] ;
}
predicted _prices . push ( {
min : min _pred ,
max : max _pred ,
} ) ;
}
return prob ;
}
/ *
* This corresponds to the code :
* rate = randfloat ( start _rate _min , start _rate _max ) ;
* for ( int i = start ; i < start + length ; i ++ )
@ -287,7 +293,7 @@ class PDF {
* the predicted _prices array .
* If the given _prices won ' t match , returns 0.
* /
function generate _decreasing _random _price (
generate _decreasing _random _price (
given _prices , predicted _prices , start , length , start _rate _min ,
start _rate _max , rate _decay _min , rate _decay _max ) {
start _rate _min *= RATE _MULTIPLIER ;
@ -300,17 +306,17 @@ function generate_decreasing_random_price(
let prob = 1 ;
for ( let i = start ; i < start + length ; i ++ ) {
let min _pred = get _price ( rate _pdf . min _value ( ) , buy _price ) ;
let max _pred = get _price ( rate _pdf . max _value ( ) , buy _price ) ;
let min _pred = this . get _price ( rate _pdf . min _value ( ) , buy _price ) ;
let max _pred = this . get _price ( rate _pdf . max _value ( ) , buy _price ) ;
if ( ! isNaN ( given _prices [ i ] ) ) {
if ( given _prices [ i ] < min _pred - FUDGE _FACTOR || given _prices [ i ] > max _pred + FUDGE _FACTOR ) {
if ( given _prices [ i ] < min _pred - this . fudge _factor || given _prices [ i ] > max _pred + this . fudge _factor ) {
// Given price is out of predicted range, so this is the wrong pattern
return 0 ;
}
// TODO: How to deal with probability when there's fudge factor?
// Clamp the value to be in range now so the probability won't be totally biased to fudged values.
const real _rate _range =
rate _range _from _given _and _base ( clamp ( given _prices [ i ] , min _pred , max _pred ) , buy _price ) ;
this . rate _range _from _given _and _base ( clamp ( given _prices [ i ] , min _pred , max _pred ) , buy _price ) ;
prob *= rate _pdf . range _limit ( real _rate _range ) ;
if ( prob == 0 ) {
return 0 ;
@ -327,10 +333,10 @@ function generate_decreasing_random_price(
rate _pdf . decay ( rate _decay _min , rate _decay _max ) ;
}
return prob ;
}
}
/ *
/ *
* This corresponds to the code :
* rate = randfloat ( rate _min , rate _max ) ;
* sellPrices [ work ++ ] = intceil ( randfloat ( rate _min , rate ) * basePrice ) - 1 ;
@ -341,7 +347,7 @@ function generate_decreasing_random_price(
* the predicted _prices array .
* If the given _prices won ' t match , returns 0.
* /
function generate _peak _price (
generate _peak _price (
given _prices , predicted _prices , start , rate _min , rate _max ) {
rate _min *= RATE _MULTIPLIER ;
rate _max *= RATE _MULTIPLIER ;
@ -354,16 +360,16 @@ function generate_peak_price(
// Prob(middle_price)
const middle _price = given _prices [ start + 1 ] ;
if ( ! isNaN ( middle _price ) ) {
const min _pred = get _price ( rate _min , buy _price ) ;
const max _pred = get _price ( rate _max , buy _price ) ;
if ( middle _price < min _pred - FUDGE _FACTOR || middle _price > max _pred + FUDGE _FACTOR ) {
const min _pred = this . get _price ( rate _min , buy _price ) ;
const max _pred = this . get _price ( rate _max , buy _price ) ;
if ( middle _price < min _pred - this . fudge _factor || middle _price > max _pred + this . fudge _factor ) {
// Given price is out of predicted range, so this is the wrong pattern
return 0 ;
}
// TODO: How to deal with probability when there's fudge factor?
// Clamp the value to be in range now so the probability won't be totally biased to fudged values.
const real _rate _range =
rate _range _from _given _and _base ( clamp ( middle _price , min _pred , max _pred ) , buy _price ) ;
this . rate _range _from _given _and _base ( clamp ( middle _price , min _pred , max _pred ) , buy _price ) ;
prob *= range _intersect _length ( rate _range , real _rate _range ) /
range _length ( rate _range ) ;
if ( prob == 0 ) {
@ -393,15 +399,15 @@ function generate_peak_price(
if ( isNaN ( price ) ) {
continue ;
}
const min _pred = get _price ( rate _min , buy _price ) - 1 ;
const max _pred = get _price ( rate _range [ 1 ] , buy _price ) - 1 ;
if ( price < min _pred - FUDGE _FACTOR || price > max _pred + FUDGE _FACTOR ) {
const min _pred = this . get _price ( rate _min , buy _price ) - 1 ;
const max _pred = this . get _price ( rate _range [ 1 ] , buy _price ) - 1 ;
if ( price < min _pred - this . fudge _factor || price > max _pred + this . fudge _factor ) {
// Given price is out of predicted range, so this is the wrong pattern
return 0 ;
}
// TODO: How to deal with probability when there's fudge factor?
// Clamp the value to be in range now so the probability won't be totally biased to fudged values.
const rate2 _range = rate _range _from _given _and _base ( clamp ( price , min _pred , max _pred ) + 1 , buy _price ) ;
const rate2 _range = this . rate _range _from _given _and _base ( clamp ( price , min _pred , max _pred ) + 1 , buy _price ) ;
const F = ( t , ZZ ) => {
if ( t <= 0 ) {
return 0 ;
@ -424,8 +430,8 @@ function generate_peak_price(
// since forward prediction is more useful here.
//
// Main spike 1
min _pred = get _price ( rate _min , buy _price ) - 1 ;
max _pred = get _price ( rate _max , buy _price ) - 1 ;
let min _pred = this . get _price ( rate _min , buy _price ) - 1 ;
let max _pred = this . get _price ( rate _max , buy _price ) - 1 ;
if ( ! isNaN ( given _prices [ start ] ) ) {
min _pred = given _prices [ start ] ;
max _pred = given _prices [ start ] ;
@ -437,7 +443,7 @@ function generate_peak_price(
// Main spike 2
min _pred = predicted _prices [ start ] . min ;
max _pred = get _price ( rate _max , buy _price ) ;
max _pred = this . get _price ( rate _max , buy _price ) ;
if ( ! isNaN ( given _prices [ start + 1 ] ) ) {
min _pred = given _prices [ start + 1 ] ;
max _pred = given _prices [ start + 1 ] ;
@ -448,7 +454,7 @@ function generate_peak_price(
} ) ;
// Main spike 3
min _pred = get _price ( rate _min , buy _price ) - 1 ;
min _pred = this . get _price ( rate _min , buy _price ) - 1 ;
max _pred = predicted _prices [ start + 1 ] . max - 1 ;
if ( ! isNaN ( given _prices [ start + 2 ] ) ) {
min _pred = given _prices [ start + 2 ] ;
@ -460,10 +466,9 @@ function generate_peak_price(
} ) ;
return prob ;
}
}
function *
generate _pattern _0 _with _lengths (
* 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 ) {
/ *
@ -516,14 +521,14 @@ function*
let probability = 1 ;
// High Phase 1
probability *= generate _individual _random _price (
probability *= this . generate _individual _random _price (
given _prices , predicted _prices , 2 , high _phase _1 _len , 0.9 , 1.4 ) ;
if ( probability == 0 ) {
return ;
}
// Dec Phase 1
probability *= generate _decreasing _random _price (
probability *= this . generate _decreasing _random _price (
given _prices , predicted _prices , 2 + high _phase _1 _len , dec _phase _1 _len ,
0.6 , 0.8 , 0.04 , 0.1 ) ;
if ( probability == 0 ) {
@ -531,14 +536,14 @@ function*
}
// High Phase 2
probability *= generate _individual _random _price ( given _prices , predicted _prices ,
probability *= this . generate _individual _random _price ( given _prices , predicted _prices ,
2 + high _phase _1 _len + dec _phase _1 _len , high _phase _2 _len , 0.9 , 1.4 ) ;
if ( probability == 0 ) {
return ;
}
// Dec Phase 2
probability *= generate _decreasing _random _price (
probability *= this . generate _decreasing _random _price (
given _prices , predicted _prices ,
2 + high _phase _1 _len + dec _phase _1 _len + high _phase _2 _len ,
dec _phase _2 _len , 0.6 , 0.8 , 0.04 , 0.1 ) ;
@ -553,7 +558,7 @@ function*
const prev _length = 2 + high _phase _1 _len + dec _phase _1 _len +
high _phase _2 _len + dec _phase _2 _len ;
probability *= generate _individual _random _price (
probability *= this . generate _individual _random _price (
given _prices , predicted _prices , prev _length , 14 - prev _length , 0.9 , 1.4 ) ;
if ( probability == 0 ) {
return ;
@ -565,9 +570,9 @@ function*
prices : predicted _prices ,
probability ,
} ;
}
}
function * generate _pattern _0 ( given _prices ) {
* generate _pattern _0 ( given _prices ) {
/ *
decPhaseLen1 = randbool ( ) ? 3 : 2 ;
decPhaseLen2 = 5 - decPhaseLen1 ;
@ -578,15 +583,15 @@ function* generate_pattern_0(given_prices) {
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 * multiply _generator _probability (
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 ) ,
yield * this . multiply _generator _probability (
this . 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 ) ,
1 / ( 4 - 2 ) / 7 / ( 7 - high _phase _1 _len ) ) ;
}
}
}
}
}
function * generate _pattern _1 _with _peak ( given _prices , peak _start ) {
* generate _pattern _1 _with _peak ( given _prices , peak _start ) {
/ *
// PATTERN 1: decreasing middle, high spike, random low
peakStart = randint ( 3 , 9 ) ;
@ -621,17 +626,17 @@ function* generate_pattern_1_with_peak(given_prices, peak_start) {
] ;
let probability = 1 ;
probability *= generate _decreasing _random _price (
probability *= this . generate _decreasing _random _price (
given _prices , predicted _prices , 2 , peak _start - 2 , 0.85 , 0.9 , 0.03 , 0.05 ) ;
if ( probability == 0 ) {
return ;
}
// 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 ]
let min _randoms = [ 0.9 , 1.4 , 2.0 , 1.4 , 0.9 , 0.4 , 0.4 , 0.4 , 0.4 , 0.4 , 0.4 ]
let 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 ( let i = peak _start ; i < 14 ; i ++ ) {
probability *= generate _individual _random _price (
probability *= this . generate _individual _random _price (
given _prices , predicted _prices , i , 1 , min _randoms [ i - peak _start ] ,
max _randoms [ i - peak _start ] ) ;
if ( probability == 0 ) {
@ -644,15 +649,15 @@ function* generate_pattern_1_with_peak(given_prices, peak_start) {
prices : predicted _prices ,
probability ,
} ;
}
}
function * generate _pattern _1 ( given _prices ) {
* generate _pattern _1 ( given _prices ) {
for ( var peak _start = 3 ; peak _start < 10 ; peak _start ++ ) {
yield * multiply _generator _probability ( generate _pattern _1 _with _peak ( given _prices , peak _start ) , 1 / ( 10 - 3 ) ) ;
yield * this . multiply _generator _probability ( this . generate _pattern _1 _with _peak ( given _prices , peak _start ) , 1 / ( 10 - 3 ) ) ;
}
}
}
function * generate _pattern _2 ( given _prices ) {
* generate _pattern _2 ( given _prices ) {
/ *
// PATTERN 2: consistently decreasing
rate = 0.9 ;
@ -679,7 +684,7 @@ function* generate_pattern_2(given_prices) {
] ;
let probability = 1 ;
probability *= generate _decreasing _random _price (
probability *= this . generate _decreasing _random _price (
given _prices , predicted _prices , 2 , 14 - 2 , 0.85 , 0.9 , 0.03 , 0.05 ) ;
if ( probability == 0 ) {
return ;
@ -691,9 +696,9 @@ function* generate_pattern_2(given_prices) {
prices : predicted _prices ,
probability ,
} ;
}
}
function * generate _pattern _3 _with _peak ( given _prices , peak _start ) {
* generate _pattern _3 _with _peak ( given _prices , peak _start ) {
/ *
// PATTERN 3: decreasing, spike, decreasing
@ -738,27 +743,27 @@ function* generate_pattern_3_with_peak(given_prices, peak_start) {
] ;
let probability = 1 ;
probability *= generate _decreasing _random _price (
probability *= this . generate _decreasing _random _price (
given _prices , predicted _prices , 2 , peak _start - 2 , 0.4 , 0.9 , 0.03 , 0.05 ) ;
if ( probability == 0 ) {
return ;
}
// The peak
probability *= generate _individual _random _price (
probability *= this . generate _individual _random _price (
given _prices , predicted _prices , peak _start , 2 , 0.9 , 1.4 ) ;
if ( probability == 0 ) {
return ;
}
probability *= generate _peak _price (
probability *= this . generate _peak _price (
given _prices , predicted _prices , peak _start + 2 , 1.4 , 2.0 ) ;
if ( probability == 0 ) {
return ;
}
if ( peak _start + 5 < 14 ) {
probability *= generate _decreasing _random _price (
probability *= this . generate _decreasing _random _price (
given _prices , predicted _prices , peak _start + 5 , 14 - ( peak _start + 5 ) ,
0.4 , 0.9 , 0.03 , 0.05 ) ;
if ( probability == 0 ) {
@ -772,52 +777,66 @@ function* generate_pattern_3_with_peak(given_prices, peak_start) {
prices : predicted _prices ,
probability ,
} ;
}
}
function * generate _pattern _3 ( given _prices ) {
* generate _pattern _3 ( given _prices ) {
for ( let peak _start = 2 ; peak _start < 10 ; peak _start ++ ) {
yield * multiply _generator _probability ( generate _pattern _3 _with _peak ( given _prices , peak _start ) , 1 / ( 10 - 2 ) ) ;
yield * this . multiply _generator _probability ( this . generate _pattern _3 _with _peak ( given _prices , peak _start ) , 1 / ( 10 - 2 ) ) ;
}
}
}
function get _transition _probability ( previous _pattern ) {
get _transition _probability ( previous _pattern ) {
if ( typeof previous _pattern === 'undefined' || Number . isNaN ( previous _pattern ) || previous _pattern === null || previous _pattern < 0 || previous _pattern > 3 ) {
// TODO: Fill the steady state pattern (https://github.com/mikebryant/ac-nh-turnip-prices/pull/90) here.
return [ 0.346278 , 0.247363 , 0.147607 , 0.258752 ] ;
// Use the steady state probabilities of PROBABILITY_MATRIX if we don't
// know what the previous pattern was.
// See https://github.com/mikebryant/ac-nh-turnip-prices/issues/68
// and https://github.com/mikebryant/ac-nh-turnip-prices/pull/90
// for more information.
return [ 4530 / 13082 , 3236 / 13082 , 1931 / 13082 , 3385 / 13082 ] ;
}
return PROBABILITY _MATRIX [ previous _pattern ] ;
}
}
function * generate _all _patterns ( sell _prices , previous _pattern ) {
const generate _pattern _fns = [ generate _pattern _0 , generate _pattern _1 , generate _pattern _2 , generate _pattern _3 ] ;
const transition _probability = get _transition _probability ( previous _pattern ) ;
* generate _all _patterns ( sell _prices , previous _pattern ) {
const generate _pattern _fns = [ this . generate _pattern _0 , this . generate _pattern _1 , this . generate _pattern _2 , this . generate _pattern _3 ] ;
const transition _probability = this . get _transition _probability ( previous _pattern ) ;
for ( let i = 0 ; i < 4 ; i ++ ) {
yield * multiply _generator _probability ( generate _pattern _fns [ i ] ( sell _prices ) , transition _probability [ i ] ) ;
yield * this . multiply _generator _probability ( generate _pattern _fns [ i ] . bind ( this ) ( sell _prices ) , transition _probability [ i ] ) ;
}
}
}
function * generate _possibilities ( sell _prices , first _buy , previous _pattern ) {
* generate _possibilities ( sell _prices , first _buy , previous _pattern ) {
if ( first _buy || isNaN ( sell _prices [ 0 ] ) ) {
for ( var buy _price = 90 ; buy _price <= 110 ; buy _price ++ ) {
sell _prices [ 0 ] = sell _prices [ 1 ] = buy _price ;
if ( first _buy ) {
yield * generate _pattern _3 ( sell _prices ) ;
yield * this . generate _pattern _3 ( sell _prices ) ;
} else {
// All buy prices are equal probability and we're at the outmost layer,
// so don't need to multiply_generator_probability here.
yield * generate _all _patterns ( sell _prices , previous _pattern )
yield * this . generate _all _patterns ( sell _prices , previous _pattern )
}
}
} else {
yield * generate _all _patterns ( sell _prices , previous _pattern )
yield * this . generate _all _patterns ( sell _prices , previous _pattern )
}
}
}
function analyze _possibilities ( sell _prices , first _buy , previous _pattern ) {
const generated _possibilities = Array . from ( generate _possibilities ( sell _prices , first _buy , previous _pattern ) ) ;
console . log ( generated _possibilities ) ;
analyze _possibilities ( ) {
const sell _prices = this . prices ;
const first _buy = this . first _buy ;
const previous _pattern = this . previous _pattern ;
let generated _possibilities = [ ]
for ( let i = 0 ; i < 6 ; i ++ ) {
this . fudge _factor = i ;
generated _possibilities = Array . from ( this . generate _possibilities ( sell _prices , first _buy , previous _pattern ) ) ;
if ( generated _possibilities . length > 0 ) {
console . log ( "Generated possibilities using fudge factor %d: " , i , generated _possibilities ) ;
break ;
}
}
const total _probability = generated _possibilities . reduce ( ( acc , it ) => acc + it . probability , 0 ) ;
for ( const it of generated _possibilities ) {
@ -846,7 +865,7 @@ function analyze_possibilities(sell_prices, first_buy, previous_pattern) {
poss . weekMax = Math . max ( ... weekMaxes ) ;
}
category _totals = { }
let category _totals = { }
for ( let i of [ 0 , 1 , 2 , 3 ] ) {
category _totals [ i ] = generated _possibilities
. filter ( value => value . pattern _number == i )
@ -862,7 +881,7 @@ function analyze_possibilities(sell_prices, first_buy, previous_pattern) {
return b . category _total _probability - a . category _total _probability || b . probability - a . probability ;
} ) ;
global _min _max = [ ] ;
let global _min _max = [ ] ;
for ( var day = 0 ; day < 14 ; day ++ ) {
prices = {
min : 999 ,
@ -888,4 +907,5 @@ function analyze_possibilities(sell_prices, first_buy, previous_pattern) {
} ) ;
return generated _possibilities ;
}
}