@@ -0,0 +1,235 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CandleStickAndVolumeSeriesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("CandleStickAndVolumeSeries")]
|
||||
[Tags("Series")]
|
||||
public static class CandleStickAndVolumeSeriesExamples
|
||||
{
|
||||
[Example("Candles + Volume (combined volume), adjusting Y-axis")]
|
||||
public static Example CombinedVolume_Adjusting()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (combined volume)",
|
||||
VolumeStyle.Combined,
|
||||
naturalY: false,
|
||||
naturalV: false);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (combined volume), natural Y-axis")]
|
||||
public static Example CombinedVolume_Natural()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (combined volume)",
|
||||
VolumeStyle.Combined,
|
||||
naturalY: true,
|
||||
naturalV: true);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (stacked volume), adjusting Y-axis")]
|
||||
public static Example StackedVolume_Adjusting()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (stacked volume)",
|
||||
VolumeStyle.Stacked,
|
||||
naturalY: false,
|
||||
naturalV: false);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (stacked volume), natural Y-axis")]
|
||||
public static Example StackedVolume_Natural()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (stacked volume)",
|
||||
VolumeStyle.Stacked,
|
||||
naturalY: true,
|
||||
naturalV: true);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (+/- volume), adjusting Y-axis")]
|
||||
public static Example PosNegVolume_Adjusting()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (+/- volume)",
|
||||
VolumeStyle.PositiveNegative,
|
||||
naturalY: false,
|
||||
naturalV: false);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (+/- volume), natural Y-axis")]
|
||||
public static Example PosNegVolume_Natural()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (+/- volume)",
|
||||
VolumeStyle.PositiveNegative,
|
||||
naturalY: true,
|
||||
naturalV: true);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (volume not shown), adjusting Y-axis")]
|
||||
public static Example NoVolume_Adjusting()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (volume not shown)",
|
||||
VolumeStyle.None,
|
||||
naturalY: false,
|
||||
naturalV: false);
|
||||
}
|
||||
|
||||
[Example("Candles + Volume (volume not shown), natural Y-axis")]
|
||||
public static Example NoVolume_Natural()
|
||||
{
|
||||
return CreateCandleStickAndVolumeSeriesExample(
|
||||
"Candles + Volume (volume not shown)",
|
||||
VolumeStyle.None,
|
||||
naturalY: true,
|
||||
naturalV: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the candle stick and volume series example.
|
||||
/// </summary>
|
||||
/// <returns>The candle stick and volume series example.</returns>
|
||||
/// <param name="title">Title.</param>
|
||||
/// <param name="style">Style.</param>
|
||||
/// <param name="n">N.</param>
|
||||
/// <param name="naturalY">If set to <c>true</c> natural y.</param>
|
||||
/// <param name="naturalV">If set to <c>true</c> natural v.</param>
|
||||
private static Example CreateCandleStickAndVolumeSeriesExample(
|
||||
string title,
|
||||
VolumeStyle style,
|
||||
int n = 10000,
|
||||
bool naturalY = false,
|
||||
bool naturalV = false)
|
||||
{
|
||||
var pm = new PlotModel { Title = title };
|
||||
|
||||
var series = new CandleStickAndVolumeSeries
|
||||
{
|
||||
PositiveColor = OxyColors.DarkGreen,
|
||||
NegativeColor = OxyColors.Red,
|
||||
PositiveHollow = false,
|
||||
NegativeHollow = false,
|
||||
SeparatorColor = OxyColors.Gray,
|
||||
SeparatorLineStyle = LineStyle.Dash,
|
||||
VolumeStyle = style
|
||||
};
|
||||
|
||||
// create bars
|
||||
foreach (var bar in OhlcvItemGenerator.MRProcess(n))
|
||||
{
|
||||
series.Append(bar);
|
||||
}
|
||||
|
||||
// create visible window
|
||||
var Istart = n - 200;
|
||||
var Iend = n - 120;
|
||||
var Ymin = series.Items.Skip(Istart).Take(Iend - Istart + 1).Select(x => x.Low).Min();
|
||||
var Ymax = series.Items.Skip(Istart).Take(Iend - Istart + 1).Select(x => x.High).Max();
|
||||
var Xmin = series.Items[Istart].X;
|
||||
var Xmax = series.Items[Iend].X;
|
||||
|
||||
// setup axes
|
||||
var timeAxis = new DateTimeAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
Minimum = Xmin,
|
||||
Maximum = Xmax
|
||||
};
|
||||
var barAxis = new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
Key = series.BarAxisKey,
|
||||
StartPosition = 0.25,
|
||||
EndPosition = 1.0,
|
||||
Minimum = naturalY ? double.NaN : Ymin,
|
||||
Maximum = naturalY ? double.NaN : Ymax
|
||||
};
|
||||
var volAxis = new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
Key = series.VolumeAxisKey,
|
||||
StartPosition = 0.0,
|
||||
EndPosition = 0.22,
|
||||
Minimum = naturalV ? double.NaN : 0,
|
||||
Maximum = naturalV ? double.NaN : 5000
|
||||
};
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case VolumeStyle.None:
|
||||
barAxis.Key = null;
|
||||
barAxis.StartPosition = 0.0;
|
||||
pm.Axes.Add(timeAxis);
|
||||
pm.Axes.Add(barAxis);
|
||||
break;
|
||||
|
||||
case VolumeStyle.Combined:
|
||||
case VolumeStyle.Stacked:
|
||||
pm.Axes.Add(timeAxis);
|
||||
pm.Axes.Add(barAxis);
|
||||
pm.Axes.Add(volAxis);
|
||||
break;
|
||||
|
||||
case VolumeStyle.PositiveNegative:
|
||||
volAxis.Minimum = naturalV ? double.NaN : -5000;
|
||||
pm.Axes.Add(timeAxis);
|
||||
pm.Axes.Add(barAxis);
|
||||
pm.Axes.Add(volAxis);
|
||||
break;
|
||||
}
|
||||
|
||||
pm.Series.Add(series);
|
||||
|
||||
if (naturalY == false)
|
||||
{
|
||||
timeAxis.AxisChanged += (sender, e) => AdjustYExtent(series, timeAxis, barAxis);
|
||||
}
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
|
||||
return new Example(pm, controller);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the Y extent.
|
||||
/// </summary>
|
||||
/// <param name="series">Series.</param>
|
||||
/// <param name="xaxis">Xaxis.</param>
|
||||
/// <param name="yaxis">Yaxis.</param>
|
||||
private static void AdjustYExtent(CandleStickAndVolumeSeries series, DateTimeAxis xaxis, LinearAxis 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CandleStickSeriesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("CandleStickSeries"), Tags("Series")]
|
||||
public static class CandleStickSeriesExamples
|
||||
{
|
||||
[Example("Large Data Set (wide window)")]
|
||||
public static Example LargeDataSetWide()
|
||||
{
|
||||
var pm = new PlotModel { Title = "Large Data Set (wide window)" };
|
||||
|
||||
var timeSpanAxis1 = new DateTimeAxis { Position = AxisPosition.Bottom };
|
||||
pm.Axes.Add(timeSpanAxis1);
|
||||
var linearAxis1 = new LinearAxis { Position = AxisPosition.Left };
|
||||
pm.Axes.Add(linearAxis1);
|
||||
var n = 1000000;
|
||||
var items = HighLowItemGenerator.MRProcess(n).ToArray();
|
||||
var series = new CandleStickSeries
|
||||
{
|
||||
Color = OxyColors.Black,
|
||||
IncreasingColor = OxyColors.DarkGreen,
|
||||
DecreasingColor = OxyColors.Red,
|
||||
DataFieldX = "Time",
|
||||
DataFieldHigh = "H",
|
||||
DataFieldLow = "L",
|
||||
DataFieldOpen = "O",
|
||||
DataFieldClose = "C",
|
||||
TrackerFormatString =
|
||||
"High: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}",
|
||||
ItemsSource = items
|
||||
};
|
||||
|
||||
timeSpanAxis1.Minimum = items[n - 200].X;
|
||||
timeSpanAxis1.Maximum = items[n - 130].X;
|
||||
|
||||
linearAxis1.Minimum = items.Skip(n - 200).Take(70).Select(x => x.Low).Min();
|
||||
linearAxis1.Maximum = items.Skip(n - 200).Take(70).Select(x => x.High).Max();
|
||||
|
||||
pm.Series.Add(series);
|
||||
|
||||
timeSpanAxis1.AxisChanged += (sender, e) => AdjustYExtent(series, timeSpanAxis1, linearAxis1);
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
|
||||
return new Example(pm, controller);
|
||||
}
|
||||
|
||||
[Example("Large Data Set (narrow window)")]
|
||||
public static Example LargeDataSetNarrow()
|
||||
{
|
||||
var pm = new PlotModel { Title = "Large Data Set (narrow window)" };
|
||||
|
||||
var timeSpanAxis1 = new DateTimeAxis { Position = AxisPosition.Bottom };
|
||||
pm.Axes.Add(timeSpanAxis1);
|
||||
var linearAxis1 = new LinearAxis { Position = AxisPosition.Left };
|
||||
pm.Axes.Add(linearAxis1);
|
||||
var n = 1000000;
|
||||
var items = HighLowItemGenerator.MRProcess(n).ToArray();
|
||||
var series = new CandleStickSeries
|
||||
{
|
||||
Color = OxyColors.Black,
|
||||
IncreasingColor = OxyColors.DarkGreen,
|
||||
DecreasingColor = OxyColors.Red,
|
||||
TrackerFormatString =
|
||||
"High: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}",
|
||||
ItemsSource = items
|
||||
};
|
||||
|
||||
|
||||
timeSpanAxis1.Minimum = items[0].X;
|
||||
timeSpanAxis1.Maximum = items[29].X;
|
||||
|
||||
linearAxis1.Minimum = items.Take(30).Select(x => x.Low).Min();
|
||||
linearAxis1.Maximum = items.Take(30).Select(x => x.High).Max();
|
||||
|
||||
pm.Series.Add(series);
|
||||
|
||||
timeSpanAxis1.AxisChanged += (sender, e) => AdjustYExtent(series, timeSpanAxis1, linearAxis1);
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
|
||||
return new Example(pm, controller);
|
||||
}
|
||||
|
||||
[Example("Small Set")]
|
||||
public static Example SmallDataSet()
|
||||
{
|
||||
var pm = new PlotModel { Title = "Small Data Set" };
|
||||
|
||||
var timeSpanAxis1 = new DateTimeAxis { Position = AxisPosition.Bottom };
|
||||
pm.Axes.Add(timeSpanAxis1);
|
||||
var linearAxis1 = new LinearAxis { Position = AxisPosition.Left };
|
||||
pm.Axes.Add(linearAxis1);
|
||||
var n = 100;
|
||||
var items = HighLowItemGenerator.MRProcess(n).ToArray();
|
||||
var series = new CandleStickSeries
|
||||
{
|
||||
Color = OxyColors.Black,
|
||||
IncreasingColor = OxyColors.DarkGreen,
|
||||
DecreasingColor = OxyColors.Red,
|
||||
DataFieldX = "X",
|
||||
DataFieldHigh = "High",
|
||||
DataFieldLow = "Low",
|
||||
DataFieldOpen = "Open",
|
||||
DataFieldClose = "Close",
|
||||
TrackerFormatString =
|
||||
"High: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}",
|
||||
ItemsSource = items
|
||||
};
|
||||
|
||||
pm.Series.Add(series);
|
||||
|
||||
timeSpanAxis1.AxisChanged += (sender, e) => AdjustYExtent(series, timeSpanAxis1, linearAxis1);
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
|
||||
return new Example(pm, controller);
|
||||
}
|
||||
|
||||
[Example("Simple CandleStickSeries example")]
|
||||
public static PlotModel SimpleExample()
|
||||
{
|
||||
var startTimeValue = DateTimeAxis.ToDouble(new DateTime(2016, 1, 1));
|
||||
var pm = new PlotModel { Title = "Simple CandleStickSeries example" };
|
||||
pm.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom, Minimum = startTimeValue - 7, Maximum = startTimeValue + 7 });
|
||||
pm.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
var series = new CandleStickSeries();
|
||||
series.Items.Add(new HighLowItem(startTimeValue, 100, 80, 92, 94));
|
||||
series.Items.Add(new HighLowItem(startTimeValue + 1, 102, 77, 94, 93));
|
||||
series.Items.Add(new HighLowItem(startTimeValue + 2, 99, 85, 93, 93));
|
||||
pm.Series.Add(series);
|
||||
return pm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the Y extent.
|
||||
/// </summary>
|
||||
/// <param name="series">Series.</param>
|
||||
/// <param name="xaxis">Xaxis.</param>
|
||||
/// <param name="yaxis">Yaxis.</param>
|
||||
private static void AdjustYExtent(CandleStickSeries series, DateTimeAxis xaxis, LinearAxis 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="HighLowItemGenerator.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Creates realistic high/low items.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
/// <summary>
|
||||
/// Creates realistic high/low items.
|
||||
/// </summary>
|
||||
public static class HighLowItemGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The random number generator.
|
||||
/// </summary>
|
||||
private static readonly Random Rand = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// Creates bars governed by a MR process
|
||||
/// </summary>
|
||||
/// <returns>The process.</returns>
|
||||
/// <param name="n">N.</param>
|
||||
/// <param name="x0">X0.</param>
|
||||
/// <param name="csigma">Csigma.</param>
|
||||
/// <param name="esigma">Esigma.</param>
|
||||
/// <param name="kappa">Kappa.</param>
|
||||
public static IEnumerable<HighLowItem> MRProcess(
|
||||
int n,
|
||||
double x0 = 100.0,
|
||||
double csigma = 0.50,
|
||||
double esigma = 0.70,
|
||||
double kappa = 0.01)
|
||||
{
|
||||
double x = x0;
|
||||
|
||||
var baseT = DateTime.UtcNow;
|
||||
for (int ti = 0; ti < n; ti++)
|
||||
{
|
||||
var dx_c = -kappa * (x - x0) + RandomNormal(0, csigma);
|
||||
var dx_1 = -kappa * (x - x0) + RandomNormal(0, esigma);
|
||||
var dx_2 = -kappa * (x - x0) + RandomNormal(0, esigma);
|
||||
|
||||
var open = x;
|
||||
var close = x = x + dx_c;
|
||||
var low = Min(open, close, open + dx_1, open + dx_2);
|
||||
var high = Max(open, close, open + dx_1, open + dx_2);
|
||||
|
||||
var nowT = baseT.AddSeconds(ti);
|
||||
var t = DateTimeAxis.ToDouble(nowT);
|
||||
yield return new HighLowItem(t, high, low, open, close);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the minimum of the specified a, b, c and d.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">B.</param>
|
||||
/// <param name="c">C.</param>
|
||||
/// <param name="d">D.</param>
|
||||
/// <returns>The minimum.</returns>
|
||||
private static double Min(double a, double b, double c, double d)
|
||||
{
|
||||
return Math.Min(a, Math.Min(b, Math.Min(c, d)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the maximum of the specified a, b, c and d.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">B.</param>
|
||||
/// <param name="c">C.</param>
|
||||
/// <param name="d">D.</param>
|
||||
/// <returns>The maximum.</returns>
|
||||
private static double Max(double a, double b, double c, double d)
|
||||
{
|
||||
return Math.Max(a, Math.Max(b, Math.Max(c, d)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get random normal
|
||||
/// </summary>
|
||||
/// <param name="mu">Mu.</param>
|
||||
/// <param name="sigma">Sigma.</param>
|
||||
private static double RandomNormal(double mu, double sigma)
|
||||
{
|
||||
return InverseCumNormal(Rand.NextDouble(), mu, sigma);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fast approximation for inverse cum normal
|
||||
/// </summary>
|
||||
/// <param name="p">probability</param>
|
||||
/// <param name="mu">Mean</param>
|
||||
/// <param name="sigma">std dev</param>
|
||||
private static double InverseCumNormal(double p, double mu, double sigma)
|
||||
{
|
||||
const double A1 = -3.969683028665376e+01;
|
||||
const double A2 = 2.209460984245205e+02;
|
||||
const double A3 = -2.759285104469687e+02;
|
||||
const double A4 = 1.383577518672690e+02;
|
||||
const double A5 = -3.066479806614716e+01;
|
||||
const double A6 = 2.506628277459239e+00;
|
||||
|
||||
const double B1 = -5.447609879822406e+01;
|
||||
const double B2 = 1.615858368580409e+02;
|
||||
const double B3 = -1.556989798598866e+02;
|
||||
const double B4 = 6.680131188771972e+01;
|
||||
const double B5 = -1.328068155288572e+01;
|
||||
|
||||
const double C1 = -7.784894002430293e-03;
|
||||
const double C2 = -3.223964580411365e-01;
|
||||
const double C3 = -2.400758277161838e+00;
|
||||
const double C4 = -2.549732539343734e+00;
|
||||
const double C5 = 4.374664141464968e+00;
|
||||
const double C6 = 2.938163982698783e+00;
|
||||
|
||||
const double D1 = 7.784695709041462e-03;
|
||||
const double D2 = 3.224671290700398e-01;
|
||||
const double D3 = 2.445134137142996e+00;
|
||||
const double D4 = 3.754408661907416e+00;
|
||||
|
||||
const double Xlow = 0.02425;
|
||||
const double Xhigh = 1.0 - Xlow;
|
||||
|
||||
double z, r;
|
||||
|
||||
if (p < Xlow)
|
||||
{
|
||||
// Rational approximation for the lower region 0<x<u_low
|
||||
z = Math.Sqrt(-2.0 * Math.Log(p));
|
||||
z = (((((C1 * z + C2) * z + C3) * z + C4) * z + C5) * z + C6) /
|
||||
((((D1 * z + D2) * z + D3) * z + D4) * z + 1.0);
|
||||
}
|
||||
else if (p <= Xhigh)
|
||||
{
|
||||
// Rational approximation for the central region u_low<=x<=u_high
|
||||
z = p - 0.5;
|
||||
r = z * z;
|
||||
z = (((((A1 * r + A2) * r + A3) * r + A4) * r + A5) * r + A6) * z /
|
||||
(((((B1 * r + B2) * r + B3) * r + B4) * r + B5) * r + 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rational approximation for the upper region u_high<x<1
|
||||
z = Math.Sqrt(-2.0 * Math.Log(1.0 - p));
|
||||
z = -(((((C1 * z + C2) * z + C3) * z + C4) * z + C5) * z + C6) /
|
||||
((((D1 * z + D2) * z + D3) * z + D4) * z + 1.0);
|
||||
}
|
||||
|
||||
// error (f_(z) - x) divided by the cumulative's derivative
|
||||
r = (CumN0(z) - p) * Math.Sqrt(2.0) * Math.Sqrt(Math.PI) * Math.Exp(0.5 * z * z);
|
||||
|
||||
// Halley's method
|
||||
z -= r / (1 + (0.5 * z * r));
|
||||
|
||||
return mu + (z * sigma);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cumulative for a N(0,1) distribution
|
||||
/// </summary>
|
||||
/// <returns>The n0.</returns>
|
||||
/// <param name="x">The x coordinate.</param>
|
||||
private static double CumN0(double x)
|
||||
{
|
||||
const double B1 = 0.319381530;
|
||||
const double B2 = -0.356563782;
|
||||
const double B3 = 1.781477937;
|
||||
const double B4 = -1.821255978;
|
||||
const double B5 = 1.330274429;
|
||||
const double P = 0.2316419;
|
||||
const double C = 0.39894228;
|
||||
|
||||
if (x >= 0.0)
|
||||
{
|
||||
double t = 1.0 / (1.0 + (P * x));
|
||||
return (1.0 - C * Math.Exp(-x * x / 2.0) * t * (t * (t * (t * (t * B5 + B4) + B3) + B2) + B1));
|
||||
}
|
||||
else
|
||||
{
|
||||
double t = 1.0 / (1.0 - P * x);
|
||||
return (C * Math.Exp(-x * x / 2.0) * t * (t * (t * (t * (t * B5 + B4) + B3) + B2) + B1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="HighLowSeriesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using ExampleLibrary.Utilities;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("HighLowSeries"), Tags("Series")]
|
||||
public static class HighLowSeriesExamples
|
||||
{
|
||||
[Example("HighLowSeries")]
|
||||
public static PlotModel HighLowSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "HighLowSeries" };
|
||||
var l = new Legend
|
||||
{
|
||||
LegendSymbolLength = 24
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
var s1 = new HighLowSeries { Title = "HighLowSeries 1", Color = OxyColors.Black, };
|
||||
var r = new Random(314);
|
||||
var price = 100.0;
|
||||
for (int x = 0; x < 24; x++)
|
||||
{
|
||||
price = price + r.NextDouble() + 0.1;
|
||||
var high = price + 10 + r.NextDouble() * 10;
|
||||
var low = price - (10 + r.NextDouble() * 10);
|
||||
var open = low + r.NextDouble() * (high - low);
|
||||
var close = low + r.NextDouble() * (high - low);
|
||||
s1.Items.Add(new HighLowItem(x, high, low, open, close));
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, MaximumPadding = 0.3, MinimumPadding = 0.3 });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("HighLowSeries (reversed X Axis)")]
|
||||
public static PlotModel HighLowSeriesReversedXAxis()
|
||||
{
|
||||
return HighLowSeries().ReverseXAxis();
|
||||
}
|
||||
|
||||
[Example("HighLowSeries (DateTime axis)")]
|
||||
public static PlotModel HighLowSeriesDateTimeAxis()
|
||||
{
|
||||
var m = new PlotModel();
|
||||
var x0 = DateTimeAxis.ToDouble(new DateTime(2013, 05, 04));
|
||||
var a = new DateTimeAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
Minimum = x0 - 0.9,
|
||||
Maximum = x0 + 1.9,
|
||||
IntervalType = DateTimeIntervalType.Days,
|
||||
MajorStep = 1,
|
||||
MinorStep = 1,
|
||||
StringFormat = "yyyy-MM-dd"
|
||||
};
|
||||
m.Axes.Add(a);
|
||||
var s = new HighLowSeries
|
||||
{
|
||||
TrackerFormatString =
|
||||
"X: {1:yyyy-MM-dd}\nHigh: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}"
|
||||
};
|
||||
|
||||
s.Items.Add(new HighLowItem(x0, 14, 10, 13, 12.4));
|
||||
s.Items.Add(new HighLowItem(x0 + 1, 17, 8, 12.4, 16.3));
|
||||
m.Series.Add(s);
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="OhlcvItemGenerator.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Creates realistic OHLCV items.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
/// <summary>
|
||||
/// Creates realistic OHLCV items.
|
||||
/// </summary>
|
||||
public static class OhlcvItemGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The random number generator.
|
||||
/// </summary>
|
||||
private static readonly Random Rand = new Random();
|
||||
|
||||
/// <summary>
|
||||
/// Creates bars governed by a MR process.
|
||||
/// </summary>
|
||||
/// <param name="n">N.</param>
|
||||
/// <param name="x0">X0.</param>
|
||||
/// <param name="v0">V0.</param>
|
||||
/// <param name="csigma">Csigma.</param>
|
||||
/// <param name="esigma">Esigma.</param>
|
||||
/// <param name="kappa">Kappa.</param>
|
||||
/// <returns>
|
||||
/// The process.
|
||||
/// </returns>
|
||||
public static IEnumerable<OhlcvItem> MRProcess(
|
||||
int n,
|
||||
double x0 = 100.0,
|
||||
double v0 = 500,
|
||||
double csigma = 0.50,
|
||||
double esigma = 0.75,
|
||||
double kappa = 0.01)
|
||||
{
|
||||
double x = x0;
|
||||
var baseT = DateTime.UtcNow;
|
||||
for (int ti = 0; ti < n; ti++)
|
||||
{
|
||||
var dx_c = -kappa * (x - x0) + RandomNormal(0, csigma);
|
||||
var dx_1 = -kappa * (x - x0) + RandomNormal(0, esigma);
|
||||
var dx_2 = -kappa * (x - x0) + RandomNormal(0, esigma);
|
||||
|
||||
var open = x;
|
||||
var close = x = x + dx_c;
|
||||
var low = Min(open, close, open + dx_1, open + dx_2);
|
||||
var high = Max(open, close, open + dx_1, open + dx_2);
|
||||
|
||||
var dp = close - open;
|
||||
var v = v0 * Math.Exp(Math.Abs(dp) / csigma);
|
||||
var dir = (dp < 0) ?
|
||||
-Math.Min(-dp / esigma, 1.0) :
|
||||
Math.Min(dp / esigma, 1.0);
|
||||
|
||||
var skew = (dir + 1) / 2.0;
|
||||
var buyvol = skew * v;
|
||||
var sellvol = (1 - skew) * v;
|
||||
|
||||
var nowT = baseT.AddSeconds(ti);
|
||||
var t = DateTimeAxis.ToDouble(nowT);
|
||||
yield return new OhlcvItem(t, open, high, low, close, buyvol, sellvol);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the minimum of the specified a, b, c and d.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">B.</param>
|
||||
/// <param name="c">C.</param>
|
||||
/// <param name="d">D.</param>
|
||||
/// <returns>The minimum.</returns>
|
||||
private static double Min(double a, double b, double c, double d)
|
||||
{
|
||||
return Math.Min(a, Math.Min(b, Math.Min(c, d)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the maximum of the specified a, b, c and d.
|
||||
/// </summary>
|
||||
/// <param name="a">A.</param>
|
||||
/// <param name="b">B.</param>
|
||||
/// <param name="c">C.</param>
|
||||
/// <param name="d">D.</param>
|
||||
/// <returns>The maximum.</returns>
|
||||
private static double Max(double a, double b, double c, double d)
|
||||
{
|
||||
return Math.Max(a, Math.Max(b, Math.Max(c, d)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets random normal
|
||||
/// </summary>
|
||||
/// <param name="mu">Mu.</param>
|
||||
/// <param name="sigma">Sigma.</param>
|
||||
/// <returns></returns>
|
||||
private static double RandomNormal(double mu, double sigma)
|
||||
{
|
||||
return InverseCumNormal(Rand.NextDouble(), mu, sigma);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fast approximation for inverse cum normal
|
||||
/// </summary>
|
||||
/// <param name="p">probability</param>
|
||||
/// <param name="mu">Mean</param>
|
||||
/// <param name="sigma">std dev</param>
|
||||
private static double InverseCumNormal(double p, double mu, double sigma)
|
||||
{
|
||||
const double A1 = -3.969683028665376e+01;
|
||||
const double A2 = 2.209460984245205e+02;
|
||||
const double A3 = -2.759285104469687e+02;
|
||||
const double A4 = 1.383577518672690e+02;
|
||||
const double A5 = -3.066479806614716e+01;
|
||||
const double A6 = 2.506628277459239e+00;
|
||||
|
||||
const double B1 = -5.447609879822406e+01;
|
||||
const double B2 = 1.615858368580409e+02;
|
||||
const double B3 = -1.556989798598866e+02;
|
||||
const double B4 = 6.680131188771972e+01;
|
||||
const double B5 = -1.328068155288572e+01;
|
||||
|
||||
const double C1 = -7.784894002430293e-03;
|
||||
const double C2 = -3.223964580411365e-01;
|
||||
const double C3 = -2.400758277161838e+00;
|
||||
const double C4 = -2.549732539343734e+00;
|
||||
const double C5 = 4.374664141464968e+00;
|
||||
const double C6 = 2.938163982698783e+00;
|
||||
|
||||
const double D1 = 7.784695709041462e-03;
|
||||
const double D2 = 3.224671290700398e-01;
|
||||
const double D3 = 2.445134137142996e+00;
|
||||
const double D4 = 3.754408661907416e+00;
|
||||
|
||||
const double Xlow = 0.02425;
|
||||
const double Xhigh = 1.0 - Xlow;
|
||||
|
||||
double z, r;
|
||||
|
||||
if (p < Xlow)
|
||||
{
|
||||
// Rational approximation for the lower region 0<x<u_low
|
||||
z = Math.Sqrt(-2.0 * Math.Log(p));
|
||||
z = (((((C1 * z + C2) * z + C3) * z + C4) * z + C5) * z + C6) /
|
||||
((((D1 * z + D2) * z + D3) * z + D4) * z + 1.0);
|
||||
}
|
||||
else if (p <= Xhigh)
|
||||
{
|
||||
// Rational approximation for the central region u_low<=x<=u_high
|
||||
z = p - 0.5;
|
||||
r = z * z;
|
||||
z = (((((A1 * r + A2) * r + A3) * r + A4) * r + A5) * r + A6) * z /
|
||||
(((((B1 * r + B2) * r + B3) * r + B4) * r + B5) * r + 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rational approximation for the upper region u_high<x<1
|
||||
z = Math.Sqrt(-2.0 * Math.Log(1.0 - p));
|
||||
z = -(((((C1 * z + C2) * z + C3) * z + C4) * z + C5) * z + C6) /
|
||||
((((D1 * z + D2) * z + D3) * z + D4) * z + 1.0);
|
||||
}
|
||||
|
||||
// error (f_(z) - x) divided by the cumulative's derivative
|
||||
r = (CumN0(z) - p) * Math.Sqrt(2.0) * Math.Sqrt(Math.PI) * Math.Exp(0.5 * z * z);
|
||||
|
||||
// Halley's method
|
||||
z -= r / (1 + (0.5 * z * r));
|
||||
|
||||
return mu + (z * sigma);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cumulative for a N(0,1) distribution
|
||||
/// </summary>
|
||||
/// <returns>The n0.</returns>
|
||||
/// <param name="x">The x coordinate.</param>
|
||||
private static double CumN0(double x)
|
||||
{
|
||||
const double B1 = 0.319381530;
|
||||
const double B2 = -0.356563782;
|
||||
const double B3 = 1.781477937;
|
||||
const double B4 = -1.821255978;
|
||||
const double B5 = 1.330274429;
|
||||
const double P = 0.2316419;
|
||||
const double C = 0.39894228;
|
||||
|
||||
if (x >= 0.0)
|
||||
{
|
||||
double t = 1.0 / (1.0 + (P * x));
|
||||
return (1.0 - C * Math.Exp(-x * x / 2.0) * t * (t * (t * (t * (t * B5 + B4) + B3) + B2) + B1));
|
||||
}
|
||||
else
|
||||
{
|
||||
double t = 1.0 / (1.0 - P * x);
|
||||
return (C * Math.Exp(-x * x / 2.0) * t * (t * (t * (t * (t * B5 + B4) + B3) + B2) + B1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="OldCandleStickSeriesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("Old CandleStickSeries"), Tags("Series")]
|
||||
[Obsolete]
|
||||
public static class OldCandleStickSeriesExamples
|
||||
{
|
||||
[Example("CandleStickSeries")]
|
||||
public static PlotModel CandleStickSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "CandleStickSeries" };
|
||||
var l = new Legend
|
||||
{
|
||||
LegendSymbolLength = 24
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
var s1 = new OldCandleStickSeries
|
||||
{
|
||||
Title = "CandleStickSeries 1",
|
||||
Color = OxyColors.Black,
|
||||
};
|
||||
var r = new Random(314);
|
||||
var price = 100.0;
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
price = price + r.NextDouble() + 0.1;
|
||||
var high = price + 10 + (r.NextDouble() * 10);
|
||||
var low = price - (10 + (r.NextDouble() * 10));
|
||||
var open = low + (r.NextDouble() * (high - low));
|
||||
var close = low + (r.NextDouble() * (high - low));
|
||||
s1.Items.Add(new HighLowItem(x, high, low, open, close));
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, MaximumPadding = 0.3, MinimumPadding = 0.3 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, MaximumPadding = 0.03, MinimumPadding = 0.03 });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("CandleStickSeries (red/green)")]
|
||||
public static PlotModel CandleStickSeriesRedGreen()
|
||||
{
|
||||
var model = CandleStickSeries();
|
||||
model.Title = "CandleStickSeries (red/green)";
|
||||
var s1 = (OldCandleStickSeries)model.Series[0];
|
||||
s1.IncreasingFill = OxyColors.DarkGreen;
|
||||
s1.DecreasingFill = OxyColors.Red;
|
||||
s1.ShadowEndColor = OxyColors.Gray;
|
||||
s1.Color = OxyColors.Black;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Minute data (DateTimeAxis)")]
|
||||
public static PlotModel MinuteData_DateTimeAxis()
|
||||
{
|
||||
var pm = new PlotModel { Title = "Minute Data (DateTimeAxis)" };
|
||||
|
||||
var timeSpanAxis1 = new DateTimeAxis { Position = AxisPosition.Bottom, StringFormat = "hh:mm" };
|
||||
pm.Axes.Add(timeSpanAxis1);
|
||||
var linearAxis1 = new LinearAxis { Position = AxisPosition.Left };
|
||||
pm.Axes.Add(linearAxis1);
|
||||
var candleStickSeries = new OldCandleStickSeries
|
||||
{
|
||||
CandleWidth = 6,
|
||||
Color = OxyColors.Black,
|
||||
IncreasingFill = OxyColors.DarkGreen,
|
||||
DecreasingFill = OxyColors.Red,
|
||||
DataFieldX = "Time",
|
||||
DataFieldHigh = "H",
|
||||
DataFieldLow = "L",
|
||||
DataFieldOpen = "O",
|
||||
DataFieldClose = "C",
|
||||
TrackerFormatString = "High: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}",
|
||||
ItemsSource = lst
|
||||
};
|
||||
pm.Series.Add(candleStickSeries);
|
||||
return pm;
|
||||
}
|
||||
|
||||
private static List<MinuteRec> lst = new List<MinuteRec>
|
||||
{
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:31:00"), O = 1672.5000, H = 1673.5000, L = 1671.7500, C = 1672.7500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:32:00"), O = 1672.5000, H = 1673.5000, L = 1672.5000, C = 1672.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:33:00"), O = 1672.5000, H = 1672.7500, L = 1670.7500, C = 1671.2500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:34:00"), O = 1671.2500, H = 1671.2500, L = 1670.2500, C = 1670.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:35:00"), O = 1670.7500, H = 1671.7500, L = 1670.5000, C = 1671.2500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:36:00"), O = 1671.0000, H = 1672.5000, L = 1671.0000, C = 1672.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:37:00"), O = 1672.5000, H = 1673.0000, L = 1672.0000, C = 1673.0000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:38:00"), O = 1672.7500, H = 1673.2500, L = 1672.5000, C = 1672.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:39:00"), O = 1672.5000, H = 1672.7500, L = 1671.2500, C = 1671.2500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:40:00"), O = 1671.2500, H = 1672.5000, L = 1671.0000, C = 1672.0000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:41:00"), O = 1672.2500, H = 1672.5000, L = 1671.2500, C = 1672.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:42:00"), O = 1672.2500, H = 1672.5000, L = 1671.5000, C = 1671.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:43:00"), O = 1671.5000, H = 1671.7500, L = 1670.5000, C = 1671.0000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:44:00"), O = 1670.7500, H = 1671.7500, L = 1670.7500, C = 1671.7500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:45:00"), O = 1672.0000, H = 1672.2500, L = 1671.5000, C = 1671.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:46:00"), O = 1671.7500, H = 1671.7500, L = 1671.0000, C = 1671.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:47:00"), O = 1671.7500, H = 1672.2500, L = 1671.5000, C = 1671.7500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:48:00"), O = 1671.7500, H = 1672.7500, L = 1671.7500, C = 1672.5000 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:49:00"), O = 1672.2500, H = 1673.7500, L = 1672.2500, C = 1673.7500 },
|
||||
new MinuteRec { QTime = TimeSpan.Parse("06:50:00"), O = 1673.7500, H = 1675.0000, L = 1673.5000, C = 1675.0000 }
|
||||
};
|
||||
|
||||
[Example("Minute data (TimeSpanAxis)")]
|
||||
public static PlotModel MinuteData_TimeSpan()
|
||||
{
|
||||
var pm = new PlotModel { Title = "Minute Data (TimeSpanAxis)" };
|
||||
|
||||
var timeSpanAxis1 = new TimeSpanAxis { Position = AxisPosition.Bottom, StringFormat = "hh:mm" };
|
||||
pm.Axes.Add(timeSpanAxis1);
|
||||
var linearAxis1 = new LinearAxis { Position = AxisPosition.Left };
|
||||
pm.Axes.Add(linearAxis1);
|
||||
var candleStickSeries = new OldCandleStickSeries
|
||||
{
|
||||
CandleWidth = 5,
|
||||
Color = OxyColors.DarkGray,
|
||||
IncreasingFill = OxyColors.DarkGreen,
|
||||
DecreasingFill = OxyColors.Red,
|
||||
DataFieldX = "QTime",
|
||||
DataFieldHigh = "H",
|
||||
DataFieldLow = "L",
|
||||
DataFieldOpen = "O",
|
||||
DataFieldClose = "C",
|
||||
TrackerFormatString = "High: {2:0.00}\nLow: {3:0.00}\nOpen: {4:0.00}\nClose: {5:0.00}",
|
||||
ItemsSource = lst
|
||||
};
|
||||
pm.Series.Add(candleStickSeries);
|
||||
return pm;
|
||||
}
|
||||
|
||||
public class MinuteRec
|
||||
{
|
||||
public DateTime Time { get { return new DateTime(2013, 10, 8) + this.QTime; } }
|
||||
public TimeSpan QTime { get; set; }
|
||||
public double H { get; set; }
|
||||
public double L { get; set; }
|
||||
public double O { get; set; }
|
||||
public double C { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="VolumeSeriesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("VolumeSeries")]
|
||||
[Tags("Series")]
|
||||
public static class VolumeSeriesExamples
|
||||
{
|
||||
[Example("Just Volume (combined), fixed axis")]
|
||||
public static Example JustVolumeCombined_Fixed()
|
||||
{
|
||||
return CreateVolumeSeries("Just Volume (combined)", VolumeStyle.Combined, natural: false);
|
||||
}
|
||||
|
||||
[Example("Just Volume (combined), natural axis")]
|
||||
public static Example JustVolumeCombined_Natural()
|
||||
{
|
||||
return CreateVolumeSeries("Just Volume (combined)", VolumeStyle.Combined, natural: true);
|
||||
}
|
||||
|
||||
[Example("Just Volume (stacked), fixed axis")]
|
||||
public static Example JustVolumeStacked_Fixed()
|
||||
{
|
||||
return CreateVolumeSeries("Just Volume (stacked)", VolumeStyle.Stacked, natural: false);
|
||||
}
|
||||
|
||||
[Example("Just Volume (stacked), natural axis")]
|
||||
public static Example JustVolumeStacked_Natural()
|
||||
{
|
||||
return CreateVolumeSeries("Just Volume (stacked)", VolumeStyle.Stacked, natural: true);
|
||||
}
|
||||
|
||||
[Example("Just Volume (+/-), fixed axis")]
|
||||
public static Example JustVolumePositiveNegative_Fixed()
|
||||
{
|
||||
return CreateVolumeSeries("Just Volume (+/-)", VolumeStyle.PositiveNegative, natural: false);
|
||||
}
|
||||
|
||||
[Example("Just Volume (+/-), natural axis")]
|
||||
public static Example JustVolumePositiveNegative_Natural()
|
||||
{
|
||||
return CreateVolumeSeries("Just Volume (+/-)", VolumeStyle.PositiveNegative, natural: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the volume series.
|
||||
/// </summary>
|
||||
/// <returns>The volume series.</returns>
|
||||
/// <param name="title">Title.</param>
|
||||
/// <param name="style">Style.</param>
|
||||
/// <param name="n">N.</param>
|
||||
/// <param name="natural">If set to <c>true</c> natural.</param>
|
||||
/// <param name="transposed">If set to <c>true</c> transposed.</param>
|
||||
private static Example CreateVolumeSeries(
|
||||
string title,
|
||||
VolumeStyle style,
|
||||
int n = 10000,
|
||||
bool natural = false)
|
||||
{
|
||||
var pm = new PlotModel { Title = title };
|
||||
|
||||
var series = new VolumeSeries
|
||||
{
|
||||
PositiveColor = OxyColors.DarkGreen,
|
||||
NegativeColor = OxyColors.Red,
|
||||
PositiveHollow = false,
|
||||
NegativeHollow = false,
|
||||
VolumeStyle = style,
|
||||
Title = "VolumeSeries",
|
||||
};
|
||||
|
||||
// create bars
|
||||
foreach (var bar in OhlcvItemGenerator.MRProcess(n))
|
||||
{
|
||||
series.Append(bar);
|
||||
}
|
||||
|
||||
// create visible window
|
||||
var Istart = n - 200;
|
||||
var Iend = n - 120;
|
||||
var Xmin = series.Items[Istart].X;
|
||||
var Xmax = series.Items[Iend].X;
|
||||
|
||||
// setup axes
|
||||
var timeAxis = new DateTimeAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
Minimum = Xmin,
|
||||
Maximum = Xmax
|
||||
};
|
||||
|
||||
var volAxis = new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
StartPosition = 0.0,
|
||||
EndPosition = 1.0,
|
||||
Minimum = natural ? double.NaN : 0,
|
||||
Maximum = natural ? double.NaN : 10000
|
||||
};
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case VolumeStyle.Combined:
|
||||
case VolumeStyle.Stacked:
|
||||
pm.Axes.Add(timeAxis);
|
||||
pm.Axes.Add(volAxis);
|
||||
break;
|
||||
|
||||
case VolumeStyle.PositiveNegative:
|
||||
volAxis.Minimum = natural ? double.NaN : -10000;
|
||||
pm.Axes.Add(timeAxis);
|
||||
pm.Axes.Add(volAxis);
|
||||
break;
|
||||
}
|
||||
|
||||
pm.Series.Add(series);
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
|
||||
return new Example(pm, controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user