期货量化软件:从头开始开发智能交易系统新订单系统 (VI)

期货量化软件:从头开始开发智能交易系统新订单系统 (VI)

为了实现修改,赫兹期货量化需要做一件非常简单的事情:不要通知服务器所有更改,只通知所需的变更。 即便只是这样做,业已令一切操作正常,尽管我们不能绝对确保一切都恰如我们正在做的一样。

现在我们来看看赫兹期货量化需要在哪里修改代码。 我们所用的单独函数如下所示:

 
 

#define macroGetPrice(A) StringToDouble(ObjectGetString(Terminal.Get_ID(), MountName(ticket, A, EV_LINE), OBJPROP_TOOLTIP)) void MoveSelection(double price, uint keys) { static string memStr = NULL; static ulong ticket = 0; static eIndicatorTrade it; eEventType ev; double tp, sl, pr; bool isPending; string sz0 = m_TradeLine.GetObjectSelected(); if (sz0 != NULL) { if (memStr != sz0) GetIndicatorInfos(memStr = sz0, ticket, pr, it, ev); isPending = OrderSelect(ticket); switch (it) { case IT_TAKE: if (isPending) ModifyOrderPendent(ticket, macroGetPrice(IT_PENDING), price, macroGetPrice(IT_STOP)); else ModifyPosition(ticket, price, macroGetPrice(IT_STOP)); break; case IT_STOP: if (isPending) ModifyOrderPendent(ticket, macroGetPrice(IT_PENDING), macroGetPrice(IT_TAKE), price); else ModifyPosition(ticket, macroGetPrice(IT_TAKE), price); break; case IT_PENDING: pr = macroGetPrice(IT_PENDING); tp = macroGetPrice(IT_TAKE); sl = macroGetPrice(IT_STOP); ModifyOrderPendent(ticket, price, (tp == 0 ? 0 : price + tp - pr), (sl == 0 ? 0 : price + sl - pr)); break; } }; } #undef macroGetPrice

但是,伴随函数内部的修改,赫兹期货量化还需要实现一些与鼠标事件相关的修改。 这就是我们首先要关注的。

高亮显示的片段需要替换为其它内容,从而表示将会用到新仓位。 但是,对于用户来说,所有修改都应该能够理解。

我已找到了一种有效的方式,可令所有内容易于理解,同时又可以运作,而且无需对整个代码结构进行重大更改。 这就是创建一个幻影指示标签,其在需要之前将不可见。 幸运的是,赫兹期货量化提供了一种非常简单的途径来做到这一点。 如此,对于那些已熟悉本系列早期文章中的素材的人来说,很容易就能理解本文内容。

2.0. 实现

为了实现一个幻影标签,赫兹期货量化简单地按照真实标签来创建它。 这它是真实标签的精确阴影,直到我们继续按照上一篇文章中展示的方式操控价格。 在此刻,幻影标签就会随着真实标签的移动而出现在图表上。 这将令您能够轻松比较正在发生的事情,并了解是否要进行更改。

2.0.1. 创建一个幻影指示标签

所有修改都在 C_IndicatorTradeView 类中实现。 我们从定义三条新指令开始:

 
 

#define def_IndicatorGhost "G" #define def_IndicatorReal "R" #define def_IndicatorGhostColor clrDimGray

这可令赫兹期货量化 为我们工作。 该规则是这样的:首先我们创建一个幻影标签,然后我们创建一个真实标签。 因此,赫兹期货量化会注意不显示幻影标签,直到我们真正需要看到它的那一刻。 由于这是由 赫兹期货量化自身完成的,我们在编程时就节省了大量精力。

一个重要的细节:如果您打算更改幻影的颜色,简单地更改在所选部件中指定的颜色即可。

因此,下一步是修改函数,只允许生成唯一的名称。

 
 

inline string MountName(ulong ticket, eIndicatorTrade it, eEventType ev, bool isGhost = false) { return StringFormat("%s%c%c%c%llu%c%c%c%s", def_NameObjectsTrade, def_SeparatorInfo, (char)it, def_SeparatorInfo, ticket, def_SeparatorInfo, (char)(isGhost ? ev + 32 : ev), def_SeparatorInfo, (isGhost ? def_IndicatorGhost : def_IndicatorReal)); }

来自先前版本的高亮显示部分已经过添加或修改。 我们让 赫兹期货量化生成唯一的名称。 如此,我们就不需要再担心这一点。 请注意,我已向事件中添加了一些数值。 我如此做是为了防止幻影接收事件,并试图控制。

下一步是显而易见的 — 我们必须创建标签本身:

 
 

inline void CreateIndicatorTrade(ulong ticket, eIndicatorTrade it) { color cor1, cor2, cor3; string sz0, sz1; switch (it) { case IT_TAKE : cor1 = clrForestGreen; cor2 = clrDarkGreen; cor3 = clrNONE; break; case IT_STOP : cor1 = clrFireBrick; cor2 = clrMaroon; cor3 = clrNONE; break; case IT_PENDING: cor1 = clrCornflowerBlue; cor2 = clrDarkGoldenrod; cor3 = def_ColorVolumeEdit; break; case IT_RESULT : default: cor1 = clrDarkBlue; cor2 = clrDarkBlue; cor3 = def_ColorVolumeResult; break; } m_TradeLine.Create(ticket, MountName(ticket, it, EV_LINE, true), def_IndicatorGhostColor); m_TradeLine.Create(ticket, MountName(ticket, it, EV_LINE), cor2); if (ticket == def_IndicatorTicket0) m_TradeLine.SpotLight(MountName(ticket, IT_PENDING, EV_LINE)); if (it != IT_RESULT) m_BackGround.Create(ticket, sz0 = MountName(ticket, it, EV_GROUND, true), def_IndicatorGhostColor); m_BackGround.Create(ticket, sz1 = MountName(ticket, it, EV_GROUND), cor1); switch (it) { case IT_TAKE: case IT_STOP: case IT_PENDING: m_BackGround.Size(sz0, 92, 22); m_BackGround.Size(sz1, 92, 22); break; case IT_RESULT: m_BackGround.Size(sz1, 84, 34); break; } m_BtnClose.Create(ticket, MountName(ticket, it, EV_CLOSE), def_BtnClose); m_EditInfo1.Create(ticket, sz0 = MountName(ticket, it, EV_EDIT, true), def_IndicatorGhostColor, 0.0); m_EditInfo1.Create(ticket, sz1 = MountName(ticket, it, EV_EDIT), cor3, 0.0); m_EditInfo1.Size(sz0, 60, 14); m_EditInfo1.Size(sz1, 60, 14); if (it != IT_RESULT) { m_BtnMove.Create(ticket, sz0 = MountName(ticket, it, EV_MOVE, true), "Wingdings", "u", 17, def_IndicatorGhostColor); m_BtnMove.Create(ticket, sz1 = MountName(ticket, it, EV_MOVE), "Wingdings", "u", 17, cor2); m_BtnMove.Size(sz1, 21, 21); }else { m_EditInfo2.Create(ticket, sz1 = MountName(ticket, it, EV_PROFIT), clrNONE, 0.0); m_EditInfo2.Size(sz1, 60, 14); } }

所有高亮显示的行都会产生幻影。 有一件事也许看起来很奇怪:为什么我们不重现所有的元素。 事实上,幻影并不是真实标签的精确复制品,而只是它的影子。 因此,我们不需要创建所有元素。 真实标签定义了应该发生的事情,而幻影只作为参考,即交易服务器将看到的内容。

现在进入需要更详细研究的部分,其中赫兹期货量化将真正努力工作。 您也许会认为在正确的位置排列对象需要做很多工作,但来看看源代码中实际更改的内容。

 
 

#define macroSetAxleY(A, B) { \ m_BackGround.PositionAxleY(MountName(ticket, A, EV_GROUND, B), y); \ m_TradeLine.PositionAxleY(MountName(ticket, A, EV_LINE, B), y); \ m_BtnClose.PositionAxleY(MountName(ticket, A, EV_CLOSE, B), y); \ m_EditInfo1.PositionAxleY(MountName(ticket, A, EV_EDIT, B), y, (A == IT_RESULT ? -1 : 0)); \ m_BtnMove.PositionAxleY(MountName(ticket, A, EV_MOVE, B), (A == IT_RESULT ? 9999 : y)); \ m_EditInfo2.PositionAxleY(MountName(ticket, A, EV_PROFIT, B), (A == IT_RESULT ? y : 9999), 1); \ } #define macroSetAxleX(A, B, C) { \ m_BackGround.PositionAxleX(MountName(ticket, A, EV_GROUND, C), B); \ m_TradeLine.PositionAxleX(MountName(ticket, A, EV_LINE, C), B); \ m_BtnClose.PositionAxleX(MountName(ticket, A, EV_CLOSE, C), B + 3); \ m_EditInfo1.PositionAxleX(MountName(ticket, A, EV_EDIT, C), B + 21); \ m_BtnMove.PositionAxleX(MountName(ticket, A, EV_MOVE, C), B + 80); \ m_EditInfo2.PositionAxleX(MountName(ticket, A, EV_PROFIT, C), B + 21); \ } //+------------------------------------------------------------------+ inline void ReDrawAllsIndicator(void) { int max = ObjectsTotal(Terminal.Get_ID(), -1, -1); ulong ticket; double price; eIndicatorTrade it; eEventType ev; for (int c0 = 0; c0 <= max; c0++) if (GetIndicatorInfos(ObjectName(Terminal.Get_ID(), c0, -1, -1), ticket, price, it, ev)) PositionAxlePrice(ticket, it, price); } //+------------------------------------------------------------------+ inline void PositionAxlePrice(ulong ticket, eIndicatorTrade it, double price) { int x, y, desl; ChartTimePriceToXY(Terminal.Get_ID(), 0, 0, price, x, y); ObjectSetString(Terminal.Get_ID(), MountName(ticket, it, EV_LINE), OBJPROP_TOOLTIP, DoubleToString(price)); macroSetAxleY(it, true); macroSetAxleY(it, false); switch (it) { case IT_TAKE: desl = 110; break; case IT_STOP: desl = 220; break; default: desl = 0; } macroSetAxleX(it, desl + (int)(ChartGetInteger(Terminal.Get_ID(), CHART_WIDTH_IN_PIXELS) * 0.2), true); macroSetAxleX(it, desl + (int)(ChartGetInteger(Terminal.Get_ID(), CHART_WIDTH_IN_PIXELS) * 0.2), false); } #undef macroSetAxleX #undef macroSetAxleY

全部就这些吗? 我们只需简单地更改宏? 是的,没有必要重新创建整个代码,我们只需调整它即可。 我们真正需要做的所有就是告诉 赫兹期货量化我们正在操作的对象名称,而 赫兹期货量化将为我们完成剩下的工作。 我们不需要为此创建一系列函数。 只需添加高亮显示的部分即可。

要更改的另一个函数在此如下所示:

 
 

void SetTextValue(ulong ticket, eIndicatorTrade it, double value0, double value1 = 0.0, double priceOpen = 0.0) { double finance; switch (it) { case IT_RESULT : PositionAxlePrice(ticket, it, priceOpen); PositionAxlePrice(ticket, IT_PENDING, 0); m_EditInfo2.SetTextValue(MountName(ticket, it, EV_PROFIT), value1); case IT_PENDING: value0 = value0 / Terminal.GetVolumeMinimal(); m_EditInfo1.SetTextValue(MountName(ticket, it, EV_EDIT), value0, def_ColorVolumeEdit); m_EditInfo1.SetTextValue(MountName(ticket, it, EV_EDIT, true), value0, def_IndicatorGhostColor); break; case IT_TAKE : case IT_STOP : finance = (value1 / Terminal.GetAdjustToTrade()) * value0; m_EditInfo1.SetTextValue(MountName(ticket, it, EV_EDIT), finance); m_EditInfo1.SetTextValue(MountName(ticket, it, EV_EDIT, true), finance, def_IndicatorGhostColor); break; } }

于此,我们已添加了选定的片段。 这就是我们的幻影如何被选择的。 它精准地反映了真实标签正在发生的事情。 事实上,它反映得太好了,以至于我们不得不再实现一些东西,才能让它正常工作。 代码没有错,但幻影与真实标签的关系太紧密,而这我们实际上应该避免。

此处最后一个要更改的函数如下所示:

 
 

inline void RemoveIndicator(ulong ticket, eIndicatorTrade it = IT_NULL) { #define macroDestroy(A, B) { \ ObjectDelete(Terminal.Get_ID(), MountName(ticket, A, EV_GROUND, B)); \ ObjectDelete(Terminal.Get_ID(), MountName(ticket, A, EV_LINE, B)); \ ObjectDelete(Terminal.Get_ID(), MountName(ticket, A, EV_CLOSE, B)); \ ObjectDelete(Terminal.Get_ID(), MountName(ticket, A, EV_EDIT, B)); \ if (A != IT_RESULT) ObjectDelete(Terminal.Get_ID(), MountName(ticket, A, EV_MOVE, B)); \ else ObjectDelete(Terminal.Get_ID(), MountName(ticket, A, EV_PROFIT, B)); \ } ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, false); if ((it == IT_NULL) || (it == IT_PENDING) || (it == IT_RESULT)) { macroDestroy(IT_RESULT, true); macroDestroy(IT_RESULT, false); macroDestroy(IT_PENDING, true); macroDestroy(IT_PENDING, false); macroDestroy(IT_TAKE, true); macroDestroy(IT_TAKE, false); macroDestroy(IT_STOP, true); macroDestroy(IT_STOP, false); } else { macroDestroy(it, true); macroDestroy(it, false); } ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, true); #undef macroDestroy }

高亮显示的片段已经过更改,这里没什么特别的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值