| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
+1, I need to show only business hours in some graph (removing week-ends and night hours).
Anything new here? I’ve got this code for displaying currency pair EUR/USD one hour (H1) chart:
DateTimeAxis timeSpanAxis1 = new DateTimeAxis()
{
Position = AxisPosition.Bottom,
IntervalType= DateTimeIntervalType.Auto
};
document.ChartPlotModel.Axes.Add(timeSpanAxis1);
LinearAxis linearAxis1 = new LinearAxis() { Position = AxisPosition.Left };
document.ChartPlotModel.Axes.Add(linearAxis1);
CandleStickSeries series = new CandleStickSeries()
{
Color = OxyColors.Black,
IncreasingColor = OxyColors.DarkGreen,
DecreasingColor = OxyColors.Red,
DataFieldX = "Time",
DataFieldHigh = "H",
DataFieldLow = "L",
DataFieldOpen = "O",
DataFieldClose = "C",
TrackerFormatString = "Date: {2}\nOpen: {5:0.00000}\nHigh: {3:0.00000}\nLow: {4:0.00000}\nClose: {6:0.00000}"
};
ReadData(series);
int itemsCount = series.Items.Count;
timeSpanAxis1.Minimum = series.Items[itemsCount - 46].X;
timeSpanAxis1.Maximum = series.Items[itemsCount - 1].X;
double yMin = series.Items.Skip(itemsCount - 46).Take(45).Select(x => x.Low).Min();
double yMax = series.Items.Skip(itemsCount - 46).Take(45).Select(x => x.High).Max();
double extent = yMax - yMin;
double margin = extent * .05;
linearAxis1.Minimum = yMin - margin;
linearAxis1.Maximum = yMax + margin;
document.ChartPlotModel.Series.Add(series);
timeSpanAxis1.AxisChanged += (sender, e) => AdjustYExtent(series, timeSpanAxis1, linearAxis1);
There is for example gap between Friday 2015.02.13 23:00 and Monday 2015.02.16 00:00. My solution with OxyPlot gives me that gap on the chart:
But, I’d like to have a chart without that gap. For example this is a MT4 chart with this situation:
A lot of financial series are with gaps. I think to solve this problem would by a great improvement.
Any help will be welcome.
P.S.: OxyPlot is a good job. Thanks a lot.
Hello.
One way to deal with this problem is to use a category axis. Unfortunately it means some adjustments which are not very convenient:
1/ category axis is using the index of the label collection items as coordinates. If you have 5 categories in the Labels collection, the categories will be placed at coordinates 0 to 4
2/ CandleStickAndVolumeSeries is using a datetime converted as double (to convert, use DateTimeAxis.ToDouble(YourDateTimeValue))
So to have it working I currently use a variable storing my list of datetimes (to later pass them to the category axes), and I replace them in the CandleStickAndVolumeSeries by the index. It allows to correctly plot the data on a category axis and remove the gaps. Unfortunately it has a few downsides:
1/ the auto update of the interval doesn't exist with CategoryAxes (and it looks awful)
2/ it can delete gaps that are not real gaps. Exemple: let's imagine a H1 (1 hour interval) chart on the Forex without any quotation received on Tuesday from 3pm until 6pm, those 3 hours will not appear on your x axis, if you don't pass a "fake" candle (open = high = low = close = pastclose).
So can it be possible to have a DateTimeCategoryAxis that would plot using the label index, but will automatically update the label format (changing from hh:mm to dd/MM/yyyy regarding the zoom, like a DateTimeAxis) and its interval?
At best, the CandleStickAndVolumeSeries should have a Xprime value representing the index, with an option to choose to plot using X (the double representing the datetime, for graphs using a proper DateTimeAxis) or Xprime (the index, for graph using the new DateTimeCategoryAxis).
+1, this is super important for financial charts.
This works pretty easily though:
CandleStickSeries candleStickSeries = new CandleStickSeries();
var n = 0;
foreach (var bar in bars)
candleStickSeries.Items.Add(new HighLowItem(n++, (double)bar.High, (double)bar.Low, (double)bar.Open, (double)bar.Close));
model.Series.Add(candleStickSeries);
model.Axes.Add(new LinearAxis()
{
Position = AxisPosition.Bottom,
LabelFormatter = (value) =>
{
return bars[(int)value].Date.ToString("MM/dd");
}
});
@BrianARice should your code remove the gaps?
Hi,
i took the approach of BrianARice and modified it for my needs. I ve added a new class Financial Axis that uses indexes instead of DateTimes. With that i was able to fix eaven the tooltip dates which were otherwise broken here is my code:
public class FinancialChartAxis : LinearAxis
{
public FinancialChartAxis(List<DateTime> dateTimes, string axisDateFormatString)
: base()
{
DateTimes = dateTimes;
LabelFormatter = (value) =>
{
return value >= 0 && value < dateTimes.Count ? dateTimes[(int)value].ToString(axisDateFormatString) : string.Empty;
};
}
private List<DateTime> DateTimes { get; set; }
public override object GetValue(double x)
{
int indexValue = (int)x;
if (indexValue >= 0 && indexValue < DateTimes.Count)
{
return DateTimes[indexValue];
}
return base.GetValue(x);
}
}
private PlotModel GeneratePricePlotModel(IPriceStreamReader priceStreamReader, PriceInfo priceInfo)
{
var plotModel = new PlotModel { Title = priceInfo.Name + " " + priceInfo.PriceStreamId.Interval };
var priceAxis = new LinearAxis { Position = AxisPosition.Left };
plotModel.Axes.Add(priceAxis);
List<Price> prices = priceStreamReader.ToList();
List<HighLowItem> ohlvItems = prices.Select((p, i) => new HighLowItem(i, p.High, p.Low, p.Open, p.Close)).ToList();
var candleStickSeries = new CandleStickSeries()
{
Color = OxyColors.Black,
StrokeThickness = 1,
IncreasingColor = OxyColors.LightSlateGray,
DecreasingColor = OxyColors.DarkRed,
DataFieldX = "Time",
DataFieldHigh = "H",
DataFieldLow = "L",
DataFieldOpen = "O",
DataFieldClose = "C",
ItemsSource = ohlvItems,
TrackerFormatString = "Date: {2}\nHigh: {3:0.00}\nLow: {4:0.00}\nOpen: {5:0.00}\nClose: {6:0.00}"
};
string dateFormat = priceStreamReader.PriceInfo.PriceStreamId.Interval < Interval.Day ? "dd.MM.yy\nHH:mm" : "dd.MM.yy";
var timeAxis = new FinancialChartAxis(prices.Select(p => p.TimeStamp).ToList(), dateFormat)
{
Position = AxisPosition.Bottom,
MaximumRange = 750
};
plotModel.Axes.Add(timeAxis);
int itemCount = ohlvItems.Count;
int itemWindowSize = 100;
timeAxis.Minimum = ohlvItems[itemCount - itemWindowSize].X;
timeAxis.Maximum = ohlvItems[itemCount - 1].X;
priceAxis.Minimum = ohlvItems.Skip(itemCount - itemWindowSize).Take(itemWindowSize).Select(x => x.Low).Min();
priceAxis.Maximum = ohlvItems.Skip(itemCount - itemWindowSize).Take(itemWindowSize).Select(x => x.High).Max();
plotModel.Series.Add(candleStickSeries);
timeAxis.AxisChanged += (sender, e) => AdjustYExtent(candleStickSeries, timeAxis, priceAxis);
return plotModel;
}
using the code of the example:
private static void AdjustYExtent(CandleStickSeries series, Axis xaxis, Axis yaxis)
{
var xmin = xaxis.ActualMinimum;
var xmax = xaxis.ActualMaximum;
var istart = series.FindByX(xmin);
var iend = series.FindByX(xmax, istart);
var ymin = double.MaxValue;
var ymax = double.MinValue;
for (int i = istart; i <= iend; i++)
{
var bar = series.Items[i];
ymin = Math.Min(ymin, bar.Low);
ymax = Math.Max(ymax, bar.High);
}
var extent = ymax - ymin;
var margin = extent * 0.10;
yaxis.Zoom(ymin - margin, ymax + margin);
}
This is a fascinating thread and a great project. I deal with similar time series data and learnt a good deal to get started.
| Back | FazBrowse Home | New Git URL |
Imported from http://oxyplot.codeplex.com/workitem/10089
cwevers 2013-10-18 15:44
I'm currently building a candlestick graph for stock quotes. I only have data (OHLC) for the trading days so this leaves gaps for weekend days. Of course I can work with a category axis but this throws out all the neat DateTimeAxis features. Is it possible
to remove these gaps (see attached example)? I've looked into IntervalType = DateTimeIntervalType.Manual but that seems to do nothing.