效果圖
前段時間,因業務需要,寫了這樣一個軟體,同樣的頁面已經是第2次寫了,第1次大約5年前的事情了,因為代碼遺失,于是重新寫。頁面看似複雜,實作起來非常簡單。
第一步:參照通達信的公式管理器核心檔案TCalc.dll,導出資源檔案(TCalc.rc),這樣界面基本上顯現出來了,接下來就是把這些頁面進行整合(頁面調用)。
第二步:提取公式清單資訊
enum formula_type : unsigned char {
ftFrom,
ftTechnical_Indicator_Formula,// 技術名額公式
ftConditional_Sel_Stock_Formula, // 自選股名額公式
ftExpert_System_Formula, // 系統專家公式
ftColorful_Kline_Formula, // 五彩K線公式
ftTo,
};
typedef struct _Formula_Parameter
{
char _name[16];//參數
union
{
char _value[4][16];
struct
{
char _min[16];//最小
char _max[16];//最大
char _default[16];//預設
char _step[16];//步長
};
};
}Formula_Parameter;
// 技術名額公式
typedef struct _Technical_Indicator_Formula
{
bool is_system;//是否系統公式 1-是 0-否
bool is_common;//是否系統公式 1-是 0-否
char name[32];// 公式名稱
bool is_protected;//密碼保護
char password[16];//密碼
bool type_disable;
char _type;//公式類型
/*
技術名額公式
0 - 大勢型
1 - 超買超賣型
2 - 趨勢性
3 - 能量型
4 - 成交量型
5 - 均線型
6 - 圖表型
7 - 路徑型
8 - 停損型
9 - 交易型
10 - 神系
11 - 龍系
12 - 鬼系
13 - 其他系
14 - 特色型
15 - 其他類型
條件選股公式
0 - 名額條件
1 - 基本面
2 - 即時盤中
3 - 走勢特征
4 - 形态特征
5 - 其他類型
專家系統公式
0 -
五彩K線公式
*/
bool draw_disable;
char draw_line_method;//畫線方法
/*
0 - 副圖
1 - 主圖疊加
2 - 副圖(疊加K線)
3 - 副圖(疊加美國線)
4 - 副圖(疊加收盤站線)
5 - 主圖替換
*/
char desp[64];//公式描述
char version[16];//公式版本
char show_decimal;//顯示小數
/*
0 - 預設位數
1 - 品種小數位數
2 - 品種小數位數 + 1
3 - 固定0位
4 - 固定1位
5 - 固定2位
6 - 固定3位
7 - 固定4位
*/
Formula_Parameter parameters[16];//參數
char formula_text[4096];//公式文本内容
char trade_rules;//交易法則
/*
0 - 無
1 - 左手
2 - 右手
*/
bool coordinate_disable;
char coordinate_position[64];//坐标線位置,最多6個,用分号分隔
bool extract_disable;
char extract_y_axis[4][16];//額外Y軸分界
}Technical_Indicator_Formula;
//條件選股公式
typedef struct _Conditional_Sel_Stock_Formula
{
bool is_system;//是否系統公式 1-是 0-否
bool is_common;//是否系統公式 1-是 0-否
char name[32];// 公式名稱
bool is_protected;//密碼保護
char password[16];//密碼
char _type;//公式類型
/*
條件選股公式
0 - 名額條件
1 - 基本面
2 - 即時盤中
3 - 走勢特征
4 - 形态特征
5 - 其他類型
*/
char right_to_use;//使用複權
/*
0 - 預設設定
1 - 恒不複權
*/
char desp[64];//公式描述
char version[16];//公式版本
Formula_Parameter parameters[16];//參數
char formula_text[4096];//公式文本内容
}Conditional_Sel_Stock_Formula;
//專家系統公式
typedef struct _Expert_System_Formula
{
bool is_system;//是否系統公式 1-是 0-否
bool is_common;//是否系統公式 1-是 0-否
char name[32];// 公式名稱
bool is_protected;//密碼保護
char password[16];//密碼
char desp[64];//公式描述
char version[16];//公式版本
Formula_Parameter parameters[16];//參數
char formula_text[4096];//公式文本内容
}Expert_System_Formula;
//五彩K線公式
typedef struct _Colorful_Kline_Formula
{
bool is_system;//是否系統公式 1-是 0-否
bool is_common;//是否系統公式 1-是 0-否
char name[32];// 公式名稱
bool is_protected;//密碼保護
char password[16];//密碼
char desp[64];//公式描述
char version[16];//公式版本
Formula_Parameter parameters[16];//參數
char formula_text[4096];//公式文本内容
}Colorful_Kline_Formula;
class formula
{
public:
formula();
~formula();
std::vector<Formula_Struct*> m_queFormulas;
private:
void init();
};
void formula::init()
{
// 技術名額公式
Formula_Struct formula_Struct;
//0 - 大勢型
memset(&formula_Struct, 0, sizeof(formula_Struct));
formula_Struct.is_root = true;
strcpy_s(formula_Struct.name, "大勢型");// 公式名稱
formula_Struct.subtype = 1;
formula_Struct.formulatype = formula_type::ftTechnical_Indicator_Formula;
m_queFormulas.push_back(formula_Struct.clone());
memset(&formula_Struct, 0, sizeof(formula_Struct));
formula_Struct.subtype = 0;
formula_Struct.is_system = true;
strcpy_s(formula_Struct.name, "ABI");// 公式名稱
formula_Struct.is_protected = false;//密碼保護
formula_Struct.draw_line_method = 0;//畫線方法
strcpy_s(formula_Struct.desp, "絕對廣量名額");//公式描述
strcpy_s(formula_Struct.version, "0");//公式版本
formula_Struct.show_decimal = 0;//顯示小數
strcpy_s(formula_Struct.formula_text, "ABI:100*ABS(ADVANCE-DECLINE)/(ADVANCE+DECLINE);\n");//公式文本内容
strcat_s(formula_Struct.formula_text, "MAABI:EMA(ABI,M);");
strcpy_s(formula_Struct.parameters[0]._name, "M");//參數
strcpy_s(formula_Struct.parameters[0]._min, _T("2.00"));
strcpy_s(formula_Struct.parameters[0]._max, _T("100.00"));
strcpy_s(formula_Struct.parameters[0]._default, _T("10.00"));
formula_Struct.trade_rules = 1;//交易法則
strcpy_s(formula_Struct.coordinate_position, "自動");//坐标線位置,最多6個,用分号分隔
formula_Struct.formulatype = formula_type::ftTechnical_Indicator_Formula;
m_queFormulas.push_back(formula_Struct.clone());
memset(&formula_Struct, 0, sizeof(formula_Struct));
formula_Struct.subtype = 0;
formula_Struct.is_system = true;
strcpy_s(formula_Struct.name, "ADL");// 公式名稱
formula_Struct.is_protected = false;//密碼保護
formula_Struct.draw_line_method = 0;//畫線方法
strcpy_s(formula_Struct.desp, "騰落名額");//公式描述
strcpy_s(formula_Struct.version, "0");//公式版本
formula_Struct.show_decimal = 0;//顯示小數
strcpy_s(formula_Struct.formula_text, "ADL:SUM(ADVANCE-DECLINE,0);\n");//公式文本内容
strcat_s(formula_Struct.formula_text, "MAADL:MA(ADL,M);");
strcpy_s(formula_Struct.parameters[0]._name, "M");//參數
strcpy_s(formula_Struct.parameters[0]._min, _T("2.00f"));
strcpy_s(formula_Struct.parameters[0]._max, _T("60.00f"));
strcpy_s(formula_Struct.parameters[0]._default, _T("7.00f"));
formula_Struct.trade_rules = 1;//交易法則
strcpy_s(formula_Struct.coordinate_position, "自動");//坐标線位置,最多6個,用分号分隔
formula_Struct.formulatype = formula_type::ftTechnical_Indicator_Formula;
m_queFormulas.push_back(formula_Struct.clone());
memset(&formula_Struct, 0, sizeof(formula_Struct));
formula_Struct.subtype = 0;
formula_Struct.is_system = true;
strcpy_s(formula_Struct.name, "ADR");// 公式名稱
formula_Struct.is_protected = false;//密碼保護
formula_Struct.draw_line_method = 0;//畫線方法
strcpy_s(formula_Struct.desp, "漲跌比率");//公式描述
strcpy_s(formula_Struct.version, "0");//公式版本
formula_Struct.show_decimal = 0;//顯示小數
strcpy_s(formula_Struct.formula_text, "ADR:SUM(ADVANCE,N)/SUM(DECLINE,N);\n");//公式文本内容
strcat_s(formula_Struct.formula_text, "MAADR:MA(ADR,M);");
strcpy_s(formula_Struct.parameters[0]._name, "N");//參數
strcpy_s(formula_Struct.parameters[0]._min, _T("2.00f"));
strcpy_s(formula_Struct.parameters[0]._max, _T("100.00f"));
strcpy_s(formula_Struct.parameters[0]._default, _T("10.00f"));
strcpy_s(formula_Struct.parameters[1]._name, "M");//參數
strcpy_s(formula_Struct.parameters[1]._min, _T("2.00f"));
strcpy_s(formula_Struct.parameters[1]._max, _T("60.00"));
strcpy_s(formula_Struct.parameters[1]._default, _T("6.00"));
formula_Struct.trade_rules = 1;//交易法則
strcpy_s(formula_Struct.coordinate_position, "自動");//坐标線位置,最多6個,用分号分隔
strcpy_s(formula_Struct.extract_y_axis[0], "0.50");
strcpy_s(formula_Struct.extract_y_axis[1], "1.00");
strcpy_s(formula_Struct.extract_y_axis[2], "1.50");
formula_Struct.formulatype = formula_type::ftTechnical_Indicator_Formula;
m_queFormulas.push_back(formula_Struct.clone());
......
}
第三步:将提取的公式結構填充顯示到清單樹
void CTCalcDlg::InitFormulaGroupTree()
{
CTreeCtrl* pTree = reinterpret_cast<CTreeCtrl*>(GetDlgItem(IDC_TREE_2001));
pTree->LockWindowUpdate();
pTree->DeleteAllItems();
HTREEITEM hRoot = pTree->InsertItem(_T("技術名額公式"), 32, 32);
pTree->SetItemData(hRoot, ftTechnical_Indicator_Formula * 1000);
std::vector<Formula_Struct*>::iterator iter = globalFormula.m_queFormulas.begin();
for (; iter != globalFormula.m_queFormulas.end(); iter++)
{
Formula_Struct* pFormula = *iter;
if (pFormula->is_root && pFormula->formulatype == ftTechnical_Indicator_Formula)
{
label_100:
HTREEITEM hChild = pTree->InsertItem(pFormula->name, 3, 3, hRoot);
pTree->SetItemData(hChild, (DWORD)pFormula);
for (++iter; iter != globalFormula.m_queFormulas.end(); iter++)
{
pFormula = *iter;
if (pFormula->formulatype != ftTechnical_Indicator_Formula)
break;
if (pFormula->is_root)
goto label_100;
CString sItemText;
if (pFormula->is_system)
sItemText.Format(_T("%s %s(系統)"), pFormula->name, pFormula->desp);
else
sItemText.Format(_T("%s %s(使用者)"), pFormula->name, pFormula->desp);
HTREEITEM hSubChild = NULL;
if (pFormula->is_common)
hSubChild = pTree->InsertItem(sItemText, 30, 30, hChild);
else if (pFormula->is_protected)
hSubChild = pTree->InsertItem(sItemText, 17, 17, hChild);
else
hSubChild = pTree->InsertItem(sItemText, 15, 15, hChild);
pTree->SetItemData(hSubChild, (DWORD)pFormula);
}
break;
}
}
pTree->Expand(hRoot, TVM_EXPAND);
hRoot = pTree->InsertItem(_T("條件選股公式"), 32, 32);
pTree->SetItemData(hRoot, ftConditional_Sel_Stock_Formula * 1000);
iter = globalFormula.m_queFormulas.begin();
for (; iter != globalFormula.m_queFormulas.end(); iter++)
{
Formula_Struct* pFormula = *iter;
if (pFormula->is_root && pFormula->formulatype == ftConditional_Sel_Stock_Formula)
{
label_101:
HTREEITEM hChild = pTree->InsertItem(pFormula->name, 3, 3, hRoot);
pTree->SetItemData(hChild, (DWORD)pFormula);
for (++iter; iter != globalFormula.m_queFormulas.end(); iter++)
{
pFormula = *iter;
if (pFormula->formulatype != ftConditional_Sel_Stock_Formula)
break;
if (pFormula->is_root)
goto label_101;
CString sItemText;
if (pFormula->is_system)
sItemText.Format(_T("%s %s(系統)"), pFormula->name, pFormula->desp);
else
sItemText.Format(_T("%s %s(使用者)"), pFormula->name, pFormula->desp);
HTREEITEM hSubChild = NULL;
if (pFormula->is_common)
hSubChild = pTree->InsertItem(sItemText, 30, 30, hChild);
else if (pFormula->is_protected)
hSubChild = pTree->InsertItem(sItemText, 17, 17, hChild);
else
hSubChild = pTree->InsertItem(sItemText, 15, 15, hChild);
pTree->SetItemData(hSubChild, (DWORD)pFormula);
}
break;
}
}
hRoot = pTree->InsertItem(_T("專家系統公式"), 32, 32);
pTree->SetItemData(hRoot, ftExpert_System_Formula * 1000);
iter = globalFormula.m_queFormulas.begin();
for (; iter != globalFormula.m_queFormulas.end(); iter++)
{
Formula_Struct* pFormula = *iter;
if (pFormula->formulatype == ftExpert_System_Formula)
{
for (; iter != globalFormula.m_queFormulas.end(); iter++)
{
Formula_Struct* pFormula = *iter;
if (pFormula->formulatype != ftExpert_System_Formula)
break;
CString sItemText;
if (pFormula->is_system)
sItemText.Format(_T("%s %s(系統)"), pFormula->name, pFormula->desp);
else
sItemText.Format(_T("%s %s(使用者)"), pFormula->name, pFormula->desp);
HTREEITEM hChild = NULL;
if (pFormula->is_common)
hChild = pTree->InsertItem(sItemText, 30, 30, hRoot);
else if (pFormula->is_protected)
hChild = pTree->InsertItem(sItemText, 17, 17, hRoot);
else
hChild = pTree->InsertItem(sItemText, 15, 15, hRoot);
pTree->SetItemData(hChild, (DWORD)pFormula);
}
break;
}
}
hRoot = pTree->InsertItem(_T("五彩K線公式"), 32, 32);
pTree->SetItemData(hRoot, ftColorful_Kline_Formula * 1000);
iter = globalFormula.m_queFormulas.begin();
for (; iter != globalFormula.m_queFormulas.end(); iter++)
{
Formula_Struct* pFormula = *iter;
if (pFormula->formulatype == ftColorful_Kline_Formula)
{
for (; iter != globalFormula.m_queFormulas.end(); iter++)
{
Formula_Struct* pFormula = *iter;
if (pFormula->formulatype != ftColorful_Kline_Formula)
break;
CString sItemText;
if (pFormula->is_system)
sItemText.Format(_T("%s %s(系統)"), pFormula->name, pFormula->desp);
else
sItemText.Format(_T("%s %s(使用者)"), pFormula->name, pFormula->desp);
HTREEITEM hChild = NULL;
if (pFormula->is_common)
hChild = pTree->InsertItem(sItemText, 30, 30, hRoot);
else if (pFormula->is_protected)
hChild = pTree->InsertItem(sItemText, 17, 17, hRoot);
else
hChild = pTree->InsertItem(sItemText, 15, 15, hRoot);
pTree->SetItemData(hChild, (DWORD)pFormula);
}
break;
}
}
pTree->UnlockWindowUpdate();
}
至此,清單數結構就顯示出來了。