tickrs
tickrs copied to clipboard
Stock prices beyond two decimal places
Great tool, I instantly loved it.
I have OTC penny stocks, which often are represented to 4 decimal places.
tickrs
rounds all the prices to two places, (it seems) so the data and charts a little less-than-compelling.

Would it be possible to support more decimal places, perhaps as a config options (even per symbol would be awesome!)
Great suggestion! I never even realized this. I could always just hard code it... so anything under ~$2 goes to the 4th decimal place?
Do you have any suggestions on what a good cutoff would be before stock prices start moving in 0.01+ increments?
How about we vary it based on the abs max-min delta within the active timeframe? In order to chart out reasonable fluctuations. So it doesn't require hardcoding, works for wholes and decimals alike, and can better spread out charts like the one above.
I like the idea of using the delta. I'm not sure what the threshold is for when the decimals get truncated more.
Yeah I think that's the way to go. I'm out of town for a few days, but I'll toy with this when I get back.
It should be super easy to implement, so if anyone wants to help contribute, that'd be great as well!
Ok, I've implemented this in #125. Here is an example:
I take the difference between the min and max price within the timeframe, and if it's <= 1.0, then I show 4 decimal places. Seems to work well!
@miraclx @jasongaare Can you both test for me for a few days and give me your thoughts on if things should be refined? I think I went too aggressive with the $1.0 delta cutoff, as that'd trigger on a $100 stock with < 1% movement from high to low.
I should have waited to release, but oh well :P
Maybe an alternative implementation would look at the period over period price change for the entire time frame, and take the median price change from that. If median is less than $0.01, it's a good candidate for 4 decimals?
I should have waited to release, but oh well :P
😅, I was literally in the process of reviewing and eventually testing the PR when it got merged, I thought, "oh, you're in a hurry".
So I tried the method of calculating period over period price movements, then taking the median, and seeing if it was <= $0.005 (half a cent) and this seems to work really well. However, it massively increases CPU usage due to the calculation...
Any other thoughts?
Hmm. Could you open a draft PR for this? Lemme inspect that for a sec.
Yeah, check out #126. My other concern is that any calc on "price movement" will more likely have false positives when there is not a lot of data (early in the trading period), as there are less data points.
I'm thinking the easiest way is to just hard code 4 decimals on stocks with a High price of ~<$2.
And to clarify, this now JUST impacts the "formatting" of decimal places.
I've fixed the issue where it doesn't graph from top to bottom, which was a separate issue. (I was adding 0.05 padding to high and low price for y-axis bounds, which caused stocks with low prices to be affected), which I removed.
Thought about this for a sec...I still think I approve of the already merged PR. A stock with < 1% movement in any timeframe should be in four decimal places irrespective of whether or not it's a penny stock or WDYT? This makes sense to me, to graph out reasonable fluctuations like you set out to do in the first place.
Maybe I'm ignorant, but I'm not sure the method of taking median is much of a solution. The gained cost from the required heap allocation, eventual sorting, only to end up, like you said, producing false positives (which I believe would happen more often than not), I don't really think is helpful.
I'll look at it again in the morning, perhaps I'm missing something.
Also, on heap allocation, StockState::high_low
could be rewritten without the Vec
diff --git a/src/widget/stock.rs b/src/widget/stock.rs
index 60be048..433d384 100644
--- a/src/widget/stock.rs
+++ b/src/widget/stock.rs
@@ -413,29 +413,27 @@ impl StockState {
(min, max)
}
- pub fn high_low(&self, data: &[Price]) -> (f64, f64) {
- let mut data = data.to_vec();
- data.push(Price {
- close: self.current_price(),
- open: self.current_price(),
- high: self.current_price(),
- low: self.current_price(),
- ..Default::default()
- });
- data.retain(|p| p.close.gt(&0.0));
-
- let high = data
+ pub fn high_low(&self, prices: &[Price]) -> (f64, f64) {
+ let data = prices
.iter()
- .max_by(|a, b| a.high.partial_cmp(&b.high).unwrap())
- .map(|p| p.high)
- .unwrap_or(1.0);
- let low = data
- .iter()
- .min_by(|a, b| a.low.partial_cmp(&b.low).unwrap())
- .map(|p| p.low)
- .unwrap_or(0.0);
+ .cloned()
+ .chain(std::iter::once(Price {
+ close: self.current_price(),
+ open: self.current_price(),
+ high: self.current_price(),
+ low: self.current_price(),
+ ..Default::default()
+ }))
+ .filter(|p| p.close.gt(&0.0));
+
+ let (high, low) = data.fold((None::<f64>, None::<f64>), |(pre_h, pre_l), price| {
+ (
+ Some(pre_h.map_or(price.high, |pre_h| pre_h.max(price.high))),
+ Some(pre_l.map_or(price.low, |pre_l| pre_l.min(price.low))),
+ )
+ });
- (high, low)
+ (high.unwrap_or(1.0), low.unwrap_or(0.0))
}
pub fn x_bounds(&self, start: i64, end: i64, data: &[Price]) -> [f64; 2] {
Not sure the status on this, I still have version 0.14.5... here's a screenshot:

if you went with the previous solution, is it simply possible to round numbers? Here you can see HYSR and KODK both are getting data with four decimal points, but PBR is always showing x.xx00. Would it be simple to just round of trailing zeros in this case? (not beyond two decimals, obviously)
Unfortunately >2 decimal precision prices aren't just something that happens on low prices stocks. SPY, for example, is trading around ~400 and it goes out to like 8 decimal places.
@miraclx I really don't think it's worth showing more than 2 decimal precision on anything above a certain price, even if its movement is small for the day. At $5, a $0.01 change is only 0.2%. I think I will go with the original implementation, but add a second check that ONLY shows 4 decimal places if the High price is also lower than $5.
High precision is desirable for crypto pairs since BTC price tends to dwarf anything else. Check tickrs -s ETH-BTC
to reproduce.
@tidux I've implemented a better way to dynamically add precision based on the asset price. See #134.
Let me know if you think this works.
That looks good.