Repository navigation
Try fixing non-US stock charts - #190
Conversation
|
Hey thanks! Yeah this is pretty much what I envisioned for generating a discrete axis for each stock based on its market times. I don't expect us to be 100% accurate and I think that's okay for this application, but we should still strive to tackle known gaps that we have the ability to identify & correct. Holidays are probably out of scope if we can't get them. This seems to assume market open / close fall on the same UTC day, so that's one change we need to potentially address. We also don't account for DST adjustments in our seek logic at week end to week start. Also, we probably don't want to do this for Lastly it seems like our market start - timeframe adjusted start time is off, as it includes the partial previous day to the actual start of the (1W == 5 full business days), giving a small to big gap on the left edge of the non-1D charts. We should saturate the adjusted start on the start of the first full day. We can do this by seeking to the start of the next business day start time first, then seeking back the |
|
|
|
A few things I'm noticing in testing between
Edit: Can we still use SPY / DEFAULT_TIMESTAMPS as a proxy for 1W+ adjusted start date (then add market aware time to it) so we're always aligned with how Yahoo specifies its ranges? |
Can't reproduce it either anymore. I honestly don't remember if I fixed it or not. Thankfully it's easy to notice if it reappears.
Can confirm, the old one is more accurate. Using the raw values is absolutely the way to go here, I'll do that.
Do you mean we should use both DEFAULT_TIMESTAMPS and MarketTimes (prev. MarketHours) so that the dataset items may align to either of those in order to be accepted? |
I just mean we use it as a proxy for the adjusted start that is passed into |
That still produces quite large borders with 1W and 1M. 1W goes from Friday 5/1 to Friday 4/24, which is not a weekend. For some reason 4/24 is completely empty. |
Right, this will be difficult to get right which is why I suggest we proxy start off SPY and run the market times fill from there |
Aight, I'll look into this tomorrow since it's past 1AM here :D |
Gn! Thanks for tackling this, it's coming along nicely. |
|
After SPY proxy there are still (at least) two things that should be addressed: Is there anything we can do to account for DST? I'm not exactly sure how it works currently and it's not that trivial to test it. What about the volume alignment issue? A quick git bisect led me to the initial commit from this PR, but other than that I can't seem to find the root cause. This is even though it uses the same normalized values as the price chart and the date labels. |
|
I changed the keybinds up a bit. The primary change is that now tab/shift+tab modifies the time frame whereas the arrow keys change the selected stock. I made this change to unify how stock changing and swapping works. Before you would change the stock selection using tab and swap them using the arrow keys with a modifier. Now both are done with the arrow keys. I would've kept having tab as the way to change stocks, but there aren't any modifiers left to apply for the swap action after having assigned shift+tab already. |
|
Turns out it was curl-sys which was updated while updating the lock file |
|
@ymcx nice work w/ all the new changes. Can you please split all of those commits into a new branch / PR? I'm fine if they're all bundled together, but I'd prefer they existed separate from the x-axis work you're doing since that's a bigger change & I want to keep it isolated for review & testing purposes. Also, what's the latest status on the x-axis changes? Are there still pending changes, such as the SPY adjusted start proxy value? |
Sure, I'll open a new PR with all of these changes if that's okay. I kind of lost myself in just implementing new features and now this PR has became much bigger than what I anticipated. After all these are some of my first years programming, so I'm still somewhat trying to figure out how things should be done in a manner that is expected from us.
Haven't yet been able to really focus on that since I figured I would first do the cosmetic changes and stuff before getting back to fixing the initial issue. But as you can see, that hasn't worked out so well since I constantly had new ideas that got the priority. |
|
I created another branch for this bugfix, you can find it here https://github.com/ymcx/tickrs/tree/fix-charts. I'll perhaps make a new PR (again) once it's done? Anyway, with your suggestion of using DEFAULT_TIMESTAMPS as a proxy for 1M and up, INTC works flawlessly without any kind of gaps or smoothness. As for NOVO-B.CO, from 1M onwards it starts getting both more smooth and the same gaps appear that were there without DEFAULT_TIMESTAMPS. |
|
Can't we just create a new DefaultTimestampService for each stock? I tried that and not only is the result literally perfect, but it also requires much less code. |
What does this look like? |
As good as every NYSE stock did, since after all, we're using the exact same method, now just for each stock separately |
|
I'll submit this as a standalone PR since this is much better as long as it's fine if we fetch the default times for each stock separately. There isn't really any other reason not to. |
I'm sorry for all of the headache this has caused :D |
c6f29fe to
1f171ea
Compare
No worries at all :) Yeah you can always just force push to a branch to rewrite its history. I'd highly recommend checking out |
@ymcx what did you think about this? |
I think I've actually heard about jj on HN, but never bothered to check it out as git is the industry standard (I know that it's somehow compatible with git). Now that you piqued my interest, I'll absolutely take the time to actually try it out someday.
I'm not totally sure on how the timestamps are currently fetched based on the given ticker (SPY in this case), but to me it seems like we're getting the market opening and closing time for the stock in question and turning it into a time series using a delta, correct? And basing off of that, it seems reasonable to fetch the start and end times (via default_timestamps) for each stock (/ stock exchange) separately, as that will take care of timezone differences, the actual amount of time the market will be open and probably even the holidays? Running a background service for something so apparently trivial seems unnecessary, but I think it's cleaner to do it this way in contrast to having to deal with custom deltas that need to be added to the timestamps of NYSE. The last approach involved a lot of hacky code just so we could correctly handle all of the edge cases and it still felt brittle with those pesky gaps and smoothing effect appearing sometimes, for no apparent reason. I'm cool with doing it that way, but I'm out of ideas on how we would actually make it work. I'm all ears if come up with a clever solution. |
|
I'm still not sure I follow how running I agree its wasteful to run this additional task, but we already know theres some issues in trying to manually project out the adjusted start time based on If we use SPY as the proxy, it should be close enough and probably closer than our manual adjusted logic. All we need to do is normalize that first SPY timestamp to the current stocks timezone / regular market start_time and our We already incur the cost of this task today, so its not a regression in performance. Ideally we can get rid of it, but without a known, pure accurate adjusted start time computation, I think its the best we have. |
|
I put the following code in prices() in src/widget/stock.rs: Now when I open tickrs using a time frame of one week and switch between stocks that are not on the same stock exchange, something like this gets appended to the logs: The goal of this is to make non-US stocks work just as well as US stocks do. Currently we have timestamps that follow NYSE and when there is a stock that isn't on NYSE, i.e. its market opens at a different time, we're discarding everything that doesn't fall within the NYSE window. This is why NOVO-B.CO on the Copenhagen stock exchange was cut off to just a couple of hours of data each day with the rest being a straight line to the next item on the next day when viewing on 1W. So if the problem is that earlier we had to choose which exchange to follow (we chose NYSE via SPY), we would be able to solve the problem by calculating the same for each stock or more specifically each exchange or market start/end time.
Exactly, but now the problem becomes how do we get that time delta? You're correct in saying that this doesn't help much in the sense that we're just fetching the time delta between whatever timezone NYSE uses and the timezone of the stock exchange of the current stock. I figured that this would be the easiest approach to gather that data without the need of perhaps hard-coding the time deltas of each stock exchange and then also trying to somehow deal with DST (I'm not sure if it works OOTB when using Unix epoch). If I'm understanding you correctly, the biggest issue you have with this approach is that we're wasting Yahoo's resources by pinging them more often than absolutely necessary, then yes, I agree. What do you think, would it be better to instead try to calculate the time delta ourselves using some hardcoded data about the exchanges? |
Can't we use We can also do a If Considering all of that, we should have something very accurate or accurate enough for our purposes. |
I didn't realize we already had the market opening time. In that case, we can indeed use it to calculate the exact same thing. I'll update the PR to use this approach instead. |
|
That makes sense. Instead of fitting the data to a generated discrete axis over the entire time frame, should we just sandwich the actual chart data between two projected axes? Those projected axes use the MarketTimes iterator and on the happy path will be empty if the actual chart data spans the entire time frame. For stocks where they started / stopped trading somewhere within the timeframe, it'll fill in that gap. adjusted_start..start | start..end | end..adjusted_end Then we'll never show the holiday gaps within the actual chart data since Yahoo doesn't produce data for those. Wdyt? |
|
I'm having a hard time wrapping my head around what exactly you're proposing. Do you mean we should use the new approach with default_timestamps + the delta and then add a fallback, MarketTimes, which will catch all items that didn't match default_timestamps due to differences in market hours compared to NYSE? |
|
Ok, I think we need to align on a few things, especially because you rolled back the On this current branch, you fetching I'm suggesting we use the This has the benefit of:
The rust code would be something like: let (adj_start, adj_end) = self.adjusted_start_end(prices);
let delta = self.time_frame.round_by();
let start = prices.first().unwrap().date;
let end = prices.last().unwrap().date;
let fill_before = MarketTimes::new(adj_start, start, delta);
let fill_after = MarketTimes::new(end, adj_end, delta);
fill_before
.map(Price::new)
.chain(
prices
.iter()
// Needed to filter out pre / post market data if pre / post is disabled
.filter(|p| p.date >= adj_start && p.date < adj_end)
.copied(),
)
.chain(fill_after.map(Price::new))
.collect() |
|
Aight I think I understood. I'll see how it goes and report back either tomorrow or today if the the change is trivial. |
|
Sounds good. Note I have a branch with this basically mocked up. Let me know if you want me to push it as a reference branch. Its based on your older commit history. Edit: Checkout |
|
This is what I came up with. Even though our implementations are not completely the same, it seems like they achieve the same end result. 1D is a little broken so I'll fix it later |
|
Nevermind, my approach is completely borked not only in 1D but also when padding it somehow divides the padding incorrectly. IMO we should just go with your approach since it seems to be working anyway. Will you merge your branch and then I'll go and close this PR for good? |
|
Sounds good. I'll force push that history to this branch so we don't lose all the comment history here and then I can merge. |
43a69e7 to
723f63e
Compare
I can't think of anything that we haven't discussed here already. Have you verified that holidays work correctly? X labels worked last time I checked, but what about volume bars? It's not like we touched them at all, but they used to be misaligned some commits ago.
Agreed. IMO we should just accept that the chart can't be rendered perfectly (or at least not with the current approach) and move on. Later down the line there might be reason to come back to this and really dive deep into why we have these deviations compared to Yahoo Finance's official charts etc. |
|
I don't mean to rush you, but will you be merging this? I'm waiting until this has been merged before submitting the keybind refactor so that there would be no merge conflicts. |
Merging now 👍 Sorry I lost track of this |
* Try fixing non-US stock charts * apply the linter suggestions * apply the linter suggestions 2 * apply the linter suggestions 3 * calculate the starting time from the next business day * fix crypto * handle everything (labels, chart, volume) using get_matching_prices, handle crypto there * potentially fix markets that open the day before they close * Add padding for non-1D charts based on market times --------- Co-authored-by: Cory Forsstrom <cforsstrom18@gmail.com>






Continuation of #186 and #184.
Stuff that might need to be taken care of before we can merge:
1. Account for holidays2. Make it work for market times that span from the previous day to the next day3. Fix non-1D low resolution US stock charts4. Verify the correctness (including volume & date labels), or if this approach is working at all5. Make the date labels use this new approach for non-1D stocks as well6. Crypto7. DST
8. Gaps
9. Fix volume alignment
10. DEFAULT_TIMESTAMPS
I'm unsure if this is what you envisioned, but it seems to be working all right (excluding US stocks for whatever reason).