深入浅出CChart 每日一课——快乐高四第四十七课 强渡关山,SoUI探险特别关之K线图绘制

这一课的内容,将稍微超出CChart一点点,因为CChart并没有包含K线图绘制功能。

但笨笨已经在CChart的基础上进行了一些拓展,实现了K线图绘制。这个拓展库被命名为KChart,是独立于CChart单独发布的。

KChart库目前还比较简单,包含K线绘制、移动平均线绘制、信息显示功能,同时包含MACD、KDJ、VOL三种指标。有计划把指标种类扩展到几十种,不过这要慢慢来。

下面就来看看怎么在SoUI中使用KChart库。实际上,用法和CChart基本上是一样的,前面的课程稍微修改一下就可以了。

首先先简单介绍一下KChart库的情况。和CChart类库的结构完全一样,KChart类库只包含两个类,CKChart和CKChartWnd。其中CKChart类实现了K线图的绘制功能,CKChartWnd类在CKChart类的基础上封装了窗口消息处理的功能。

以下是CKChart类中,与K线绘制直接相关的几个函数。

1) 在蜡烛图区添加一个K线的标签。

int			AddKLine(TCHAR *name);

标签的标题由这里的name参数决定。这里name可以任意设置。

 

2)添加K线图的一根蜡烛。

int			AddKNode(int nIndex, TCHAR* strTime, TCHAR* fmt, double fOpen, double fClose, double fLowest, double fHighest, double fVolume, double fAmount);

参数说明:

nIndex:标签的序号,从0开始。如上图中,日K的序号为0,周K的序号为1,月K的序号为2。

strTime:时间字符串,例如_T(“2019/12/26”),或_T(“2019-12-26 10:30:00”)。

strFmt:时间字符串的格式。此格式完全等同于C库函数strftime的时间格式。例如,上面两个时间字符串的格式分别为_T(“%Y/%m/%d”)和_T(“%Y-%m-%d %H:%M:%S”)。

fOpen:开盘价。

fClose:收盘价。

fLowest:最低价。

fHighest:最高价。

fVolume:成交量。

fAmount:成交额。

3) 增加一条移动平均线。

void		AddMALine(int nIndex, int nThAvg);

参数说明:

nIndex:标签的序号,从0开始。

nThAvg:平均的天数。

例如:AddMALine(0, 5);将为第一个标签的K线图增加一条5日移动平均线。

4) 在指标图区增加一个指标标签。

int			AddIndicator(TCHAR *name);

参数说明:

name:指标名。这里name不能任意设置。

目前支持三种指标,MACD、KDJ和VOL,指标名分别设置成_TEXT(“MACD”)、_TEXT(“KDJ”)、_TEXT(“VOL”)即可,注意所有字母需要大写。如果name不是上述名称,则此函数不起作用。

下面开始以实例来说明KChart类库在SoUI中的使用方法。

为了保持通用性,这里采用快乐高四第四十二课的方法,建立一个普通子窗口绘图。

第一步,新建一个Soui3Wizard应用程序,名字为LessonA47,其中“应用程序标题”设置为“K线图绘制”。

同时,把KChart.h和KChartu.lib拷贝到LessonA47目录中新建的KChart目录下。

第二步,打开MainDlg.h文件,在#pragma once的后面,添加如下代码。

#include "KChart\KChart.h"
using namespace NsKChart;
#pragma comment(lib,"KChart/KChartu.lib")

同时,给CMainDlg类添加一个变量。

HWND m_hWndChart;

第三步,打开MainDlg.cpp文件。

在OnInitDialog函数里,添加如下代码。

CRect rect;
rect = GetClientRect();
m_hWndChart = CreateSubKChartWnd(m_hWnd, L"KChart", rect.left+10, rect.top+40, rect.right-rect.left-20, rect.bottom-rect.top-50);

在OnClose函数里,添加如下代码。

::DestroyWindow(m_hWndChart);

在OnSize函数里面,添加如下代码。

CRect rect;
rect = GetClientRect();
::MoveWindow(m_hWndChart, rect.left+10, rect.top+40, rect.right-rect.left-20, rect.bottom-rect.top-50, TRUE);

第四步,修改dlg_main.xml文件。

找到translucent="1" 这一行,修改为:

translucent="0" 

到目前为止,必要的准备工作已经完成。

第五步,准备K线数据。

在MainDlg.cpp头部,添加如下代码。

typedef struct stMyData
{
	TCHAR strTime[32];
	double fOpen, fClose, fHighest, fLowest, fVolume, fAmount;
}MyData;

MyData HistoryData[] = {
	{_T(" 2015/6/30"),   4006.754,   4277.222,   4279.969,   3847.88,    7.09E+08,   9.42E+11},
	{_T(" 2015/6/29"),   4289.771,    4053.03,   4297.475,   3875.05,    6.74E+08,   9.04E+11},
	{_T(" 2015/6/26"),   4399.933,   4192.873,   4456.896,   4139.53,    5.65E+08,   7.88E+11},
	{_T(" 2015/6/25"),   4711.763,   4527.779,   4720.701,  4483.548,    5.73E+08,   8.65E+11},
	{_T(" 2015/6/24"),   4604.579,    4690.15,   4691.768,  4552.129,    5.43E+08,   8.15E+11},
	{_T(" 2015/6/23"),   4471.613,   4576.492,   4577.939,  4264.772,    4.74E+08,   6.94E+11},
	{_T(" 2015/6/19"),   4689.929,   4478.364,   4744.081,  4476.501,    4.53E+08,   6.85E+11},
	{_T(" 2015/6/18"),    4942.52,   4785.356,   4966.767,  4780.873,    5.07E+08,   7.86E+11},
	{_T(" 2015/6/17"),   4890.551,   4967.898,   4983.658,  4767.216,    5.37E+08,   8.30E+11},
	{_T(" 2015/6/16"),   5004.412,   4887.432,   5029.684,    4842.1,    5.51E+08,   8.95E+11},
	{_T(" 2015/6/15"),   5174.418,   5062.993,   5176.795,  5048.742,    6.38E+08,   1.06E+12},
	{_T(" 2015/6/12"),   5143.343,    5166.35,   5178.191,  5103.401,    6.26E+08,   1.06E+12},
	{_T(" 2015/6/11"),    5101.44,   5121.593,   5122.457,  5050.765,    5.64E+08,   9.75E+11},
	{_T(" 2015/6/10"),   5049.197,   5106.036,   5164.162,  5001.489,    5.97E+08,   1.01E+12},
	{_T("  2015/6/9"),   5145.978,   5113.534,   5147.454,  5042.963,     7.3E+08,   1.15E+12},
	{_T("  2015/6/8"),   5045.694,   5131.881,   5146.949,  4997.481,    8.55E+08,   1.31E+12},
	{_T("  2015/6/5"),   5016.088,   5023.096,   5051.626,  4898.068,    7.72E+08,   1.23E+12},
	{_T("  2015/6/4"),   4912.945,   4947.102,   4947.965,  4647.407,    6.75E+08,   1.05E+12},
	{_T("  2015/6/3"),   4924.381,   4909.978,   4942.065,  4822.442,    6.11E+08,   1.01E+12},
	{_T("  2015/6/2"),   4844.704,   4910.527,   4911.574,  4797.552,    6.24E+08,   9.99E+11},
	{_T("  2015/6/1"),   4633.098,   4828.738,   4829.502,  4615.231,    5.93E+08,   9.34E+11},
	{_T(" 2015/5/29"),   4603.465,   4611.744,   4698.193,  4431.563,    6.11E+08,   9.55E+11},
	{_T(" 2015/5/28"),   4943.742,   4620.266,   4986.503,  4614.241,    7.83E+08,   1.25E+12},
	{_T(" 2015/5/27"),   4932.846,   4941.714,   4958.156,  4857.056,    6.81E+08,   1.12E+12},
	{_T(" 2015/5/26"),    4854.85,   4910.897,   4911.685,  4779.075,    7.05E+08,   1.14E+12},
	{_T(" 2015/5/25"),   4660.075,   4813.798,   4814.672,  4656.825,    6.82E+08,   1.08E+12},
	{_T(" 2015/5/22"),   4584.984,   4657.596,   4658.273,  4562.989,    6.56E+08,   1.01E+12},
	{_T(" 2015/5/21"),   4456.435,   4529.422,   4530.478,  4438.258,    4.65E+08,   7.29E+11},
	{_T(" 2015/5/20"),   4434.979,   4446.288,   4520.538,  4432.279,    5.14E+08,   8.06E+11},
	{_T(" 2015/5/19"),   4285.777,   4417.552,   4418.403,  4285.777,    4.37E+08,   6.94E+11},
	{_T(" 2015/5/18"),   4277.895,   4283.491,   4324.826,  4260.509,     3.8E+08,   5.95E+11},
	{_T(" 2015/5/15"),   4366.822,   4308.691,   4366.822,  4278.553,     4.4E+08,   6.66E+11},
	{_T(" 2015/5/14"),   4372.816,   4378.311,   4397.745,  4329.042,    4.49E+08,   6.70E+11},
	{_T(" 2015/5/13"),   4402.378,    4375.76,   4415.629,  4342.481,     5.1E+08,   7.81E+11},
	{_T(" 2015/5/12"),    4342.37,   4401.219,   4402.309,  4317.975,    5.22E+08,   7.93E+11},
	{_T(" 2015/5/11"),   4231.271,   4333.584,   4334.877,   4187.82,    4.89E+08,   7.15E+11},
	{_T("  2015/5/8"),   4152.984,   4205.917,    4206.86,  4099.042,    3.97E+08,   5.60E+11},
	{_T("  2015/5/7"),   4197.896,   4112.214,   4213.764,  4108.009,    3.95E+08,   5.40E+11},
	{_T("  2015/5/6"),   4311.641,   4229.266,   4376.353,  4187.368,    4.82E+08,   7.17E+11},
	{_T("  2015/5/5"),   4479.848,   4298.706,   4488.865,  4282.237,    5.73E+08,   8.06E+11},
	{_T("  2015/5/4"),   4441.343,   4480.464,    4487.57,  4387.426,    4.94E+08,   7.18E+11},
	{_T(" 2015/4/30"),   4483.013,   4441.655,   4507.344,  4441.054,    5.27E+08,   7.74E+11},
	{_T(" 2015/4/29"),   4446.119,    4476.62,   4499.945,  4398.639,     5.2E+08,   7.52E+11},
	{_T(" 2015/4/28"),   4527.635,   4476.215,   4572.391,  4432.904,    7.68E+08,   1.06E+12},
	{_T(" 2015/4/27"),   4441.929,   4527.396,   4529.735,  4441.929,    6.71E+08,   9.75E+11},
	{_T(" 2015/4/24"),   4355.951,   4393.686,   4416.376,  4318.119,    6.29E+08,   9.17E+11},
	{_T(" 2015/4/23"),   4414.485,   4414.508,    4444.41,  4358.844,    6.67E+08,   9.63E+11},
	{_T(" 2015/4/22"),   4304.597,   4398.494,   4400.193,  4297.951,     6.8E+08,   9.77E+11},
	{_T(" 2015/4/21"),   4212.185,   4293.623,   4294.375,  4188.569,    6.34E+08,   8.62E+11},
	{_T(" 2015/4/20"),   4301.352,   4217.077,   4356.001,  4190.681,    8.57E+08,   1.15E+12},
	{_T(" 2015/4/17"),   4254.723,   4287.296,   4317.223,   4238.91,    7.02E+08,   9.16E+11},
	{_T(" 2015/4/16"),   4055.916,   4194.823,   4195.305,  4031.244,    5.51E+08,   7.12E+11},
	{_T(" 2015/4/15"),   4135.648,   4084.163,   4175.494,  4069.007,    6.13E+08,   7.73E+11},
	{_T(" 2015/4/14"),   4125.782,   4135.565,   4168.346,  4091.257,    6.11E+08,   8.15E+11},
	{_T(" 2015/4/13"),   4072.723,   4121.715,   4128.072,  4057.293,     5.9E+08,   7.82E+11},
	{_T(" 2015/4/10"),   3947.492,    4034.31,   4040.348,  3929.319,    4.84E+08,   6.69E+11},
	{_T("  2015/4/9"),    4006.13,   3957.534,   4016.396,  3900.027,    5.85E+08,   8.17E+11},
	{_T("  2015/4/8"),   3976.532,   3994.811,    4000.22,  3903.648,    6.18E+08,   8.39E+11},
	{_T("  2015/4/7"),    3899.42,   3961.378,   3961.666,  3891.728,     5.7E+08,   7.46E+11},
	{_T("  2015/4/3"),   3803.383,   3863.929,   3864.405,  3792.211,    4.73E+08,   6.36E+11},
	{_T("  2015/4/2"),   3827.689,   3825.784,   3835.451,  3775.894,    4.79E+08,   6.32E+11},
	{_T("  2015/4/1"),    3748.34,   3810.294,   3817.082,  3742.213,    4.47E+08,   5.92E+11},
	{_T(" 2015/3/31"),   3822.987,   3747.899,   3835.567,  3737.043,    5.62E+08,   7.21E+11},
	{_T(" 2015/3/30"),   3710.612,   3786.568,   3795.935,  3710.612,    5.65E+08,   6.92E+11},
	{_T(" 2015/3/27"),   3686.134,   3691.096,   3710.477,  3656.831,    4.09E+08,   5.09E+11},
	{_T(" 2015/3/26"),   3641.942,   3682.095,   3707.318,  3615.011,    4.89E+08,   6.20E+11},
	{_T(" 2015/3/25"),   3680.953,   3660.727,   3693.151,  3634.559,    5.22E+08,   6.45E+11},
	{_T(" 2015/3/24"),   3692.569,    3691.41,   3715.873,  3600.698,     6.4E+08,   7.55E+11},
	{_T(" 2015/3/23"),   3640.104,   3687.728,   3688.249,  3635.485,    5.36E+08,   6.62E+11},
	{_T(" 2015/3/20"),   3587.084,   3617.318,   3632.338,   3569.38,    5.17E+08,   6.52E+11},
	{_T(" 2015/3/19"),   3576.019,   3582.271,   3600.684,  3546.844,    5.37E+08,   6.12E+11},
	{_T(" 2015/3/18"),   3510.501,   3577.301,   3577.662,  3503.853,    5.45E+08,   6.17E+11},
	{_T(" 2015/3/17"),   3469.603,   3502.847,   3504.123,  3459.694,    5.21E+08,   6.02E+11},
	{_T(" 2015/3/16"),   3391.158,   3449.305,   3449.305,  3377.087,    3.99E+08,   4.79E+11},
	{_T(" 2015/3/13"),   3359.488,   3372.911,   3391.255,   3352.15,    3.28E+08,   3.74E+11},
	{_T(" 2015/3/12"),   3314.813,   3349.323,   3360.054,  3300.488,    3.57E+08,   4.07E+11},
	{_T(" 2015/3/11"),   3289.594,     3290.9,   3325.054,  3278.471,    2.83E+08,   3.28E+11},
	{_T(" 2015/3/10"),   3289.085,   3286.068,   3309.915,  3277.095,    2.86E+08,   3.30E+11},
	{_T("  2015/3/9"),   3224.314,   3302.408,   3307.702,   3198.37,    3.21E+08,   3.60E+11},
	{_T("  2015/3/6"),   3248.036,   3241.187,   3266.933,  3234.533,    2.83E+08,   3.28E+11},
	{_T("  2015/3/5"),   3264.085,   3248.476,   3266.638,  3221.666,    3.21E+08,   3.74E+11},
	{_T("  2015/3/4"),   3264.182,   3279.533,   3286.588,  3250.484,    2.94E+08,   3.47E+11},
	{_T("  2015/3/3"),   3317.695,   3263.052,   3317.695,  3260.429,    3.82E+08,   4.42E+11},
	{_T("  2015/3/2"),   3332.721,   3336.285,    3336.76,  3298.669,    3.46E+08,   4.10E+11},
	{_T(" 2015/2/27"),   3296.831,   3310.303,   3324.546,  3291.007,    2.99E+08,   3.35E+11},
	{_T(" 2015/2/26"),   3222.151,   3298.359,   3300.616,  3202.188,    3.01E+08,   3.34E+11},
	{_T(" 2015/2/25"),   3256.479,   3228.843,   3257.223,  3215.552,    2.33E+08,   2.65E+11},
	{_T(" 2015/2/17"),   3230.884,   3246.906,   3255.725,  3230.772,    2.28E+08,   2.63E+11},
	{_T(" 2015/2/16"),   3206.137,   3222.363,   3228.846,  3195.884,    2.24E+08,   2.66E+11},
	{_T(" 2015/2/13"),   3186.808,   3203.827,   3237.159,  3182.794,    2.61E+08,   2.93E+11},
	{_T(" 2015/2/12"),   3157.959,   3173.416,   3181.766,  3134.244,    1.95E+08,   2.30E+11},
	{_T(" 2015/2/11"),   3145.765,   3157.704,   3166.421,  3139.052,    1.73E+08,   2.11E+11},
	{_T(" 2015/2/10"),    3090.49,   3141.593,   3142.099,  3084.253,    1.94E+08,   2.25E+11},
	{_T("  2015/2/9"),    3063.51,   3095.124,   3119.034,  3049.111,    2.06E+08,   2.41E+11},
	{_T("  2015/2/6"),    3120.09,   3075.907,   3129.539,  3052.939,    2.47E+08,   2.67E+11},
	{_T("  2015/2/5"),   3251.212,   3136.531,   3251.212,  3135.819,    3.06E+08,   3.48E+11},
	{_T("  2015/2/4"),   3212.822,   3174.126,   3238.982,  3171.144,    2.49E+08,   2.90E+11},
	{_T("  2015/2/3"),   3156.086,   3204.907,   3207.935,  3129.732,    2.48E+08,   2.83E+11},
	{_T("  2015/2/2"),   3148.136,     3128.3,   3175.134,  3122.572,    2.51E+08,   2.67E+11},
	{_T(" 2015/1/30"),   3273.747,   3210.363,   3288.503,  3210.308,    2.58E+08,   2.84E+11},
	{_T(" 2015/1/29"),   3258.997,   3262.305,   3286.786,  3234.241,    2.75E+08,   2.96E+11},
	{_T(" 2015/1/28"),   3325.722,   3305.738,   3354.802,  3294.655,    3.02E+08,   3.42E+11},
	{_T(" 2015/1/27"),   3389.853,    3352.96,   3390.216,  3290.219,    3.75E+08,   4.18E+11},
	{_T(" 2015/1/26"),   3347.257,   3383.182,   3384.798,  3321.315,    3.18E+08,   3.58E+11},
	{_T(" 2015/1/23"),   3357.096,   3351.764,   3406.786,  3328.293,    3.66E+08,   4.21E+11},
	{_T(" 2015/1/22"),   3327.319,   3343.344,   3352.384,  3293.978,    3.53E+08,   4.08E+11},
	{_T(" 2015/1/21"),   3189.085,   3323.611,   3337.004,  3178.343,    4.11E+08,   4.74E+11},
	{_T(" 2015/1/20"),    3114.56,   3173.052,   3190.245,  3100.477,    3.57E+08,   4.16E+11},
	{_T(" 2015/1/19"),   3189.727,   3116.351,   3262.207,  3095.066,    4.01E+08,   4.10E+11},
	{_T(" 2015/1/16"),   3343.603,   3376.495,   3400.318,   3340.49,     3.4E+08,   3.92E+11},
	{_T(" 2015/1/15"),    3224.07,   3336.455,   3337.084,  3207.545,    2.83E+08,   3.31E+11},
	{_T(" 2015/1/14"),   3242.337,   3222.437,   3268.483,  3193.978,     2.4E+08,   2.67E+11},
	{_T(" 2015/1/13"),   3223.542,   3235.301,   3259.386,  3214.412,    2.31E+08,   2.74E+11},
	{_T(" 2015/1/12"),   3258.213,   3229.316,   3275.185,  3191.582,    3.22E+08,   3.66E+11},
	{_T("  2015/1/9"),   3276.965,   3285.412,   3404.834,  3267.509,     4.1E+08,   4.59E+11},
	{_T("  2015/1/8"),   3371.957,   3293.456,   3381.566,  3285.095,    3.71E+08,   3.99E+11},
	{_T("  2015/1/7"),   3326.649,   3373.954,   3374.896,  3312.211,    3.92E+08,   4.36E+11},
	{_T("  2015/1/6"),   3330.799,   3351.446,   3394.224,  3303.184,    5.02E+08,   5.32E+11},
	{_T("  2015/1/5"),   3258.627,   3350.519,   3369.281,  3253.883,    5.31E+08,   5.50E+11}
};

这里定义了一个结构体,用于放置K线数据。并初始化了一个结构体数组。

第六步,绘制K线。

在MainDlg.cpp的OnInitDialog函数中添加如下代码。

	GetChart(m_hWndChart)->AddKLine(_T("日¨?K"));
	GetChart(m_hWndChart)->AddKLine(_T("周¨¹K"));
	GetChart(m_hWndChart)->AddKLine(_T("月?K"));
			
	int i;
	for(i=sizeof(HistoryData)/sizeof(MyData)-1; i>=0; --i)
	{
		GetChart(m_hWndChart)->AddKNode( 0, HistoryData[i].strTime, _T("%Y/%m/%d"), HistoryData[i].fOpen, HistoryData[i].fClose, HistoryData[i].fLowest, HistoryData[i].fHighest, HistoryData[i].fVolume, HistoryData[i].fAmount);
	}
	GetChart(m_hWndChart)->AddMALine(0, 5);
	GetChart(m_hWndChart)->AddMALine(0, 10);
	GetChart(m_hWndChart)->AddMALine(0, 20);
	GetChart(m_hWndChart)->AddMALine(0, 30);
	GetChart(m_hWndChart)->SetTitle(_T("沪市历史日K图"));
	GetChart(m_hWndChart)->SetMALineSize(0, 2);

	GetChart(m_hWndChart)->AddIndicator(_T("MACD"));
	GetChart(m_hWndChart)->AddIndicator(_T("KDJ"));
	GetChart(m_hWndChart)->AddIndicator(_T("VOL"));

这里利用AddKLine函数添加了三个K线标签,可以显示三条K线。后面只对第一条K线进行了处理。

根据前面预置的数据,利用AddKNode函数添加K线数据。注意上面的循环,由于K线预置数据是最新数据放在最上面的,而K线图上需要按时间顺序排列,因此循环是倒序的。

利用AddMALine函数增加四条移动平均线,平均天数分别是5、10、20、30。

利用AddIndicator增加了三个指标图,分别是MACD、KDJ、VOL。

程序编制结束,效果如图。

当鼠标位于蜡烛图区K线框中时,信息窗口将显示当日K线信息,当鼠标位于指标图区中时,信息窗口将显示当日的指标信息。

KChart的调用接口相当简单。本节课的内容不仅适合SoUI环境使用,在其它编程环境,也完全适用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值