mikebryant / ac-nh-turnip-prices Goto Github PK
View Code? Open in Web Editor NEWPrice calculator/predictor for Turnip prices
Home Page: https://turnipprophet.io
License: Apache License 2.0
Price calculator/predictor for Turnip prices
Home Page: https://turnipprophet.io
License: Apache License 2.0
I forgot my Monday AM prices, so I just entered the next 3 prices. The table shows me that my possible prices for Monday AM are 86..92, but if I update my Monday AM prices with either 86 or 92, no pattern is found, whereas with 87 to 91 it works fine.
I saw #8 but I'm not sure it's exactly the same issue. Sorry if it is.
If this is a different issue specific to these prices, here are the values to reproduce : buy price of 102, Monday PM 84, Tuesday AM 79, Tuesday PM 76.
Hi! I love this tool and use it every day with my friends :) It paid off last week when someone with a predicted high hit it (519 bells)!
I've been looking at the reverse engineered code, too, and have an idea I'd like to implement, and I'd be happy to take a stab at a pull request if you're interested. What we know is that each of the four price patterns have a chance of happening depending on the previous week's pattern. (So if you had a decreasing pattern last week, your chance of a large spike this week is 50%). Right now, each of the patterns are shown, but we don't have a sense of what are the odds of each pattern occurring.
I'm thinking of adding a dropdown where you can select which of the four patterns you had the previous week (or "unknown", the default choice). It won't be required, only if you happen to know what it is. The results will then calculate what are the odds of each pattern happening. And when we know some patterns won't happen, the chances will be recalculated based on available patterns. It should give someone much more clarity on what their odds are of hitting a large spike, given their prices and previous week's behavior!
Let me know what you think and if you would like me to help!
Disclosure: Webdev is a bit out of my field of expertise.
If there's interest for it and an API I can consume though, I can write a handy mobile app - just for the heck of it!
EDIT: I could always just write the prediction calculations myself, probably. But if somebody else has done that bit and got it working fine, I'd rather just collab with them on something than rewrite unnecessarily.
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;
The min and max prices for the 3rd and 5th periods of a small spike should be 1 lower than the min and max prices for the 4th period.
Once the 4th period's price is known, the max price for the 5th period should be 1 less than the 4th period's price.
Thanks for the handy tool!
Edit: I just noticed this is already mentioned in a TODO comment :)
Hello! Me again :D
I was wondering what is meant with high, decreasing, high, decreasing, high
Actually i'm in this prediction (very reliable)
and I'm wondering if "high" means that the price will always grow or if it will stay in the "high price" area...
Let me be more clear with an example:
An help box with the explaination of the pattern terms could be useful.
Thank you and great domain name :D
When entering the current price, I accidentally hit enter in an attempt to "submit" the value.
This sadly triggered the reset functionality, as it seems to try and submit the values with the next button (Reset Turnip Prophet)
It would be good to somehow prevent the enter event or to add some confirmation dialog
Based on my own turnip prices, and Treeki's original gist, I think there is a small inaccuracy with the spike in the "decreasing, spike, decreasing" pattern. Here's output from the website for my turnip prices (note the 86 value in both predictions):
According to the site, the min for when the spike starts is 86, but this is inconsistent with the Treeki's original gist. For this pattern, the spike values are calculated like so:
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;
So for basePrice=96
, the min for the start of the spike should be ceil(0.9*96) = 87
. Forgive me, I'm not 100% certain of the relevant part in the code, but it appears to be here where instead of Math.floor
it should be Math.ceil
I purchased my turnips yesterday for 104 apiece. This morning (Monday AM) they were 97, and now (Monday PM) they are 92.
I am 100% positive these are the correct prices, but the app has no patterns that allow for 92 right now if I purchased at 104 yesterday. Is this a floating point case or have I screwed up using it?
(Understood if it may be hard to solve from this minimal case, but it may help as a data point for another issue. This is also my third week in the stalk market, so I don't think anything special applies)
some statistic analysis will be nice, mean, median..etc, and it''s better to show total probability of pattern 0/1/2/3
here are some expected peak value of each pattern I derived from the code
mean_p0 = 1.3375
mean_p1 = 4
mean_p2 = 0.595 (or using current day price)
mean_p3 = 1.7
Hello!
It is possible in a near future to provide you a French translation? I would like to share your wonderful tool to some friends or people who are not good in English...
Similar to #36 but I think it would be useful to have the option to collapse or hide the columns from the data you've already entered (except perhaps the current day's prices). It's additional clutter and would be useful for clarity on remaining days.
Hi, I'm not sure if it's expected for the given ranges to be 100% accurate, but my turnip prices create 0 possible outcomes using your tool.
Buy 93
Monday AM: 115
Monday PM: ??? (Forgot to check)
Tuesday AM: 199
Tuesday PM: 215
If I enter just the "Buy" and "Monday AM" prices, I get a bunch of different outcomes, but the highest possible outcome is 186 for Tuesday AM.
When putting in a buy price and checking the box for first time buyer, instead of showing you only the options for small spike for your buy price, it shows all options for each buy price. I do not believe this is the intended functionality, I would assume you want to only show the options for your buy price. My guess that there is just a small issue with the JS that is not hiding the other options.
I would love to contribute to this project as well, I feel like more can be added to the already great tool you made (my thought is some sort of graph with a cone of uncertainty, since I am in Florida and love the cone of uncertainty from Hurricane season).
Once the box is checked for "First time buyer", there is no way to input the buy price. However, based on the rows that emerge, it appears that the buy price does affect the forecast. Is there way to address this?
For reference, the input I'm working w/ is:
The guaranteed minimum for "All Patterns" (the last row) appears to be taking the maximum of the minimums for the "All Patterns" row. However, it seems to me that the guaranteed minimum should actually be the minimum of the guaranteed minimums for all rows above it.
See below. The guaranteed minimum should be 128 rather than 78.
Per subject, is there a way to retrieve the turnip prices that were saved in localStorage on the github.io subdomain? Cheers
It'd be nice if you could optionally input the pattern you knew you had last week, and display and sort the probabilities for the next pattern based on these lines.
Or maybe on each individual prediction, whether it's good or bad?
Hi.
When entering the following values, I am getting my results as guaranteed Min 999 and potential Max as 0.
First time: No
Pattern: Decreasing
Buy Price: 101
Monday: 89AM - 77PM
When clearing the Buy Price it readjusts to Guaranteed min 89 and Potential max 139.
Any ideas why itβs not calculating correctly when I enter my buy price?
Hi. The idea would be to be able to put a url like this:
https://turnipprophet.io/index.html?buy=90&sell_2=80
And then it was automatically put into the buy input and added to the table.
Only these functions would be necessary:
function getSearchParameters() {
var prmstr = window.location.search.substr(1);
return prmstr != null && prmstr != "" ? transformToAssocArray(prmstr) : {};
}
function transformToAssocArray(prmstr) {
var params = {};
var prmarr = prmstr.split("&");
for (var i = 0; i < prmarr.length; i++) {
var tmparr = prmarr[i].split("=");
params[tmparr[0]] = tmparr[1];
}
return params;
}
With these functions it would only remain to do something similar to this when the page starts:
const params = getSearchParameters();
document.getElementById('buy').value = params.buy;
document.getElementById('sell_2').value = params.sell_2;
If you could please add it it would be great, if you have any questions don't hesitate to ask me and I will help you.
Thank you very much in advance, greetings!
Not sure how well that'll be accessible, but it's a 144X144 .png picture of a turnip! (copied after the in-game turnip icon!) with transparency~
Enjoy! ErinPeril (on insta by same name ;3)
ALT LINK: Turnip.png
Just noticed that the final two columns are Guaranteed Minimum
and Potential Maximum
. I am assuming both are meant for the highest price of the week, correct?
If that is the case, perhaps we should rename the guaranteed min column to something like "Lowest Potential Maximum" and the current potential max to "Highest Potential Maximum". Maybe it's just me, but "guaranteed minimum" seems to imply that turnips will not go below that price for the entire week.
I put in my totals for sun, Mon, Tues, and then after wed am entered, it showed the result as "all patterns" with 0-999 under every prediction. It is a first week input.
There are a few people who have shown interest in wanting to help out on different parts of the code.
I'd love to see this app flourish and become more widely used in the AC community, so I'd love to help this grow.
Hi, I have to say it is an amazing tool for turnip market. However I'm a little bit confused by how this tool defines a 'first time buyer'. My case is: Daisy Mae came to my island for the first time this week but I actually bought turnips from another island. So in this case should I mark myself as a first time buyer?
In another project, weβre using the chunk of code in scripts.js above the jQuery that does the actual predictions (generate_possibilities and everything it depends on). Weβre generating a google sheet instead of HTML. Itβd be nice if the prediction code was separate from the code that generates the HTML.
I was thinking the best way would be to move the code into another git repository and include it in this one as a sub module. That way your website is independent of the code that generates the predictions (would be nice for our project). Also we could make an npm package potentially.
Let me know what you think π
Request is to move week min/max to the front as I can scan possible high's before I dig into the specific data of the week.
A recent change has introduced a bug where the All Patterns result is now sorted among the rest of the pattern results, rather than being at the end of the list.
This appears to be the result of #64. In the PR the contributor notes that sorting did not work in Chrome, however my testing seems to indicate that the only browser it did work in was Chrome.
If anyone is working specifically on the design/styling, suggest making the scroll bars for the table at least twice as wide; as it is they are difficult to target.
Collapse this to a single number
We can calculate the steady state probability of any given pattern using a Markov model. Thus, we can get initial probabilities for the 4 states and display it to the users when they select "I don't know" for the "Previous Pattern". This builds on issue #13.
If my calculations are correct (details below; someone please verify), given no information about the previous week and no information on Mon - Sat for the current week, the chances for each pattern are:
pattern0: 0.346
pattern1: 0.247
pattern2: 0.148
pattern3: 0.259
I'm using a Markov chain with the pattern numbers & probabilities from Ninji's TurnipPrices::calculate()
. And, since I've not done these calculations in over a decade, I'm using an online calculator with the following data:
0.20 0.30 0.15 0.35
0.50 0.05 0.20 0.25
0.25 0.45 0.05 0.25
0.45 0.25 0.15 0.15
I'm not certain how this is affected by issue #48, which seeks to update probabilities based on Bayes. I suspect the problems are independent; that is, the solution for issue #48 will just work when given these probabilities. If not, maybe a HMM would work?
I'm in charge of an ACNH discord in Spanish and would love to help edit a Spanish version of the calculator, don't know much about HTML5 or coding in general, but could pass you a doc with full translations! Im awaiting any confirmation if my help is needed!
I am currently thinking that having shorter pattern names would be desirable.
I also think having a more detailed description of how they would work be nice.
My thoughts as to how to solve this are to put them in the table with short names, and on hover or tap on mobile they should explain what happens in longer words.
I tried to set my week and can't calculate it. If you put 130+ bells in any of the label gives you an error.
I bought turnips in Sunday at 91 bells.
Monday AM were at 120 bells
Monday PM were at 147 bells
Tuesday AM were at 197 bells
Tuesday PM were at 199 bells
Wednesday AM were at 99 bells
Wednesday PM were at 95 bells
Calculate across all possible predictions, and get the global minima and maxima per day
current algorithm calculates probability via redistribution probability based on user input price falling into some price intervals and rule out those impossible ones, right? But I think this way may not be accurate. (still a good approximation)
say 100 for buy price and 85 on MonAM and last week is pattern3, it rule out pattern0 and redistribute. Total probabilities are:
pattern1 = 0.25*1 /(0.25*1+0.15*7/8+0.15*1)=0.47/7=0.0672each
pattern2 = 0.15*7/8 /(0.25*1+0.15*7/8+0.15*1)=0.28
pattern3 = 0.15*1 /(0.25*1+0.15*7/8+0.15*1)=0.247/7=0.0353 each
But for pattern 1 and 2 (they follow same rule on Mon so treat as one), it needs : rate = 0.85 for rate = randfloat(0.85,0.9)
and for pattern3, it needs: rate = 0.85 for rate = randfloat(0.4,0.9)
clearly the probability for pattern3 to get rate = 0.85 is much smaller(10 times) than pattern 1 and 2
using bayes equation it should be:
pattern1 = 0.25*0.01/(0.9-0.85) /( 0.25*0.01/(0.9-0.85)+0.15*0.01/(0.9-0.4)+0.15*0.01/(0.9-0.85))=0.602/7=0.0860 each
pattern2 = 0.15*0.01/(0.9-0.85) /( 0.25*0.01/(0.9-0.85)+0.15*0.01/(0.9-0.4)+0.15*0.01/(0.9-0.85))=0.361
pattern3 = 0.15*0.01/(0.9-0.4) /( 0.25*0.01/(0.9-0.85)+0.15*0.01/(0.9-0.4)+0.15*0.01/(0.9-0.85))=0.0361/7=0.0051 each
or generally
P(pattern is k | input price is X) = P( X | k) *P(k) / sum(P( X | k) *P(k)) k from 0 to 3
key here is P( X | k)
, under pattern_k find probability of input price X, i think assuming X is uniformly distributed in calculated maxmin interval is a good start, since most of turnip price is generated by sellPrices[work++] = intceil(randfloat(A, B) * basePrice);
, only for decreasing pattern like
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);
}
the price X = A-sum(B_k), A and B are uniform distributed but X is bell shape distributed
The amount of white space is near blinding when playing the Stalk Market late at night. I would love to have a feature to enable dark mode!
Hello,
I was wondering if this could be an additional feature to continue with the statistic trend.
I made a working sample
for the current version as of 4/12/2020. It loops through the data found in the table and adds all of the percent chances per category.
I use the Custom JavaScript for Websites 2
extension for Chrome to run outside scripts into a page. If anyone wants to sample this in their own browser, you can use the following JavaScript code:
var trend = {};
function getChances() {
trend = {
random: {
chance: 0,
count: 0,
min: 0,
max: 0
},
down: {
chance: 0,
count: 0,
min: 0,
max: 0
},
small: {
chance: 0,
count: 0,
min: 0,
max: 0
},
large: {
chance: 0,
count: 0,
min: 0,
max: 0
}
}
$('#output tr').each(function(){
var type = $(this).children('td:nth-child(1)').text();
var percent = parseFloat($(this).children('td:nth-child(2)').text());
var low = parseInt($(this).children('td:nth-child(16)').text());
var high = parseInt($(this).children('td:nth-child(17)').text());
switch (type) {
case 'Fluctuating':
type = trend.random;
break;
case 'Decreasing':
type = trend.down;
break;
case 'Small spike':
type = trend.small;
break;
case 'Large spike':
type = trend.large;
break;
}
type.chance = percent;
type.count++;
type.min = low;
type.max = high;
});
var totalCount = trend.large.count + trend.small.count + trend.random.count + trend.down.count;
var randomChance = isNaN(trend.random.chance) ? `${((trend.random.count / totalCount) * 100).toFixed(0)}%` : `${(trend.random.chance * trend.random.count).toFixed(0)}%`;
var downChance = isNaN(trend.down.chance) ? `${((trend.down.count / totalCount) * 100).toFixed(0)}%` : `${(trend.down.chance * trend.down.count).toFixed(0)}%`;
var smallChance = isNaN(trend.small.chance) ? `${((trend.small.count / totalCount) * 100).toFixed(0)}%` : `${(trend.small.chance * trend.small.count).toFixed(0)}%`;
var largeChance = isNaN(trend.large.chance) ? `${((trend.large.count / totalCount) * 100).toFixed(0)}%` : `${(trend.large.chance * trend.large.count).toFixed(0)}%`;
$('.table-wrapper').before(`<div id="extraStats">
<style>
#extraStats, #extraStats>div {
width: 100%;
display: flex;
justify-content: space-around;
}
#extraStats>div>div>* {
text-align: center;
}
@media (max-width: 768px) {
#extraStats {
flex-direction: column;
}
}
</style>
<div>
<div>
<h2>Fluctuating</h2>
<h3>Chance: ${randomChance}</h3>
<h3>Min/Max: ${trend.random.min}~${trend.random.max}</h3>
</div>
<div>
<h2>Decreasing</h2>
<h3>Chance: ${downChance}</h3>
<h3>Min/Max: ${trend.down.min}~${trend.down.max}</h3>
</div>
</div>
<div>
<div>
<h2>Small Spike</h2>
<h3>Chance: ${smallChance}</h3>
<h3>Min/Max: ${trend.small.min}~${trend.small.max}</h3>
</div>
<div>
<h2>Large Spike</h2>
<h3>Chance: ${largeChance}</h3>
<h3>Min/Max: ${trend.large.min}~${trend.large.max}</h3>
</div>
</div>
</div>`);
}
getChances();
$('body').on('DOMSubtreeModified', '#output', function(){
$('#extraStats').remove();
getChances();
});
Edit: I have modified the above code to include other added suggestions discussed in this issue.
I'll try to be as clear as possible.
I noticed that "Week Max" column uses Sunday's buying price when it collects every price to get the highest, as we can see on this screenshot (I just removed all the other patterns with Ctrl+Shift+I). We can see that, on each prediction, I'll never reach 92 or more; however, Week Max returns 92, which is Sunday's price.
May be a useful visual representation of how much you stand to make. Obviously the math can be done manually very quickly but people appreciate the visual value done for them.
Hi,
I have tested your tool with the following pattern, which I just got :
Sell Price : 95
Buy Prices : 79, 76, 74, 69, 95, xx, 529
For the 6th value, it was around 145 but I can not tell more precisely (I sold them on an other island before that).
Even entering all the values, your tool can not predict the 529, nor the large spike. It will only predict a small spike if you do not enter the 6th or 7th value, and won't be able to tell the pattern if you do.
No time travel, and no FirstKabuBuy involved.
Thanks a lot for all your work :)
Regards,
Thanks for all your amazing work on this tool! I had a UX suggestion, and I hope this is the right place.
As a new user, I'm unable to determine what's the bare minimum number of data points needed to obtain an accurate estimate. I can enter just one data point and see results, but is this enough? The tool allows for data entry all the way until Saturday evening, which may cause users to question if they need to wait that long before getting accurate data and selling their turnips. I'm also not sure if missing a day (let's say I forget to check Tuesday morning) invalidates my projections for the week. Do I need to enter the purchase price from Daisy Mae? Or can the tool create an accurate estimate without it? Etc etc.
Some short descriptions added to the main page may help alleviate this!
I'd also recommend blocking projection generation if the user hasn't entered enough data, or hasn't entered required data. For example, if the purchase price from Daisy Mae hasn't been entered and is indeed essential for the projection, display a small note in place of the projection informing the player they need to enter this data first.
Reading the output table could be more intuitive if the rows were sorted by their probability, so that the most likely outcome is the first one that the user sees.
It would also be nice keep the "All patterns" row at the top of the table as a summary.
If either of these changes sound good, I'd be happy to make a pull request referencing this issue that implements them.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.