|
Finance Chart volume profile sample request (C#) |
Posted by Brian Hui on Jan-12-2024 17:52 |
|
Hi Peter,
I just started to develop the volume profile in my finance chart. I tried to search in this support forum. However, it is no suitable sample for me. See whether you can provide a simple sample coding in C# for me. The finishing result should be look like the attached picture. Many thanks!
Regards,
Brian
|
Re: Finance Chart volume profile sample request (C#) |
Posted by Brian Hui on Jan-15-2024 21:43 |
|
Hi Peter,
Yes. It is quite difficult for me to translate the sample code from C++ to C#. It would be highly appreciated if you could help. Many thanks!
Regards,
Brian |
Re: Finance Chart volume profile sample request (C#) |
Posted by Peter Kwan on Jan-16-2024 02:28 |
|
Hi Brian,
Below please find the code in C#. The code is modified from the "Finance Chart (1)" sample code. Basically, the code creates an additional horizontal bar chart and use it as the plot area background of the financial chart. The key is to how to position the horizontal bars correctly.
//==== Start of Code ====
using System;
using ChartDirector;
namespace CSharpChartExplorer
{
public class finance : DemoModule
{
//Name of demo module
public string getName() { return "Finance Chart (1)"; }
//Number of charts produced in this demo module
public int getNoOfCharts() { return 1; }
BarLayer addPriceVolLayer(XYChart c, int startPos, int endPos, double[] priceDataX, double[] volDataY, int color)
{
BarLayer layer = c.addBarLayer(volDataY, color);
layer.setBorderColor(Chart.SameAsMainColor);
layer.setXData(priceDataX);
layer.setBarGap(Chart.TouchBar);
// Create a dedicated axis for this layer to allow us to control the bar
// direction and position for this layer
Axis a = c.addAxis(Chart.Bottom, 10);
a.setAutoScale(0, 0, 1);
a.setRounding(false, false);
layer.setUseYAxis(a);
// If endPos > startPos, reverse bar direction
if (endPos > startPos)
{
a.setReverse();
int temp = startPos;
startPos = endPos;
endPos = temp;
}
// Position the bars by manipulating the axis margin
a.setMargin(c.getPlotArea().getWidth() - endPos, startPos);
return layer;
}
public void createChart(WinChartViewer viewer, int chartIndex)
{
// Create a finance chart demo containing 100 days of data
int noOfDays = 100;
// To compute moving averages starting from the first day, we need to get extra data points
// before the first day
int extraDays = 30;
// In this exammple, we use a random number generator utility to simulate the data. We set up
// the random table to create 6 cols x (noOfDays + extraDays) rows, using 9 as the seed.
RanTable rantable = new RanTable(9, 6, noOfDays + extraDays);
// Set the 1st col to be the timeStamp, starting from Sep 4, 2002, with each row representing
// one day, and counting week days only (jump over Sat and Sun)
rantable.setDateCol(0, Chart.chartTime(2002, 9, 4), 86400, true);
// Set the 2nd, 3rd, 4th and 5th columns to be high, low, open and close data. The open value
// starts from 100, and the daily change is random from -5 to 5.
rantable.setHLOCCols(1, 100, -5, 5);
// Set the 6th column as the vol data from 5 to 25 million
rantable.setCol(5, 50000000, 250000000);
// Now we read the data from the table into arrays
double[] timeStamps = rantable.getCol(0);
double[] highData = rantable.getCol(1);
double[] lowData = rantable.getCol(2);
double[] openData = rantable.getCol(3);
double[] closeData = rantable.getCol(4);
double[] volData = rantable.getCol(5);
// Create a FinanceChart object of width 640 pixels
FinanceChart c = new FinanceChart(640);
// Add a title to the chart
c.addTitle("Finance Chart Demonstration");
// Set the data into the finance chart object
c.setData(timeStamps, highData, lowData, openData, closeData, volData, extraDays);
// Add the main chart with 240 pixels in height
XYChart mainChart = c.addMainChart(240);
// Add a 5 period simple moving average to the main chart, using brown color
c.addSimpleMovingAvg(5, 0x663300);
// Add a 20 period simple moving average to the main chart, using purple color
c.addSimpleMovingAvg(20, 0x9900ff);
// Add HLOC symbols to the main chart, using green/red for up/down days
c.addHLOC(0x008000, 0xcc0000);
// Add 20 days bollinger band to the main chart, using light blue (9999ff) as the border and
// semi-transparent blue (c06666ff) as the fill color
c.addBollingerBand(20, 2, 0x9999ff, unchecked((int)0xc06666ff));
// Add a 75 pixels volume bars sub-chart to the bottom of the main chart, using green/red/grey
// for up/down/flat days
c.addVolBars(75, 0x99ff99, 0xff9999, 0x808080);
mainChart.layoutAxes();
// Set up the price volue chart, which is a chart the same size as the mainChart
// plot area and used as its backgrouind
PlotArea p = mainChart.getPlotArea();
XYChart pvChart = new XYChart(p.getWidth(), p.getHeight(), Chart.Transparent);
pvChart.setPlotArea(0, 0, pvChart.getWidth() - 1, pvChart.getHeight() - 1);
pvChart.swapXY(); // swapXY for horizontal bar chart
pvChart.xAxis().syncAxis(mainChart.yAxis());
// Add price vol layers to the pyChart
double[] volDataY = { 0, 100, 200, 300, 200, 100, 0 };
double[] priceDataX = { 100, 110, 120, 130, 140, 150, 160 };
// The visible candlestick number for the starting and end points of the bars
int PVstartIndex = 0;
int PVendIndex = 29;
// Convert from candlestick number to pixel coordinates
int startOffset = mainChart.getXCoor(PVstartIndex - 0.5) - p.getLeftX();
int endOffset = mainChart.getXCoor(PVendIndex) - p.getLeftX();
addPriceVolLayer(pvChart, startOffset, endOffset, priceDataX, volDataY, 0xffcccc);
double[] volDataY2 = { 0, 300, 200, 300, 100, 50, 0 };
double[] priceDataX2 = { 80, 85, 90, 95, 100, 105, 115 };
int PVstartIndex2 = 30;
int PVendIndex2 = 59;
int startOffset2 = mainChart.getXCoor(PVstartIndex2 - 0.5) - p.getLeftX();
int endOffset2 = mainChart.getXCoor(PVendIndex2) - p.getLeftX();
addPriceVolLayer(pvChart, startOffset2, endOffset2, priceDataX2, volDataY2, 0xffcccc);
double[] testDataY3 = { 0, 300, 200, 300, 100, 500, 0 };
double[] testDataX3 = { 100, 110, 120, 130, 140, 150, 160 };
addPriceVolLayer(pvChart, p.getWidth(), p.getWidth() - 100, testDataX3, testDataY3, 0xccffcc);
// use the price volume chart as the mainChart background
mainChart.setResource("pvChart", pvChart.makeChart());
p.setBackground("@/pvChart", Chart.TopLeft);
// Append a 14-days RSI indicator chart (75 pixels high) after the main chart. The main RSI line
// is purple (800080). Set threshold region to +/- 20 (that is, RSI = 50 +/- 25). The
// upper/lower threshold regions will be filled with red (ff0000)/blue (0000ff).
c.addRSI(75, 14, 0x800080, 20, 0xff0000, 0x0000ff);
// Append a 12-days momentum indicator chart (75 pixels high) using blue (0000ff) color.
c.addMomentum(75, 12, 0x0000ff);
// Output the chart
viewer.Chart = c;
}
}
}
//==== End of Code ====
|
Re: Finance Chart volume profile sample request (C#) |
Posted by Brian Hui on Jan-16-2024 14:56 |
|
Thanks a lot for the sampe, it saved me a lot of time. I tried to add the code with same sample data into the interactive finance chart. I have below questions
1. After pvChart.swapXY() and pvChart.xAxis().syncAxis(mainChart.yAxis()), I found the xAxis of the pvChart is not follow the movement of mainChart.yAxis value.
2. I used the same sample data of your example (priceDataX = { 100, 110, 120, 130, 140, 150, 160 }), it is obvious that the position of the priceDataX are not match with the values of mainchart.yAxis.
Thanks,
Brian
|
Re: Finance Chart volume profile sample request (C#) |
Posted by Peter Kwan on Jan-16-2024 19:03 |
|
Hi Brian,
Sorry for this problem. I forgot that the x-axis for a bar chart is "indented" by default, while the y-axis is not indented. To solve the problem, please add the following line to disable indenting the x-axis:
pvChart.xAxis().setIndent(false);
By default, the axis scale starts and ends at the axis end points. If the axis is from 0 to 100, and there is a data point at 0, the point will be plotted at an axis end point.
However, for a bar chart, if a bar is at 0, it means the "center" of the bar is at 0. So half of the bar will be outside the axis. So for a bar chart, the axis scale will default to "indented" to shift the axis scale inwards. The setIndent can be used to disable indentation.
https://www.advsofteng.com/doc/cdnet.htm#Axis.setIndent.htm
Best Regards
Peter Kwan
|
Re: Finance Chart volume profile sample request (C#) |
Posted by Peter Kwan on Jan-16-2024 19:11 |
|
Hi Brian,
I found another cosmetic issue. The right y-axis is darker than expected. To solve the problem, in the pvChart.setPlotArea(....) line, we need to set the border to transparent:
pvChart.setPlotArea(0, 0, pvChart.getWidth() - 1, pvChart.getHeight() - 1, Chart.Transparent, -1, Chart.Transparent);
Best Regards
Peter Kwan |
Re: Finance Chart volume profile sample request (C#) |
Posted by Peter Kwan on Jan-16-2024 19:17 |
|
Hi Brian,
After some thoughts, I think the best way to configure the plotarea is simply:
pvChart.setPlotArea(0, 0, pvChart.getWidth(), pvChart.getHeight());
Best Regards
Peter Kwan |
Re: Finance Chart volume profile sample request (C#) |
Posted by Brian Hui on Jan-23-2024 22:51 |
|
It works. Thanks! |
|