public void SetUpChart()
{
// Panel caption
stringCaptionText = Language.T("Indicator Chart");
fontCaptionText = new Font(Font.FontFamily, 9);
captionHeight = Math.Max(fontCaptionText.Height, 18);
captionWidth = this.ClientSize.Width;
brushCaptionText = new SolidBrush(LayoutColors.ColorCaptionText);
rectfCaption = new RectangleF(0, 0, captionWidth, captionHeight);
stringFormatCaption = new StringFormat();
stringFormatCaption.Alignment |= StringAlignment.Center;
stringFormatCaption.LineAlignment |= StringAlignment.Center;
stringFormatCaption.Trimming |= StringTrimming.EllipsisCharacter;
stringFormatCaption.FormatFlags |= StringFormatFlags.NoWrap;
if (!Data.IsData || !Data.IsResult || Data.Bars <= Data.FirstBar) return;
clSzWidth = this.ClientSize.Width;
clSzHeight = this.ClientSize.Height;
xLeft = space;
xRight = clSzWidth - space;
yTop = (int)captionHeight + space;
yBottom = clSzHeight - scrollBar.Height - space;
yPrcBottom = yBottom; // Price chart y
inds = 0; // Count of separated indicators
indHeight = 0; // Height of Ind charts
aiIndSlot = new int[12];
penFore = new Pen(LayoutColors.ColorChartFore);
penVolume = new Pen(LayoutColors.ColorVolume);
penBorder = new Pen(Data.GetGradientColor(LayoutColors.ColorCaptionBack, -LayoutColors.DepthCaption), border);
for (int slot = Data.Strategy.Slots - 1; slot >= 0; slot--)
if (Data.Strategy.Slot[slot].SeparatedChart)
aiIndSlot[inds++] = slot;
if (inds > 0)
{
indHeight = (yBottom - yTop) / (2 + inds);
yPrcBottom = yBottom - inds * indHeight;
}
maxPrice = double.MinValue;
minPrice = double.MaxValue;
maxVolume = int.MinValue;
for (int bar = firstBar; bar <= lastBar; bar++)
{
if (Data.High[bar] > maxPrice ) maxPrice = Data.High[bar];
if (Data.Low[bar] < minPrice ) minPrice = Data.Low[bar];
if (Data.Volume[bar] > maxVolume) maxVolume = Data.Volume[bar];
}
minPrice = Math.Round(minPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) - Data.InstrProperties.Point * 10;
maxPrice = Math.Round(maxPrice, Data.InstrProperties.Point < 0.001 ? 3 : 1) + Data.InstrProperties.Point * 10;
scaleY = (yPrcBottom - yTop) / (maxPrice - minPrice);
scaleYVol = maxVolume > 0 ? ((yPrcBottom - yTop) / 8d) / maxVolume : 0d;
// Volume, Lots and Price
x = new int[chartBars];
yOpen = new int[chartBars];
yHigh = new int[chartBars];
yLow = new int[chartBars];
yClose = new int[chartBars];
yVolume = new int[chartBars];
rectPosition = new Rectangle[chartBars];
brushPosition = new Brush[chartBars];
int index = 0;
for (int bar = firstBar; bar <= lastBar; bar++)
{
x[index] = (bar - firstBar) * barPixels + xLeft;
yOpen[index] = (int)(yPrcBottom - (Data.Open[bar] - minPrice) * scaleY);
yHigh[index] = (int)(yPrcBottom - (Data.High[bar] - minPrice) * scaleY);
yLow[index] = (int)(yPrcBottom - (Data.Low[bar] - minPrice) * scaleY);
yClose[index] = (int)(yPrcBottom - (Data.Close[bar] - minPrice) * scaleY);
yVolume[index] = (int)(yPrcBottom - Data.Volume[bar] * scaleYVol);
// Draw position lots
if (Backtester.IsPos(bar))
{
int iPosHight = (int)(Math.Max(Backtester.SummaryLots(bar) * 2, 2));
int iPosY = yPrcBottom - iPosHight;
if (Backtester.SummaryDir(bar) == PosDirection.Long)
{ // Long
rectPosition[index] = new Rectangle(x[index], iPosY, 1, iPosHight);
brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeLong);
}
else if (Backtester.SummaryDir(bar) == PosDirection.Short)
{ // Short
rectPosition[index] = new Rectangle(x[index], iPosY, 1, iPosHight);
brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeShort);
}
else
{ // Close position
rectPosition[index] = new Rectangle(x[index], iPosY - 2, 1, 2);
brushPosition[index] = new SolidBrush(LayoutColors.ColorTradeClose);
}
}
else
{ // There is no position
rectPosition[index] = Rectangle.Empty;
brushPosition[index] = new SolidBrush(LayoutColors.ColorChartBack);
}
index++;
}
// Indicators in the chart
slots = Data.Strategy.Slots;
bIsSeparatedChart = new bool[slots];
iComponentLenght = new int[slots];
chartType = new IndChartType[slots][];
chartLine = new Point[slots][][];
chartDot = new Rectangle[slots][][];
chartLevel = new Rectangle[slots][][];
chartValue = new double[slots][][];
chartPen = new Pen[slots][][];
chartBrush = new Brush[slots][];
for (int iSlot = 0; iSlot < slots; iSlot++)
{
bIsSeparatedChart[iSlot] = Data.Strategy.Slot[iSlot].SeparatedChart;
int iLenght = Data.Strategy.Slot[iSlot].Component.Length;
iComponentLenght[iSlot] = iLenght;
chartType[iSlot] = new IndChartType[iLenght];
chartLine[iSlot] = new Point[iLenght][];
chartDot[iSlot] = new Rectangle[iLenght][];
chartLevel[iSlot] = new Rectangle[iLenght][];
chartValue[iSlot] = new double[iLenght][];
chartPen[iSlot] = new Pen[iLenght][];
chartBrush[iSlot] = new Brush[iLenght];
}
for (int slot = 0; slot < slots; slot++)
{
if (bIsSeparatedChart[slot]) continue;
for (int comp = 0; comp < iComponentLenght[slot]; comp++)
{
chartType[slot][comp] = Data.Strategy.Slot[slot].Component[comp].ChartType;
if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Line ||
Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudUp ||
Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.CloudDown )
{ // Line
chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
chartLine[slot][comp] = new Point[lastBar - firstBar + 1];
for (int bar = firstBar; bar <= lastBar; bar++)
{
double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
int ix = (bar - firstBar) * barPixels + xLeft;
int iy = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
if(dValue == 0)
chartLine[slot][comp][bar - firstBar] = chartLine[slot][comp][Math.Max(bar - firstBar - 1, 0)];
else
chartLine[slot][comp][bar - firstBar] = new Point(ix, iy);
}
}
else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Dot)
{ // Dots
chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
chartDot[slot][comp] = new Rectangle[lastBar - firstBar + 1];
for (int bar = firstBar; bar <= lastBar; bar++)
{
double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
int ix = (bar - firstBar) * barPixels + xLeft;
int iy = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
chartDot[slot][comp][bar-firstBar] = new Rectangle(ix, iy, 1, 1);
}
}
else if (Data.Strategy.Slot[slot].Component[comp].ChartType == IndChartType.Level)
{ // Level
chartBrush[slot][comp] = new SolidBrush(Data.Strategy.Slot[slot].Component[comp].ChartColor);
chartLevel[slot][comp] = new Rectangle[lastBar - firstBar + 1];
for (int bar = firstBar; bar <= lastBar; bar++)
{
double dValue = Data.Strategy.Slot[slot].Component[comp].Value[bar];
int ix = (bar - firstBar) * barPixels + xLeft;
int iy = (int)(yPrcBottom - (dValue - minPrice) * scaleY);
chartLevel[slot][comp][bar - firstBar] = new Rectangle(ix, iy, barPixels, 1);
}
}
}
}
// Separate indicators
yIndTop = new int[inds];
yIndBottom = new int[inds];
dMaxValue = new double[inds];
dMinValue = new double[inds];
dScale = new double[inds];
for (int ind = 0; ind < inds; ind++)
{
yIndTop[ind] = yBottom - (ind + 1) * indHeight + 1;
yIndBottom[ind] = yBottom - ind * indHeight - 1;
dMaxValue[ind] = double.MinValue;
dMinValue[ind] = double.MaxValue;
int iSlot = aiIndSlot[ind];
double dValue;
for (int iComp = 0; iComp < iComponentLenght[iSlot]; iComp++)
if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType != IndChartType.NoChart)
for (bar = Math.Max(firstBar, Data.Strategy.Slot[iSlot].Component[iComp].FirstBar); bar <= lastBar; bar++)
{
dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
if (dValue > dMaxValue[ind]) dMaxValue[ind] = dValue;
if (dValue < dMinValue[ind]) dMinValue[ind] = dValue;
}
dMaxValue[ind] = Math.Max(dMaxValue[ind], Data.Strategy.Slot[iSlot].MaxValue);
dMinValue[ind] = Math.Min(dMinValue[ind], Data.Strategy.Slot[iSlot].MinValue);
foreach (double dSpecVal in Data.Strategy.Slot[iSlot].SpecValue)
if (dSpecVal == 0)
{
dMaxValue[ind] = Math.Max(dMaxValue[ind], 0);
dMinValue[ind] = Math.Min(dMinValue[ind], 0);
}
dScale[ind] = (yIndBottom[ind] - yIndTop[ind] - 2) / (Math.Max(dMaxValue[ind] - dMinValue[ind], 0.0001f));
// Indicator chart
for (int iComp = 0; iComp < Data.Strategy.Slot[iSlot].Component.Length; iComp++)
{
chartType[iSlot][iComp] = Data.Strategy.Slot[iSlot].Component[iComp].ChartType;
if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType == IndChartType.Line)
{ // Line
chartBrush[iSlot][iComp] = new SolidBrush(Data.Strategy.Slot[iSlot].Component[iComp].ChartColor);
chartLine[iSlot][iComp] = new Point[lastBar - firstBar + 1];
for (bar = firstBar; bar <= lastBar; bar++)
{
dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
int ix = (bar - firstBar) * barPixels + xLeft;
int iy = (int)(yIndBottom[ind] - 1 - (dValue - dMinValue[ind]) * dScale[ind]);
chartLine[iSlot][iComp][bar - firstBar] = new Point(ix, iy);
}
}
else if (Data.Strategy.Slot[iSlot].Component[iComp].ChartType == IndChartType.Histogram)
{ // Histogram
chartValue[iSlot][iComp] = new double[lastBar - firstBar + 1];
chartPen[iSlot][iComp] = new Pen[lastBar - firstBar + 1];
for (bar = firstBar; bar <= lastBar; bar++)
{
dValue = Data.Strategy.Slot[iSlot].Component[iComp].Value[bar];
chartValue[iSlot][iComp][bar - firstBar] = dValue;
if (dValue > Data.Strategy.Slot[iSlot].Component[iComp].Value[bar - 1])
chartPen[iSlot][iComp][bar - firstBar] = penGreen;
else
chartPen[iSlot][iComp][bar - firstBar] = penRed;
}
}
}
}
}