MT5CTP帮助手册-插件
在MT5CTP的介绍文章中,项目组列出了所有的EA函数和类库,源代码中也有详细的注释,没有更详细的介绍和结合功能的使用方法。在项目爱好者的督促之下,基于1.2版本的类库,项目组开始编写开发手册,项目组推荐爱好者基于类库做EA开发的使用、提高和扩展,因为这更加安全、可靠、高效和优雅。
MT5CTP类库在<include\mt5ctp\>目录下,列表如下:
类库文件名 | 类名 | 说明 | 备注 |
AccountInfo.mqh | CAccountInfo | 账户类:提取账户信息 | V1.20 |
DealInfo.mqh | CDealInfo | 成交类:提取成交信息 | V1.20 |
HistoryOrderInfo.mqh | CHistoryOrderInfo | 报单类:提取报单信息 | V1.20 |
OrderInfo.mqh | COrderInfo | 挂单类:未成交报单信息 | V1.20 |
mtctp.mqh | MT4CTP | MT4源码适配 | 本手册不涉及 |
mt5ctp.mqh | 无 | MT5CTP基础函数库 | 本手册不涉及 |
PositionInfo.mqh | CPositionInfo | 持仓类:提取持仓信息 | V1.20 |
SymbolInfo.mqh | CSymbolInfo | 合约类:提取合约信息 | V1.20 |
toolbox.mqh | 无 | 交易管理工具(界面) | 本手册不涉及 |
JAson.mqh | CJAVal | Json类:第三方库 | 本手册不涉及 |
Trade.mqh | CTrade | 交易类:交易驱动 | V1.20 |
开发手册主要介绍上述加粗的7个类库1.20版本的使用。按照EA设计、开发、测试、部署等流程和习惯,先从交易合约入手,然后是交易账户(资金和持仓),再然后是交易,最后是报单和成交统计分析。开发手册也按照这个顺序展开,首先列出类函数和功能简介,然后针对问题,提供解决方案的方式来展示其使用方法,务求清晰明了。
第一章 交易合约:CSymbolInfo类
为了便于记忆,我们库文件名和类名与mt5原生的类库保持一致,CSymbolInfo类也遵循这一原则,CSymbolInfo类用于EA中驱动交易是安全的,如果是用来做指标设计和开发,你可以直接使用mt5原生函数和类库就可以。也就是说,本项目由两套交易合约数据提取的方案:mt5原生函数和CSymbolInfo类和MT5CTP项目提供的CSymbolInfo类,都可用,特别声明:MT5CTP项目提供的CSymbolInfo类用于EA更安全可靠。
CSymbolInfo类功能函数表:
函数名 | 参数 | 返回值 | 功能说明 |
Symbol | void | string | 取得交易合约代码 |
Name | void | string | 取得交易合约名称 |
ExchangeID | void | string | 取得交易所代码 |
ExchangeInstID | void | string | 取得合约在交易所的代码 |
ProductID | void | string | 取得合约的产品代码 |
ProductName | void | string | 取得合约的产品名称 |
ExchangeProductID | void | string | 取得产品在交易所的代码 |
UnderlyingInstrID | void | string | 取得合约的基础商品代码 |
Currency | void | string | 取得合约的交易币种 |
CreateDate | void | string | 取得合约的创建日 |
OpenDate | void | string | 取得合约的上市日 |
ExpireDate | void | string | 取得合约的到期日 |
StartDelivDate | void | string | 取得合约的开始交割日 |
EndDelivDate | void | string | 取得合约的结束交割日 |
EnterTime | void | string | 取得合约的【状态】变化的时间 |
TradingDay | void | string | 取得合约行情的当前交易日 |
ActionDay | void | string | 取得合约行情的当前业务日期 |
UpdateTime | void | string | 取得合约行情的更新时间 |
SessionStart | int | string | 取得合约交易时段的开始时间 |
SessionEnd | int | string | 取得合约交易时段的结束时间 |
PriceTick | void | double | 取得合约的最小变动价位 |
UnderlyingMultiple | void | double | 取得合约的合约基础商品乘数 |
StrikePrice | void | double | 取得合约的执行价(期权) |
LastPrice | void | double | 取得合约的最新价 |
PreSettlement | void | double | 取得合约的昨结算价 |
PreClose | void | double | 取得合约的昨收盘价 |
Open | void | double | 取得合约的今开盘价 |
High | void | double | 取得合约的最高价 |
Low | void | double | 取得合约的最低价 |
Close | void | double | 取得合约的收盘价 |
Settlement | void | double | 取得合约的结算价 |
UpperLimit | void | double | 取得合约的涨停板价 |
LowerLimit | void | double | 取得合约的跌停板价 |
Bid | void | double | 取得合约的申买价 |
Ask | void | double | 取得合约的申卖价 |
Bid2 | void | double | 取得合约的申买价2 |
Ask2 | void | double | 取得合约的申卖价2 |
Bid3 | void | double | 取得合约的申买价3 |
Ask3 | void | double | 取得合约的申卖价3 |
Bid4 | void | double | 取得合约的申买价4 |
Ask4 | void | double | 取得合约的申卖价4 |
Bid5 | void | double | 取得合约的申买价5 |
Ask5 | void | double | 取得合约的申卖价5 |
AvgPrice | void | double | 取得合约的日均价 |
Turnover | void | double | 取得合约的成交金额 |
PreOpenInterest | void | double | 取得合约的昨持仓量 |
OpenInterest | void | double | 取得合约的持仓量 |
PreDelta | void | double | 取得合约的昨虚实度(期权) |
Delta | void | double | 取得合约的虚实度(期权) |
LongMarginRatioByMoney | void | double | 取得合约的多头保证金率 |
LongMarginRatioByVolume | void | double | 取得合约的多头保证金费 |
ShortMarginRatioByMoney | void | double | 取得合约的空头保证金率 |
ShortMarginRatioByVolume | void | double | 取得合约的空头保证金费 |
ExchangeLongMarginRatioByMoney | void | double | 取得合约的交易所多头保证金率 |
ExchangeLongMarginRatioByVolume | void | double | 取得合约的交易所多头保证金费 |
ExchangeShortMarginRatioByMoney | void | double | 取得合约的交易所空头保证金率 |
ExchangeShortMarginRatioByVolume | void | double | 取得合约的交易所空头保证金费 |
OpenRatioByMoney | void | double | 取得合约的开仓手续费率 |
OpenRatioByVolume | void | double | 取得合约的开仓手续费 |
CloseRatioByMoney | void | double | 取得合约的平仓手续费率 |
CloseRatioByVolume | void | double | 取得合约的平仓手续费 |
CloseTodayRatioByMoney | void | double | 取得合约的平今仓手续费率 |
CloseTodayRatioByVolume | void | double | 取得合约的平今仓手续费 |
OrderCommByVolume | void | double | 取得合约的报单手续费 |
OrderActionCommByVolume | void | double | 取得合约的撤单手续费 |
ProductClass | void | char | 取得合约的产品类型 |
ProductClassDescription | void | string | 合约产品类型说明 |
DeliveryYear | void | long | 取得合约的交割年份 |
DeliveryMonth | void | long | 取得合约的交割月份 |
MaxMarketOrderVolume | void | long | 取得合约的市价最大下单量 |
MinMarketOrderVolume | void | long | 取得合约的市价最小下单量 |
MaxLimitOrderVolume | void | long | 取得合约的限价最大下单量 |
MinLimitOrderVolume | void | long | 取得合约的限价最小下单量 |
ContractSize | void | long | 取得合约的数量/乘数 |
Digits | void | long | 取得合约的小数点位数 |
InstLifePhase | void | char | 取得合约的生命周期状态 |
InstLifePhaseDescription | void | string | 合约生命周期状态说明 |
IsTrading | void | bool | 取得合约当前是否交易 |
PositionType | void | char | 取得合约的持仓类型 |
PositionTypeDescription | void | string | 合约持仓类型说明 |
PositionDateType | void | char | 取得合约的持仓日期类型 |
PositionDateTypeDescription | void | string | 合约持仓日期类型说明 |
CloseDealType | void | char | 取得合约的平仓处理类型 |
CloseDealTypeDescription | void | string | 合约平仓处理类型说明 |
MortgageFundUseRange | void | char | 取得合约的质押资金可用范围 |
MortgageFundUseRangeDescription | void | string | 合约质押资金可用范围说明 |
MaxMarginSideAlgorithm | void | char | 取得合约的大额单边保证金算法 |
MaxMarginSideAlgorithmDescription | void | string | 合约大额单边保证金算法说明 |
OptionsType | void | char | 取得合约的期权类型 |
OptionsTypeDescription | void | string | 合约期权类型说明 |
CombinationType | void | char | 取得组合类型 |
CombinationTypeDescription | void | string | 组合类型说明 |
IsIndex | void | bool | 是否指数合约 |
IsMain | void | bool | 是否主力合约 |
IsSubMarket | void | bool | 是否已订阅行情 |
SymbolExists | void | bool | 是否交易时间 |
Status | void | char | 取得合约的交易状态 |
StatusDescription | void | string | 合约交易状态说明 |
EnterReason | void | char | 取得合约进入交易本状态原因 |
EnterReasonDescription | void | string | 合约进入交易本状态原因说明 |
Volume | void | long | 取得合约的日成交数量 |
UpdateMillisec | void | long | 取得合约最新行情的毫秒数 |
BidVolume | void | long | 取得合约行情的申买量 |
AskVolume | void | long | 取得合约行情的申卖量 |
Bid2Volume | void | long | 取得合约行情的申买量2 |
Ask2Volume | void | long | 取得合约行情的申卖量2 |
Bid3Volume | void | long | 取得合约行情的申买量3 |
Ask3Volume | void | long | 取得合约行情的申卖量3 |
Bid4Volume | void | long | 取得合约行情的申买量4 |
Ask4Volume | void | long | 取得合约行情的申卖量4 |
Bid5Volume | void | long | 取得合约行情的申买量5 |
Ask5Volume | void | long | 取得合约行情的申卖量5 |
SessionsTotal | void | int | 取得合约的交易时段数 |
SessionStartTime | int | datetime | 合约交易时段开始时间/本地 |
SessionEndTime | int | datetime | 合约交易时段结束时间/本地 |
NormalizePrice | double | double | 按合约tick格式化合约价格 |
Select | string | bool | 是否选中/可选参数:合约代码 |
第二章 交易账户:CAccountInfo类
CAccountInfo类用来操作和提取账户属性和资金数据。功能函数表:
函数名 | 参数 | 返回值 | 功能说明 |
Login | void | string | 取得登陆账户ID |
BrokerID | void | string | 取得经纪商ID |
TradingDay | void | string | 取得交易日 |
LoginTime | void | string | 取得登陆时间 |
CurrencyID | void | string | 取得币种代码 |
SystemName | void | string | 取得交易系统名称 |
FrontID | void | long | 取得用户前置 |
SessionID | void | long | 取得用户会话 |
MaxOrderRef | void | long | 取得最大报单引用 |
AccountType | void | char | 取得账户类型 |
AccountTypeDescription | void | string | 账户类型注释 |
PreBalance | void | double | 取得昨结算权益 |
PreMargin | void | double | 取得昨保证金占用 |
Balance | void | double | 取得动态权益 |
Available | void | double | 取得可用资金 |
Margin | void | double | 取得保证金占用 |
Commission | void | double | 取得手续费 |
DeliveryMargin | void | double | 取得交割保证金 |
Deposit | void | double | 取得入金 |
Withdraw | void | double | 取得出金 |
FrozenMargin | void | double | 取得保证金冻结 |
FrozenCommission | void | double | 取得手续费冻结 |
CloseProfit | void | double | 取得平仓盈亏 |
PositionProfit | void | double | 取得持仓盈亏 |
AccountExists | void | bool | 账户是否登陆 |
第三章 账户持仓:CPositionInfo类
CPositionInfo类是【MT5CTP】项目比较核心的一个类,EA中使用非常频繁,开发手册尽量详尽的介绍,先把类函数列表出来。
函数名 | 参数 | 返回值 | 功能说明 |
Ticket | void | string | 取得持仓编码(mt5ctp系统) |
Symbol | void | string | 取得持仓的合约代码 |
BrokerID | void | string | 取得持仓的经纪公司代码 |
InvestorID | void | string | 取得持仓的投资者代码 |
TradingDay | void | string | 取得交易日 |
ExchangeID | void | string | 取得持仓的交易所代码 |
InvestUnitID | void | string | 取得持仓的投资单元代码 |
LongFrozenAmount | void | double | 取得持仓的开仓冻结金额/多 |
ShortFrozenAmount | void | double | 取得持仓的开仓冻结金额/空 |
OpenAmount | void | double | 取得持仓的开仓金额 |
CloseAmount | void | double | 取得持仓的平仓金额 |
Price | void | double | 取得持仓的持仓均价 |
PositionCost | void | double | 取得持仓的持仓成本 |
PreMargin | void | double | 取得持仓的昨结算保证金 |
Margin | void | double | 取得持仓的保证金 |
FrozenMargin | void | double | 取得持仓的冻结的保证金 |
FrozenCash | void | double | 取得持仓的冻结的资金 |
FrozenCommission | void | double | 取得持仓的冻结的手续费 |
CashIn | void | double | 取得持仓的资金差额 |
Commission | void | double | 取得持仓的手续费 |
CloseProfit | void | double | 取得持仓的平仓盈亏 |
PositionProfit | void | double | 取得持仓的持仓盈亏 |
PreSettlementPrice | void | double | 取得持仓的昨结算价 |
SettlementPrice | void | double | 取得持仓的结算价 |
OpenCost | void | double | 取得持仓的开仓成本 |
OpenProfit | void | double | 取得持仓的开仓盈亏 |
CloseProfitByDate | void | double | 取得持仓的逐日盯市平仓盈亏 |
CloseProfitByTrade | void | double | 取得持仓的逐笔对冲平仓盈亏 |
MarginRateByMoney | void | double | 取得持仓的保证金率 |
MarginRateByVolume | void | double | 取得持仓的保证金率(按手数) |
StrikeFrozenAmount | void | double | 取得持仓的执行冻结金额 |
PositionCostOffset | void | double | 取得持仓的大商所持仓成本差值 |
StopLoss | void | double | 取得持仓的止损价 |
TakeProfit | void | double | 取得持仓的止赢价 |
TasPositionCost | void | double | 取得tas持仓成本 |
ToTal | void | int | 取得持仓总数 |
Index | void | int | 取得持仓序号/用于持仓操作 |
PositionType | void | ENUM_POSITION_TYPE | 取得持仓多空方向 |
Direction | void | char | 取得持仓多空方向 |
DirectionDescription | void | string | 持仓多空方向注释 |
Hedge | void | char | 取得持仓投机套保标志 |
HedgeDescription | void | string | 持仓投机套保标志注释 |
PositionDate | void | char | 取得持仓日期类型 |
PositionDateDescription | void | string | 持仓日期类型注释 |
YdPosition | void | long | 取得持仓昨仓数量 |
Position | void | long | 取得持仓数量 |
LongFrozen | void | long | 取得持仓多头冻结数量 |
ShortFrozen | void | long | 取得持仓空头冻结数量 |
OpenVolume | void | long | 取得持仓开仓量 |
CloseVolume | void | long | 取得持仓平仓量 |
SettlementID | void | long | 取得持仓的结算编号 |
CombPosition | void | long | 取得持仓组合持仓数量 |
CombLongFrozen | void | long | 取得持仓组合多头冻结数量 |
CombShortFrozen | void | long | 取得持仓组合空头冻结数量 |
TodayPosition | void | long | 取得今日持仓数量 |
StrikeFrozen | void | long | 取得执行冻结数量 |
AbandonFrozen | void | long | 取得放弃执行冻结数量 |
YdStrikeFrozen | void | long | 取得执行冻结的昨仓数量 |
TasPosition | void | long | 取得tas持仓手数 |
Select | string | bool | ticket方式选中持仓 |
SelectByIndex | int | bool | index方式选中持仓 |
第四章 报单信息:COrderInfo类和CHistoryOrderInfo类
【MT5CTP】的COrderInfo类与MT5的原生类库类似都是操作工作中订单,与MT5的原生类库不同,【MT5CTP】的CHistoryOrderInfo类可以操作所有订单,包括已成交订单和未成交的工作中订单。实际上【MT5CTP】系统只需要一个CHistoryOrderInfo类九可以实现对应的功能,不过为了与MT5保持“形式上”统一和EA开发过程中的操作便利和执行效率,【MT5CTP】单独把未成交的订单操作独立出一个类:COrderInfo类。
一个报单报送流程:MT5CTP指令生成报单信息->CTP系统检验生成报单信息->交易所检验报送交易撮合主机->成交更新报单信息。MT5CTP指令生成报单信息即时在MT5CTP系统保存,并根据CTP返回信息更新系统信息,如果是MT5CTP系统外的报单,MT5CTP会根据报单回报信息即时生成一个系统内报单,并根据收到的报单信息持续更新,保持MT5CTP系统与CTP系统的实时一致。报单指令包括:买入(卖出)开仓指令,买入(卖出)平仓(平今仓)指令,撤单指令,订单修改指令,条件报单指令,TAS指令(赞不支持),期权行权指令(赞不支持),组合开平仓指令(赞不支持)等。
CHistoryOrderInfo类在EA中应用较少,下面主要介绍COrderInfo类的功能函数及调用方法,功能函数:
函数名 | 参数 | 返回值 | 功能说明 |
Ticket | void | string | 取得报单mt5ctp系统编码 |
BrokerID | void | string | 取得报单经纪商ID |
InvestorID | void | string | 取得报单投资者代码 |
Symbol | void | string | 取得报单合约代码 |
UserID | void | string | 取得报单用户代码 |
Offset | void | string | 取得报单组合开平标志 |
OpenClose | void | long | 取得报单mt5ctp系统开平 |
Hedge | void | string | 取得组合投机套保标志 |
GTDDate | void | string | 取得GTD日期 |
BusinessUnit | void | string | 取得业务单元 |
OrderLocalID | void | string | 取得本地报单编号 |
ExchangeID | void | string | 取得交易所代码 |
ParticipantID | void | string | 取得会员代码 |
ClientID | void | string | 取得客户代码 |
ExchangeInstID | void | string | 取得合约在交易所的代码 |
TraderID | void | string | 取得交易所交易员代码 |
TradingDay | void | string | 取得报单交易日 |
OrderSysID | void | string | 取得交易所报单编号 |
InsertDate | void | string | 取得报单日期”20201218” |
InsertTime | void | string | 取得委托时间”09:36:36” |
ActiveTime | void | string | 取得激活时间 |
SuspendTime | void | string | 取得挂起时间 |
UpdateTime | void | string | 取得最后修改时间 |
CancelTime | void | string | 取得报单撤销时间 |
ActiveTraderID | void | string | 取得最后修改交易所交易员代码 |
UserProductInfo | void | string | 取得用户端产品信息 |
StatusMsg | void | string | 取得报单状态信息 |
ActiveUserID | void | string | 取得操作用户代码 |
RelativeOrderSysID | void | string | 取得报单相关报单 |
BranchID | void | string | 取得营业部编号 |
InvestUnitID | void | string | 取得投资单元代码 |
AccountID | void | string | 取得资金账号 |
CurrencyID | void | string | 取得币种代码 |
IPAddress | void | string | 取得报单IP地址 |
MacAddress | void | string | 取得报单Mac地址 |
LimitPrice | void | double | 取得报单价格 |
StopPrice | void | double | 取得报单触发价 |
StopLoss | void | double | 取得报单止损价(mt5ctp系统) |
TakeProfit | void | double | 取得报单止赢价(mt5ctp系统) |
ToTal | void | int | 取得工作订单总数 |
Index | void | int | 取得报单序号/用于订单操作 |
Time | void | datetime | 取得报单时间 |
OrderRef | void | long | 取得报单引用 |
OrderPriceType | void | char | 取得报单价格条件 |
OrderPriceTypeDescription | void | string | 报单价格条件说明 |
OrderTypeMt5 | void | ENUM | 取得报单买卖方向(MT5) |
Direction | void | char | 取得报单买卖方向(CTP) |
DirectionDescription | void | string | 报单买卖方向(CTP)说明 |
TimeCondition | void | char | 取得报单有效期类型 |
TimeConditionDescription | void | string | 报单有效期类型说明 |
VolumeTotal | void | long | 取得报单数量 |
VolumeTraded | void | long | 取得报单成交数量 |
Volume | void | long | 取得报单剩余/工作中数量 |
MinVolume | void | long | 取得报单最小成交量 |
VolumeCondition | void | char | 取得报单成交量类型 |
VolumeConditionDescription | void | string | 报单成交量类型说明 |
ContingentCondition | void | char | 取得报单触发条件 |
ContingentConditionDescription | void | string | 报单触发条件说明 |
ForceCloseReason | void | char | 取得报单强平原因 |
ForceCloseReasonDescription | void | string | 报单强平原因说明 |
IsAutoSuspend | void | bool | 取得报单是否自动挂起 |
RequestID | void | long | 取得报单请求编号 |
InstallID | void | long | 取得报单安装编号 |
OrderSubmitStatus | void | char | 取得报单提交状态 |
OrderSubmitStatusDescription | void | string | 报单提交状态说明 |
NotifySequence | void | long | 取得报单提示序号 |
SettlementID | void | long | 取得报单结算编号 |
OrderSource | void | char | 取得报单来源 |
OrderSourceDescription | void | string | 报单来源说明 |
OrderStatus | void | char | 取得报单状态 |
OrderStatusDescription | void | string | 报单状态说明 |
OrderType | void | char | 取得报单状态 |
OrderTypeDescription | void | string | 报单状态说明 |
SequenceNo | void | long | 取得序号 |
FrontID | void | long | 取得前置编号 |
SessionID | void | long | 取得会话编号 |
UserForceClose | void | bool | 取得用户强评标志 |
BrokerOrderSeq | void | long | 取得经纪公司报单编号 |
ZCETotalTradedVolume | void | long | 取得郑商所成交数量 |
IsSwapOrder | void | bool | 取得互换单标志 |
Select | string | bool | 用ticket选中报单 |
SelectByIndex | int | bool | 用index选中报单 |
第五章 成交信息:CDealInfo类
【MT5CTP】的CDealInfo类与MT5的原生类库类似都是取得订单成交信息。这个类库的功能比较简单,工作机制和原理与CPositionInfo、COrderInfo、CHistoryOrderInfo类库一致,就不做更多深入的介绍。类库的功能函数:
函数名 | 参数 | 返回值 | 功能说明 |
Ticket | void | string | 取得成交mt5ctp系统编码 |
Order | void | string | 取得报单mt5ctp系统编码 |
Symbol | void | string | 取得成交合约代码 |
ExchangeInstID | void | string | 取得成交合约在交易所的代码 |
ExchangeID | void | string | 取得成交合约的交易所代码 |
InvestorID | void | string | 取得成交投资者代码 |
UserID | void | string | 报单成交用户代码 |
BrokerID | void | string | 取得成交经纪公司代码 |
TradeID | void | string | 取得成交编号 |
OrderSysID | void | string | 取得报单编号 |
OrderLocalID | void | string | 取得本地报单编号 |
TradeDate | void | string | 取得成交日期 |
TradeTime | void | string | 取得成交时间 |
TradingDay | void | string | 取得交易日 |
BusinessUnit | void | string | 取得业务单元 |
InvestUnitID | void | string | 取得投资单元代码 |
Price | void | double | 取得成交价 |
ToTal | void | int | 取得成交记录总数 |
Time | void | datetime | 取得成交日期时间 |
Direction | void | char | 取得买卖方向 |
DirectionDescription | void | string | 买卖方向说明 |
Offset | void | char | 取得开平仓 |
OffsetDescription | void | string | 开平仓说明 |
Hedge | void | char | 取得投机套保标志 |
HedgeDescription | void | string | 投机套保标志说明 |
TradeType | void | char | 取得成交类型 |
TradeTypeDescription | void | string | 成交类型说明 |
TradingRole | void | char | 取得交易角色 |
TradingRoleDescription | void | string | 交易角色说明 |
PriceSource | void | char | 取得成交价格来源 |
PriceSourceDescription | void | string | 成交价格来源说明 |
TradeSource | void | char | 取得成交来源 |
TradeSourceDescription | void | string | 成交来源说明 |
Volume | void | long | 取得成交数量 |
OrderRef | void | long | 取得报单引用 |
SequenceNo | void | long | 取得成交序号 |
SettlementID | void | long | 取得结算编号 |
BrokerOrderSeq | void | long | 取得经纪公司报单序号 |
Select | string | bool | 用ticket选中成交 |
SelectByIndex | int | bool | 用index选中成交 |
第六章 报单交易:CTrade类
前面介绍的类库及功能函数,都是数据提取方法,提取数据,计算统计都是为了交易驱动,【MT5CTP】的CTrade类是完成交易报单的核心驱动类,有必要做周到的介绍。还是先逐一介绍类库的功能函数:
1) void Request(MqlTradeRequest &request)
功能:取得最近一次报单请求的信息,MqlTradeRequest结构体做参数引用
2) void Result(MqlTradeResult &result)
功能:取得最近一次报单请求的结果,MqlTradeResult 结构体做参数引用
3) void CheckResult(MqlTradeCheckResult &check_result)
功能:取得最近一次报单检查的结果,MqlTradeCheckResult 结构体做参数引用
4) void SetDeviationInPoints(const ulong deviation)
功能:设置报单滑点tick数
5) void SetTypeFilling(const ENUM_ORDER_TYPE_FILLING filling)
功能:设置特殊交易指令,普通交易指令不用设置,如果使用FAK、FOK指令需要特别设置
6) void Reset(void);
功能:恢复默认设置
7) bool PositionOpen(const string symbol, // 开仓合约代码
const ENUM_ORDER_TYPE order_type, // 开仓报单类型:买|卖
const long volume, // 开仓数量
const double price, // 开仓价格
const ulong deviation=ULONG_MAX, // 开仓滑点
const double sl=0.0, // 开仓止损价
const double tp=0.0) // 开仓止盈价
功能:开仓报单
8) Bool PositionClose(const string symbol, // 平仓合约代码
const ENUM_ORDER_TYPE order_type, // 平仓报单类型:买|卖
const long volume, // 平仓数量
const double price, // 平仓价格
const long close_type = ORDER_TYPE_EXIT, // 平仓类型:平仓|平今
const ulong deviation=ULONG_MAX); // 平仓滑点
功能:平仓报单
9) bool PositionClose(const string ticket, // 持仓ticket
const long volume, // 平仓数量
const double price, // 平仓价格
const ulong deviation=ULONG_MAX); // 平仓滑点
功能:快捷平仓,根据选中的持仓ticket
10) bool PositionClose(const int pos, // 持仓ticket
const long volume, // 平仓数量
const double price, // 平仓价格
const ulong deviation=ULONG_MAX); // 平仓滑点
功能:快捷平仓,根据选中的持仓index
11) bool PositionModify(const string ticket,const double sl,const double tp);
功能:根据选中的持仓ticket,修改持仓止损止盈
12) bool PositionModify(const int pos,const double sl,const double tp);
功能:根据选中的持仓index,修改持仓止损止盈
13) bool PositionAuto(const string symbol, // 报单合约代码
const ENUM_ORDER_TYPE order_type, // 报单类型:买|卖
const long volume, // 报单数量
const double price, // 报单价格
const ulong deviation=ULONG_MAX); // 报单滑点
功能:自动开平仓/先平今/后平昨/再开仓,用户层只需要关注买|卖即可
14) bool OrderOpen(const string symbol, // 条件单合约代码
const ENUM_ORDER_TYPE order_type, // 条件单报单类型
const long volume, // 条件单报单数量
const double price, // 条件单报单价格
const double stoplimit_price, // 条件单触发价格
const double sl, // 条件单止损价
const double tp); // 条件单止盈价
功能:挂单,对应CTP系统的条件单(是否支持条件单功能需要咨询期货公司,simnow仿真交易不支持条件单),【MT5CTP】支持限价单和触发限价单。
15) bool OrderModify(const string ticket,const double sl,const double tp)
功能:根据选中的挂单ticket,修改报单止损止盈
16) bool OrderModify(const int order,const double sl,const double tp);
功能:根据选中的挂单index,修改报单止损止盈
17) bool OrderModify(const string ticket,const long volume,const double price,const double stoplimit_price);
功能:根据选中的挂单ticket,修改报单数量,报单执行价格,报单触发价格,撤单重下
18) bool OrderModify(const int order,const long volume,const double price,const double stoplimit_price);
功能:根据选中的挂单index,修改报单数量,报单执行价格,报单触发价格,撤单重下
19) bool OrderModify(const string ticket,const long volume,const double price,const double stoplimit_price,const double sl,const double tp);
功能:根据选中的挂单ticket,修改报单信息,上述多个功能的综合版本
20) bool OrderModify(const int order,const long volume,const double price,const double stoplimit_price,const double sl,const double tp);
功能:根据选中的挂单index,修改报单信息,上述多个功能的综合版本
21) bool OrderDelete(const string ticket);
功能:根据选中的挂单ticket,撤单
22) bool OrderDelete(const int order);
功能:根据选中的挂单index,撤单
23) bool Buy(const string symbol,const long volume,double price,const double sl=0.0,const double tp=0.0);
功能:买入开仓,根据交易指令类型实现的快速报单函数
24) bool Sell(const string symbol,const long volume,double price,const double sl=0.0,const double tp=0.0);
功能:卖出开仓,根据交易指令类型实现的快速报单函数
25) bool BuyLimit(const string symbol,const long volume,const double price,const double sl=0.0,const double tp=0.0);
功能:买入Limit挂单,根据交易指令类型实现的快速报单函数
26) bool BuyStop(const string symbol,const long volume,const double price,const double sl=0.0,const double tp=0.0);
功能:买入Stop挂单,根据交易指令类型实现的快速报单函数
27) bool SellLimit(const string symbol,const long volume,const double price,const double sl=0.0,const double tp=0.0);
功能:卖出Limit挂单,根据交易指令类型实现的快速报单函数
28) bool SellStop(const string symbol,const long volume,const double price,const double sl=0.0,const double tp=0.0);
功能:卖出Stop挂单,根据交易指令类型实现的快速报单函数
29) bool OrderSend(MqlTradeRequest &request,MqlTradeResult &result);
功能:MT5类型的综合报单函数,自行填充MqlTradeRequest 报单请求结构体
30) virtual void OnOrder(const int id,const long &lparam,const double &dparam,const string &sparam){};
功能:事件响应函数:报单,纯虚函数需要在子类中编写函数体,关注并处理报单响应信息,与CTP的报单响应一致,报单/撤单/成交多次响应,响应参数:
lparam:FrontID(int)
dparam:SessionID(int)
sparam:OrderRef(int)
Order/HistoryOrder Ticket:string(OrderRef.FrontID.SessionID)可确认唯一报单
31) virtual void OnTrade(const int id,const long &lparam,const double &dparam,const string &sparam){};
功能:事件响应函数:成交,纯虚函数需要在子类中编写函数体,关注并处理报单成交信息,响应参数:
lparam:TradeID(int) 成交编号/单笔报单的多笔成交
sparam:OrderSysID(string) 交易所报单编号/关联历史成交和历史报单
HistoryDeal Ticket:string(ExchangeID.OrderSysID.TradeID) 可确认唯一成交
32) virtual void OnError(const int id,const long &lparam,const double &dparam,const string &sparam){};
功能:事件响应函数:错误,纯虚函数需要在子类中编写函数体,关注并处理报单错误信息,响应参数:
lparam:FrontID(int)
dparam:SessionID(int)
sparam:OrderRef(int)
Order/HistoryOrder Ticket:string(OrderRef.FrontID.SessionID)可确认唯一报单
功能函数基本就是这样了,为了让这些功能更加安全的实现,Trade.mqh包含了前面介绍的库,也就是说Trade.mqh是一个综合的类库,Trade.mqh也是一个开源的类库,【MT5CTP】项目爱好者可以自由查看源代码,了解各功能函数实现方式,深入了解项目的工作机制。后面的章节将结合EA的功能使用Trade的类库实现各种策略思想。
第七章 CTrade类的基本应用
开始尝试使用【MT5CTP】项目CTrade类开始基本操作-开仓、平仓操作,用到PositionOpen和PositionClose函数。再回顾一下这两个函数:
bool PositionOpen(const string symbol, // 开仓合约代码
const ENUM_ORDER_TYPE order_type, // 开仓报单类型:买|卖
const long volume, // 开仓数量
const double price, // 开仓价格
const ulong deviation=ULONG_MAX, // 开仓滑点
const double sl=0.0, // 开仓止损价
const double tp=0.0) // 开仓止盈价
功能:开仓报单
Bool PositionClose(const string symbol, // 平仓合约代码
const ENUM_ORDER_TYPE order_type, // 平仓报单类型:买|卖
const long volume, // 平仓数量
const double price, // 平仓价格
const long close_type = ORDER_TYPE_EXIT, // 平仓类型:平仓|平今
const ulong deviation=ULONG_MAX); // 平仓滑点
功能:平仓报单
在正确的使用前,我们做一下解释,这两个函数的返回值是bool类型,是报单指令是否成功,一直检查和跟踪到CTP柜台的返回,因为是异步通讯的模式,指令报单成功就返回,不代表订单是否成交,这与MT5的一贯规则有所不同,MT5的报单是同步模式,报单返回其成交的ticket,这个要注意分别。
这两个函数是执行的CTP的立即单模式,即立刻将订单报送到市场参与竞价,订单的成交与否遵从CTP的工作机制和国内期货市场价格优先、时间优先的撮合机制。
这两个指令支持市价单,如果报单价格为0,则【MT5CTP】项目则驱动CTP以市价单向市场报单,市价单各交易所有所不同,想深入了解的朋友可以查阅相关资料。但需要了解您所在的期货公司是否支持市价单?Simnow仿真交易柜台不支持市价单,仿真测试过程中需要注意。
平仓指令中,有平仓和平今仓的分别,默认是平仓,上期所和能源所的品种需要指定是否平今仓。很多朋友会问,如果交易所有平仓|平今仓手续费不同,怎么办?您不用担心,【MT5CTP】项目已经做了精细的处理,逻辑是如果该品种有平今仓手续费优惠,则优先平进仓,否则按照交易所规则,先开先平。中金所是个例外,平今仓有惩罚性手续费,并无法规避。
平仓指令可能会导致持仓合约组合或保证金优惠失效,如果操作的品种有单边大额保证金优惠,【MT5CTP】项目做了比较精细的处理。大商所和郑商所的组合保证金优惠,本项目尚没有支持,组合交易或者交易所自动组合,会存在保证金占用上的差异,为了降低该差异的可能影响,【MT5CTP】项目没有做报单的可用资金检查,如果可用资金不足,错误信息由CTP柜台给出。
止损止盈功能是在本地实现的,为了实现这个功能,后台引入了sqlite数据库持久化这一数据,从报单开始,设置的止盈止损数据就跟着订单流走,直到成交,如果本地系统意外或者关闭,重新登录后止损止盈的数据还在,而且是跨交易日的存在,直至手动修改或取消,止损止盈是【MT5CTP】项目后端在处理,成交后的订单如果需要调整止损止盈,可以调用PositionModify函数。需要注意的是因为是合并持仓,如果新的报单有止损止盈,老的持仓也有止损止盈,那么新报单成交后会更新持仓的止损止盈。
报单滑点,CTrade类中默认5个PriceTick,报单函数中如果没有指定,则使用类中的默认值,如果你再次指定了滑点数,则使用您指定的参数,这好像有点复杂,其实是为了提高操作的灵活性。当然在类对象初始化后,可以调用SetDeviationInPoints函数重新设定,使用Reset函数恢复类默认值。
Ok,我们在代码中给出使用的介绍(部分代码来源于项目爱好者【老韭菜】的EA开发框架,框架功能包括指数合约映射|主力合约自动换月|自动计算交易数量等):
//---MT5CTP--【固定格式】包含合约库文件/目录 #include <mt5ctp\Trade.mqh> //+------------------------------------------------------------------+ // EA参数 input bool AllowOpenNew=true; //若false只能平仓不能开仓 input int Lots =0; //预设固定手数 input double Money =0; //预设使用资金量 input double BrokerRatio =0.14; //经纪公司杠杆比例 input int Surrender =300; //止损 input long MaxLots =500; //最大允许手数 input bool IsAutoMain =true; //主力合约自动换月 //+------------------------------------------------------------------+ // 全局变量 // 交易对象 CTrade iTrade; // 图表合约|主力合约|持仓合约 CSymbolInfo iSymbol,iOrderSymbol,pSymbol; // 持仓 CPositionInfo iPosition; // 资金账户 CAccountInfo iAccount; // 检查主力合约换月 bool iMainAutoSelcet; // 是否重新初始化 bool iInitReset; //+------------------------------------------------------------------+ //| 初始化 | //+------------------------------------------------------------------+ int OnInit() { // 框架初始化 if((iInitReset=Init())!=true) { return(INIT_FAILED); } return(INIT_SUCCEEDED); } // 框架初始化 bool Init(void) { iMainAutoSelcet = IsAutoMain; // 图表合约检查 if(!iSymbol.Select(NULL)) { return(false); } // 检查图表合约是否为指数合约/不管是否自动换月都要检查 if(!iSymbol.IsIndex()) { iMainAutoSelcet = false; Alert("图表合约不是指数合约.主力合约自动换月功能关闭"); } else { // 取得指数合约对应的主力合约 if(!iOrderSymbol.Select(SymbolInfoString(iSymbol.Symbol(),SYMBOL_BASIS))) { return(false); } } // 初始化完成 return(true); } //+------------------------------------------------------------------+ //| 反初始化 | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| 手数计算 | //+------------------------------------------------------------------+ long LotsOptimized() { if(Lots!=0) return(Lots); else { long lot=1; if(Money==0) lot=(long)MathFloor(iAccount.Available() /(iSymbol.Ask()*iSymbol.ContractSize()*BrokerRatio)); else { //代码 } if(lot>MaxLots) lot=MaxLots; return(lot); } } //+------------------------------------------------------------------+ //| 主函数 | //+------------------------------------------------------------------+ void OnTick() { // 检查账户是否已登陆 if(!iAccount.AccountExists()) { iInitReset = false; return; } // 重新初始化同步主力合约/连续无人值守交易 if(!iInitReset) { iInitReset = Init(); return; } // if(myPosition()!=0) checkClose(); else checkOpen(); } //+------------------------------------------------------------------+ //| 计算是否开仓 | //+------------------------------------------------------------------+ void checkOpen() { if(!AllowOpenNew) return;//不允许开新仓 if(signal()==1) { //代码 buy(); } if(signal()==2) { //代码 sell(); } } //+------------------------------------------------------------------+ //| 计算是否平仓 | //+------------------------------------------------------------------+ void checkClose() { for(int index = iPosition.ToTal(); index>0; index--) { if(!iPosition.SelectByIndex(index)) continue;// 选中持仓 if(iPosition.Position()==0) continue;// 过滤持仓为0的持仓 if(!pSymbol.Select(iPosition.Symbol())) continue;// 取得持仓合约 bool pos_check = false; // 图表合约为指数合约/统计该品种持仓 if(iSymbol.IsIndex()) { pos_check = iSymbol.ProductID()==pSymbol.ProductID(); } else { pos_check = iSymbol.Symbol()==pSymbol.Symbol(); } if(!pos_check) continue; // 持仓合约未匹配 if(iPosition.PositionType() == POSITION_TYPE_BUY)//多单 { // 多单止损 if(iPosition.Price()-iSymbol.Bid()>=Surrender*pSymbol.PriceTick()) { iTrade.PositionClose(index,iPosition.Position()-iPosition.LongFrozen(),pSymbol.Bid()); } if(signal()==2) { //代码 //close();//close函数为全部平仓,请假查是否符合逻辑 } // 检查自动换月 if(iMainAutoSelcet) { if(pSymbol.Symbol()!=iOrderSymbol.Symbol()) { if(iTrade.PositionClose(index,iPosition.Position()-iPosition.LongFrozen(),pSymbol.Bid())) { iTrade.PositionOpen(iOrderSymbol.Symbol(),ORDER_TYPE_BUY,iPosition.Position()-iPosition.LongFrozen(),iOrderSymbol.Ask()); } } } } else //空单 { // 止损 if(iSymbol.Ask()-iPosition.Price()>=Surrender*pSymbol.PriceTick()) { iTrade.PositionClose(index,iPosition.Position()-iPosition.ShortFrozen(),pSymbol.Ask()); } if(signal()==1) { //代码 //close();//close函数为全部平仓,请假查是否符合逻辑 } // 检查自动换月 if(iMainAutoSelcet) { if(pSymbol.Symbol()!=iOrderSymbol.Symbol()) { if(iTrade.PositionClose(index,iPosition.Position()-iPosition.ShortFrozen(),pSymbol.Ask())) { iTrade.PositionOpen(iOrderSymbol.Symbol(),ORDER_TYPE_SELL,iPosition.Position()-iPosition.ShortFrozen(),iOrderSymbol.Bid()); } } } } } } //+------------------------------------------------------------------+ //| 开平仓信号 | //+------------------------------------------------------------------+ int signal() { int signal=0; //信号代码 return(signal); } //+------------------------------------------------------------------+ //| 统计现有仓位 | //+------------------------------------------------------------------+ long myPosition() { long pos_lots_long = 0,pos_lots_short = 0; int total = iPosition.ToTal(); //总单数? for(int index = total; index>0; index--) { if(!iPosition.SelectByIndex(index)) continue;// 选中持仓 if(iPosition.Position()==0) continue;// 过滤持仓为0的持仓 if(!pSymbol.Select(iPosition.Symbol())) continue;// 取得持仓合约 bool pos_check = false; // 图表合约为指数合约/统计该品种持仓 if(iSymbol.IsIndex()) { pos_check = iSymbol.ProductID()==pSymbol.ProductID(); } else { pos_check = iSymbol.Symbol()==pSymbol.Symbol(); } if(!pos_check) continue; // 持仓合约未匹配 if(iPosition.PositionType() == POSITION_TYPE_BUY)// 汇总多头数 { pos_lots_long += iPosition.Position(); } else // 不是多头就是空头 { pos_lots_short += iPosition.Position(); // 汇总空单数 } } // 多空合约均持仓统计净持仓/否则返回多头(+)或空头(-)持仓合约数量 return(pos_lots_long-pos_lots_short); } //+------------------------------------------------------------------+ //| 开多仓 | //+------------------------------------------------------------------+ void buy() { // 图表为指数合约映射到主力合约交易 if(iSymbol.IsIndex()) { iTrade.Buy(iOrderSymbol.Symbol(),LotsOptimized(),iOrderSymbol.Ask(),0,0); } else { iTrade.Buy(iSymbol.Symbol(),LotsOptimized(),iSymbol.Ask(),0,0); } } //+------------------------------------------------------------------+ //| 开空仓 | //+------------------------------------------------------------------+ void sell() { // 图表为指数合约映射到主力合约交易 if(iSymbol.IsIndex()) { iTrade.Sell(iOrderSymbol.Symbol(),LotsOptimized(),iOrderSymbol.Bid(),0,0); } else { iTrade.Sell(iSymbol.Symbol(),LotsOptimized(),iSymbol.Bid(),0,0); } } //+------------------------------------------------------------------+ //| 全平 | //+------------------------------------------------------------------+ void close() { int total = iPosition.ToTal(); //总单数 for(int index = total; index>0; index--) { if(!iPosition.SelectByIndex(index)) continue;// 选中持仓 if(iPosition.Position()==0) continue;// 过滤持仓为0的持仓 if(!pSymbol.Select(iPosition.Symbol())) continue;// 取得持仓合约 bool pos_check = false; // 图表合约为指数合约/该品种全平 if(iSymbol.IsIndex()) { pos_check = iSymbol.ProductID()==pSymbol.ProductID(); } else { pos_check = iSymbol.Symbol()==pSymbol.Symbol(); } if(!pos_check) continue; // 持仓合约未匹配 // 平仓/扣除已经挂单的平仓 if(iPosition.PositionType()==POSITION_TYPE_BUY) { iTrade.PositionClose(index,iPosition.Position()-iPosition.LongFrozen(),pSymbol.Bid()); } else { iTrade.PositionClose(index,iPosition.Position()-iPosition.ShortFrozen(),pSymbol.Ask()); } } } //+------------------------------------------------------------------+
第八章 CTrade类的基本应用:订单操作
【MT5CTP】项目CTrade类订单操作涉及三个函数:OrderOpen,OrderModify,OrderDelete,订单主要是指未成交的挂单和未触发的条件单(工作中订单),这三个函数方法对应:报单、修改、撤单。在介绍这几个方法的应用之前,首先解释一下相关的应用背景:
1、报单到市场之后,因为交易所撮合机制的原因可能没有成交,形成挂单等待成交。这个订单,CTP柜台只提供里撤单函数,【MT5CTP】项目增加了订单修改的功能,这个功能对于mt5的工作机制是非常自然的,但是对于CTP柜台做了比较多的处理,如果只是修改止盈止损价,比较简单,修改报单的数量和价格,系统做了撤单重下的操作。
2、更多的应用是条件单,【MT5CTP】项目条件单不是本地条件单,是CTP系统条件单,也就是说,客户端报送的条件单是在CTP服务器上等待触发(交易日内有效),即便本地断开了与柜台的连接,也不影响条件单的执行。(期货公司是否支持条件单,需要咨询确认,经了解并不是所有的期货公司都支持CTP系统条件单功能)。
3、报单唯一性。mt5报单返回是一个订单的ticket用于区别其他的订单,但是CTP系统是用一组字段来确认唯一一笔订单。在这个基础上,【MT5CTP】项目使用了两套机制来取得对应的报单,ticket为string类型,用于匹配CTP的唯一报单,后台使用index(ulong类型)模仿MT5的ticket,项目建立了ticket与index的对应,需要注意的是,string类型的ticket是系统唯一不变的,index根据报单的变化在变化,即不是唯一不变的,所以记录index是不安全的,记录string类型的ticket可以是安全无误的。正因为这个情况,订单修改和撤单的函数都提供两个版本,同时报单的返回值也是bool类型。
重新认识一下这几个函数:
// 条件单报单 bool OrderOpen(const string symbol, // 合约代码 const ENUM_ORDER_TYPE order_type, // 报单类型 const long volume, // 报单数量 const double price, // 报单价格 const double stoplimit_price, // 触发价格 const double sl, // 止损价格 const double tp); // 止盈价格 // 条件单/挂单/修改止损止盈 bool OrderModify(const string ticket,const double sl,const double tp); bool OrderModify(const int order,const double sl,const double tp); // 条件单/挂单/修改价格数量 bool OrderModify(const string ticket,const long volume,const double price,const double stoplimit_price); bool OrderModify(const int order,const long volume,const double price,const double stoplimit_price); // 条件单/挂单/修改 bool OrderModify(const string ticket,const long volume,const double price,const double stoplimit_price,const double sl,const double tp); bool OrderModify(const int order,const long volume,const double price,const double stoplimit_price,const double sl,const double tp); // 条件单/挂单撤单 bool OrderDelete(const string ticket); bool OrderDelete(const int order);
4、条件单的报单价格和触发价格。条件单触发价格用于指定的触发条件,触发后订单由CTP系统报单到交易所时使用报单价格,这两个价格可以不同,无形之中拓展了条件单的使用范围,CTP的条件单功能很强大,善用调价单主观交易必定会事半功倍,如果量化交易,有没有必要有待商榷,因为所有的条件单都可以使用EA来实现,而且更加的灵活。Demo代码可以查看随本项目发布的工具箱mt5ctptools,主文件toolbox.mqh,行号[3134-3530]。
第九章 CTrade类的高级应用:事件操作
CTP的报单及响应是异步的,这区别于mt5的同步报单模式。EA可能需要精确控制每一个订单,并根据订单的变化做出反应,比如需要发小单高频率探测市场深度,比如根据回报结果快速做出反应,可能要在500毫秒的行情间隙做出多个决策,不管哪一种应用,【MT5CTP】项目的事件模式都可以支持,让你的想法变成可能。
CTrade类,提供了三个事件虚函数函数:OnOrder,OnTrade,OnError,这三个函数分别对应报单事件,成交事件和报单错误事件,在类中我们做了如下定义:
//--- methods for working with event virtual void OnOrder(const int id,const long &lparam,const double &dparam,const string &sparam){}; virtual void OnTrade(const int id,const long &lparam,const double &dparam,const string &sparam){}; virtual void OnError(const int id,const long &lparam,const double &dparam,const string &sparam){};
在事件处理函数中
// 订单事件 报单/撤单/成交多次响应 case EXPERT_CTP_ORDER: // lparam:FrontID(int) // dparam:SessionID(int) // sparam:OrderRef(int) // Order/HistoryOrder Ticket:string(OrderRef.FrontID.SessionID) OnOrder(id,lparam,dparam,sparam); break; // 成交事件 case EXPERT_CTP_TRADE: // lparam:TradeID(int) 成交编号/单笔报单的多笔成交 // sparam:OrderSysID(string) 交易所报单编号/关联历史成交和历史报单 // HistoryDeal Ticket:string(ExchangeID.OrderSysID.TradeID) 可确认唯一成交 OnTrade(id,lparam,dparam,sparam); break; // 错误事件 case EXPERT_CTP_ERROR: // lparam:FrontID(int) // dparam:SessionID(int) // sparam:OrderRef(int) // Order/HistoryOrder Ticket:string(OrderRef.FrontID.SessionID) OnError(id,lparam,dparam,sparam); break;
在报单回报信息中,我们提取到需要的关键字段ticket(string),就可以使用Select(const string ticket)来选中订单作进一步的处理。如何确定选中的订单是我们需要关注的订单呢?CTrade类保存了最后一次报单的信息,也就是做报单之后马上就可以提取到需要关注的报单关键信息ticket(string),这个值我们是借用了MqlTradeRequest结构体的comment字段实现的。
这样流程就比较明晰了:报单时返回报单的关键字段ticket(string),然后在报单回报信息中,组合产生关键字段ticket(string),然后使用Select(const string ticket)函数选中报单或成交,得到全部的报单/成交信息。
要使用上述这些内容,你需要继承CTrade类,并实现对应的三个事件响应函数,并且需要在事件处理函数中增加事件处理的接口。下面上demo:
//【固定格式】包含合约库文件/目录 #include <mt5ctp\Trade.mqh> //+------------------------------------------------------------------+ //| Expert Class | //+------------------------------------------------------------------+ class MTrade: public CTrade { //-- 各种定义 //--- methods for working with event virtual void OnOrder(const int id,const long &lparam,const double &dparam,const string &sparam); virtual void OnTrade(const int id,const long &lparam,const double &dparam,const string &sparam); virtual void OnError(const int id,const long &lparam,const double &dparam,const string &sparam); }; //+------------------------------------------------------------------+ //| MTrade函数 | //+------------------------------------------------------------------+ //-- 各种定义 //+------------------------------------------------------------------+ //| methods for working with event | //+------------------------------------------------------------------+ // 报单响应 // lparam:FrontID(int) // dparam:SessionID(int) // sparam:OrderRef(int) // Order/HistoryOrder Ticket:string(OrderRef.FrontID.SessionID) void MTrade::OnOrder(const int id,const long &lparam,const double &dparam,const string &sparam) { // 格式化ticket string order_ticket = ::StringFormat("%s.%d.%d",sparam,lparam,(long)dparam); CHistoryOrderInfo last_order; if(!last_order.Select(order_ticket)) { return; } } //+------------------------------------------------------------------+ // 成交响应 // lparam:TradeID(int) 成交编号/单笔报单的多笔成交 // sparam:OrderSysID(string) 交易所报单编号/关联历史成交和历史报单 // HistoryDeal Ticket:string(ExchangeID.OrderSysID.TradeID) 可确认唯一成交 void MTrade::OnTrade(const int id,const long &lparam,const double &dparam,const string &sparam) { CDealInfo last_deal; CSymbolInfo last_symbol; // [1.20版本]不要问为什么这么格式化ticket,项目组测试出来的,CTP给的信息有时候不完全正确 string deal_ticket = ::StringFormat("%s.%s.%12d",last_symbol.ExchangeID(),sparam,lparam); // [1.40版本]新增信息提取函数,便于提取订单信息 string deal_ticket = ::StringFormat("%s.%s.%s",ExchangeID(lparam),sparam,TradeID(dparam)); if(!last_deal.Select(deal_ticket)) { return; } // 上述信息也可以从order信息中提取 // do ... } //+------------------------------------------------------------------+ // 错误响应 // lparam:FrontID(int) // dparam:SessionID(int) // sparam:OrderRef(int) // Order/HistoryOrder Ticket:string(OrderRef.FrontID.SessionID) void MTrade::OnError(const int id,const long &lparam,const double &dparam,const string &sparam) { // 格式化ticket string order_ticket = ::StringFormat("%s.%d.%d",sparam,lparam,(long)dparam); // do ... } //+------------------------------------------------------------------+ //| 全局变量 | //+------------------------------------------------------------------+ // 交易对象 MTrade td; // 报单请求信息 MqlTradeRequest req; //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(cond) { if(td.PositionOpen(...)) { // 更新数据记录 ::ZeroMemory(req); td.Request(req); if(::StringLen(req.comment)>0) { string order_ticket = req.comment; } } } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //-- 策略图标事件响应 td.OnChartEvent(id,lparam,dparam,sparam); }
订单追踪处理的全部流程基本就是这样了。既然我们已经继承了CTrade类,那么我们就可以按照实际需求完善和丰富类的功能,甚至做到独一无二,各种便捷的处理或者公共函数,都可以实现封装和最大程度的代码重用。【MT5CTP】项目为各种可能的应用提供了比较扎实的基础,从报单驱动到信息提取,到报单的跟踪。MQL5开发环境也足够的开放、稳定、高效。无论是初学乍练,还是独孤求败,【MT5CTP】项目提供了各种可能。
还没有评论,来说两句吧...