如何禁用 MSChart 烛台的自动 "PriceUp/Down" 颜色并在需要时填充?

How to disable MSChart candlestick's automatic "PriceUp/Down" colors and fill when needed?

是否有任何方法可以操纵,甚至可以覆盖烛台图表的着色方式?

我想要做的应该是这样的:

这里发生的事情是,当 "Open" 价格高于 "Close" 价格时,蜡烛填充颜色,反之则填充黑色。

但这在 MS Chart 中是不可能的?我正在考虑在另一个烛台系列之上创建另一个烛台系列,并从中获得填充框,但它不起作用,因为 MS Chart 自动使用 "PriceDown/Up" 颜色。 ...请参阅下面的回答。

这是我使用的代码,但它无法按照我想要的方式工作:

DataPointCollection dpcCandle = Series[Candle].Points;
DataPointCollection dpcPrice = Series[Price].Points;

int candleCount = dpcCandle.Count;

dpcCandle.AddXY(time, high);
dpcCandle[candleCount].YValues[1] = low;
dpcCandle[candleCount].YValues[2] = open;
dpcCandle[candleCount].YValues[3] = close;

if( candleCount > 1 )
{
    Color col;
    float oldClose = (float)dpcCandle[candleCount-1].YValues[3];
    float oldOpen = (float)dpcCandle[candleCount-1].YValues[2];

    dpcCandle[candleCount].BorderWidth = 1;

    // Determine color
    if( oldClose <= close) // Price up!
        col = Color.ForestGreen;
    else // Price down...
        col = Color.Red;

    // Determine fill
    if( open < close )
    {
        dpcCandle[candleCount].Color = Color.Black;
        dpcCandle[candleCount].BorderColor = col;
    }
    else
    {
        dpcCandle[candleCount].Color = col;
        dpcCandle[candleCount].BorderColor = col;
    }

    if( oldOpen.Equals(close) )
    {
        dpcCandle[candleCount].Color = dpcCandle[candleCount-1].Color;
        dpcCandle[candleCount].BorderColor = dpcCandle[candleCount-1].BorderColor;
    }
}

好吧,它有效,但结果如下所示:

...使用这些设置:

Series[Candle]["PriceUpColor"] = "Black";
Series[Candle]["PriceDownColor"] = "Black";

当我将它们更改为这些时:

Series[Candle]["PriceUpColor"] = "ForestGreen";
Series[Candle]["PriceDownColor"] = "Red";

...我得到的结果是这个丑陋的烂摊子:

提前致谢。

设置PriceUpColorPriceDownColor是必要且正确的。为什么要设置其他颜色??所有蜡烛着色都应该自动发生!

如果您想在 Chart chart1Series "price" 中设置垂直条的样式,您可以像这样设置 DataPoint.Color 来实现:

chart1.Series["price"].BorderWidth = 4;
foreach(DataPoint dp in chart1.Series["price"].Points)
{
    dp.Color =  (dp.YValues[2] > dp.YValues[3]) ? Color.CadetBlue : Color.Pink;
}

我从 zeFrenchy 的 this post 那里获取了代码和数据。这是结果:

我在添加数据后添加了循环。但是你也可以边加分边做..

好的,所以我能够做解决方法,其中包括总共 三个 两个烛台系列...它有点丑,但它满足了我的要求。

设置:

// ****************************
// Candlestick setup
Series[Candle].ChartType = SeriesChartType.Candlestick;
Series[Candle]["OpenCloseStyle"] = "Triangle";
Series[Candle]["ShowOpenClose"] = "Both";
Series[Candle]["PriceUpColor"] = "Black";
Series[Candle]["PriceDownColor"] = "Black";
Series[Candle]["PointWidth"] = "0.75";

Series[CandleGreen].ChartType = SeriesChartType.Candlestick;
Series[CandleGreen]["OpenCloseStyle"] = "Triangle";
Series[CandleGreen]["ShowOpenClose"] = "Both";
Series[CandleGreen]["PriceUpColor"] = "ForestGreen";
Series[CandleGreen]["PriceDownColor"] = "Red";
Series[CandleGreen]["PointWidth"] = "0.75";
Series[CandleGreen].BorderColor = Color.Transparent;

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

然后我这样做了:

DataPointCollection dpcCandle = Series[Candle].Points;
DataPointCollection dpcCandleG = Series[CandleGreen].Points;
DataPointCollection dpcPrice = Series[Price].Points;

// Point count
int candleCount = dpcCandle.Count;

// Add the new point
dpcCandle.AddXY(time, high);
dpcCandle[candleCount].YValues[1] = low;
dpcCandle[candleCount].YValues[2] = open;
dpcCandle[candleCount].YValues[3] = close;

// Add the hacks...
int g = dpcCandleG.AddXY(dpcCandle[candleCount].XValue, 0);
        dpcCandleG[g].YValues[1] = 0;
        dpcCandleG[g].YValues[2] = 0;
        dpcCandleG[g].YValues[3] = 0;

if( candleCount > 1 )
{
    float oldClose = (float)dpcCandle[candleCount-1].YValues[3];
    float oldOpen = (float)dpcCandle[candleCount-1].YValues[2];

    dpcCandle[candleCount].BorderWidth = 1;

    // Determine color
    if( oldClose <= close) // Price up!
    {
        dpcCandle[candleCount].Color = Color.ForestGreen;
        dpcCandle[candleCount].BorderColor = Color.ForestGreen;
    }
    else // Price down...
    {
        dpcCandle[candleCount].Color = Color.Red;
        dpcCandle[candleCount].BorderColor = Color.Red;
    }

    // Determine fill
    if( open > close )
    {
        if( dpcCandle[candleCount].Color == Color.Red )
        {
            dpcCandleG[g].YValues[2] = open;
            dpcCandleG[g].YValues[3] = close;
        }
        else if( dpcCandle[candleCount].Color == Color.ForestGreen )
        {
            dpcCandleG[g].YValues[2] = close;
            dpcCandleG[g].YValues[3] = open;
        }
    }

    if( oldOpen.Equals(close) )
    {
        dpcCandle[candleCount].Color = dpcCandle[candleCount-1].Color;
        dpcCandle[candleCount].BorderColor = dpcCandle[candleCount-1].BorderColor;
    }
}

结果: