Open swharden opened 1 week ago
vlad has two accounts and the one he uses for his personal project is
VladislavPustovarov
so you can change the at to match that
@quantfreedom and @VladislavPustovarov - got it, thanks!
I added cursor tracking with highlighted labels and candle snapping in the horizontal axis
I'll keep working in #4484
holy jesus ... this thing is looking so damn sexy ... this is beyond nuts that all of this is even happening ... insane
@VladislavPustovarov I have an important message about performance.
Performance is indeed very bad when displaying 50,000 candles. However, I think this should never be done. Showing so many distinct candles on a 800px wide chart means each candle is less than 0.02 pixels wide.
I highly recommend detecting when you are trying to display an extremely large number of candles and re-binning the data so that candles are at least 1 pixel wide or wider. I don't think a user will ever want to see second-width candles on a years-wide plot.
For example, TradingView limits how far you can zoom in or out based on the width of candles. This prevents more than a few thousand candles from ever being seen at one time. Users who want to see more time can increase the candle width.
If you implement this strategy in your application, it will be extremely performant. Also, no modification to ScottPlot is required to achieve this high performance.
Let me know if you have any questions about this topic! I am updating the demo app in #4484 to show render time and frame rate at the top in the title area. It's interesting to see how poor performance gets when candles are significantly smaller than 1 pixel wide.
I'm writing this down to put words to the behavior that needs to change.
Presently, resizing the window "squeezes" the plot so there is no change in axis limits. For financial charting, this is not the desired behavior.
The chart should respond to resize events by "sliding" data off the screen to the left to achieve a fixed "distance per pixel" ratio through resize events
I figured out a way to implement this behavior using a custom axis rule
This completes my list of tasks so I'm going to merge #4484 which will close this issue, but we can still use this issue for conversation and taking notes even after it's closed.
Let's can pick up our discussion again after you make progress on improving the data tick logic
Feel free to reach out in the meantime if you have any questions 👍
having some issues with the candle width remaining stable as you zoom in and out
as you stay in one place and zoom out and zoom in each time the candle width gets smaller and smaller even though we are just zooming back and forth.
This causes a problem with being able to properly set the display on the x axis based on candle width
Also when you zoom in and out ... lets say you zoom out and the x axis changes ... it seems like you have to zoom in 3 times for it to change to the next level then you have to zoom out 3 more times for it to change but i am guessing it should always just be one zoom to change from one level to the next
@VladislavPustovarov can you comment on this so that you can get updates
also the candle width seems to be getting smaller and smaller as you zoom in and out in one place
public virtual void Render(RenderPack rp)
{
if (DateTimes.Length == 0)
return;
// allow drawing outside the data area
rp.CanvasState.DisableClipping();
// get the best tick generator given the field of view
int minIndexInView = (int)(Math.Max(0, Axes.XAxis.Range.Min));
int maxIndexInView = (int)(Math.Min(DateTimes.Length - 1, Axes.XAxis.Range.Max));
if (maxIndexInView <= minIndexInView) return;
TimeSpan timeSpanInView = DateTimes[maxIndexInView] - DateTimes[minIndexInView];
IFinancialTickGenerator tickGenerator = GetBestTickGenerator(timeSpanInView, rp.DataRect.Width);
List<(int, string)> ticks = tickGenerator.GetTicks(DateTimes, minIndexInView, maxIndexInView);
widthOfCandleInPixels = rp.DataRect.Width / Axes.XAxis.Range.Span;
// render each tick label
using SKPaint paint = new();
foreach ((int x, string label) in ticks)
{
Pixel px = new(Axes.XAxis.GetPixel(x, rp.DataRect), rp.DataRect.Bottom);
LabelStyle.Render(rp.Canvas, px, paint, label);
}
}
private IFinancialTickGenerator GetBestTickGenerator(TimeSpan timeSpan, float widthInPixels)
{
// adjust the scale so small plots show fewer ticks
double scaledViewDays = timeSpan.TotalDays * 600 / widthInPixels;
var maxWidth = LabelStyle.Measure(labelFormat).Size.Width;
Trace.WriteLine(widthOfCandleInPixels);
Trace.WriteLine(maxWidth);
Trace.WriteLine(maxWidth / widthOfCandleInPixels);
Trace.WriteLine("");
var numCandles = maxWidth / widthOfCandleInPixels;
if (widthOfCandleInPixels > 85)
{
return new EachCandleValue();
}
else if (widthOfCandleInPixels > 40)
{
return new EveryOtherCandle();
}
else if (widthOfCandleInPixels > 20)
{
return new EveryFourthCandle();
}
else if (scaledViewDays < 180)
{
return new MonthsAndMondays();
}
else if (scaledViewDays < 360 * 2)
{
return new Months();
}
else
{
return new Years();
}
}
also there is a thing that the zoom doesn't update the x axis unless you click on the chart or interact with it in some way
@swharden
Thank you for providing such high-quality charting solutions for the C# community.
As a financial hobbyist, I often need to plot candlestick charts with volume and add indicators like EMA, RSI, and others. Let me outline the common requirements for financial charting:
Hi @tiger2014, thank you for your feedback! I can see we have a growing collection of developers who are interested in seeing ScottPlot improve support for financial charts, and I'm excited to keep working to make it better!
Part of my effort is directed at adding these new features, and part of my effort is also supporting others as they contribute new features, and also to provide some direction about which features to work on in which order. Right now we are focused on adding better support for dates and times (the content of the discussion above), and I probably will wait until that contribution is submitted before putting more of my direct effort into improving financial charting, but it is a goal of mine for sure.
Based on your feedback, in my next iteration of the financial demo I'll add volume bars and also separate plots like you show to show SMA, RSI, and other similar indicators. Thanks for this suggestion!
Based on your feedback, in my next iteration of the financial demo I'll add volume bars and also separate plots like you show to show SMA, RSI, and other similar indicators. Thanks for this suggestion!
I modified the "to-do" list at the top of this issue to add my work after Vlad's. I'll re-open this issue and use it to track the progress Vlad is making toward improved support for date axis labels.
as you stay in one place and zoom out and zoom in each time the candle width gets smaller and smaller even though we are just zooming back and forth.
When you say the candles "get smaller", you mean "each candle occupies fewer pixels horizontally on the screen as you zoom out", right? Assuming this is the case, I think this is the intended behavior. It's what TradingView does when you zoom in and out.
This causes a problem with being able to properly set the display on the x axis based on candle width
There are few different ways "choosing the best horizontal tick labels" could be accomplished, but my recommendation is to not have them at all related to candle width. I would assume that a high quality chart (with nice date ticks) should be able to be made even if no candles are displayed, or if a scatter plot is displayed. Decoupling these two concepts may make the problem simpler?
"Choosing the best horizontal ticks" is probably only dependent on (1) how wide the chart is (in pixels) and (2) how much time the visible area of the chart spans.
If this task becomes too difficult to implement, let me know and I'll try to put some time into doing the "task 2" list above. If I hit a wall too maybe we can come up with a different solution.
also the candle width seems to be getting smaller and smaller as you zoom in and out in one place
Let's set this issue aside for now because a future refinement will be to make zooming automatically "snap" axis limits to edges that are between candles so zooming will not result in situations where candles run off the screen appearing cut in half
also there is a thing that the zoom doesn't update the x axis unless you click on the chart or interact with it in some way
After changing axis limits, call formsPlot1.Refresh()
to force a redraw
Summarizing what comes next, focus hard on implementing those different tick views outlined above in task 2, and if you get stuck or think the design is not sufficient then let me know and I can start working on that myself 👍
also the candle width seems to be getting smaller and smaller as you zoom in and out in one place
Fixed in #4516 / #4520
This issue tracks short term goals to improve financial charting resulting from a discussion today with @quantfreedom and @VladislavPustovarov
Progress will be evaluated using the Sandbox.WinFormsFinance project
This work extends #4385
Task 1: Scott
Use strategy pattern to allow multiple scaling strategies including custom ones injected by the user.It is already a function that can be created by the user and assigned to theContinuousAutoscaleAction
action so creating additional classes is not required.Task 2: Vlad
Task 3: Scott
This work will be performed after Vlad finishes the date work above