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】项目提供了各种可能。
还没有评论,来说两句吧...