MT5CTP帮助手册-插件

博主:EA邦唐老师EA邦唐老师 2021-08-28 3833 0条评论
摘要: 在MT5CTP的介绍文章中,项目组列出了所有的EA函数和类库,源代码中也有详细的注释,没有更详细的介绍和结合功能的使用方法。在项目爱好者的督促之下,基于1.2版本的类库,项目组开始...

在MT5CTP的介绍文章中,项目组列出了所有的EA函数和类库,源代码中也有详细的注释,没有更详细的介绍和结合功能的使用方法。在项目爱好者的督促之下,基于1.2版本的类库,项目组开始编写开发手册,项目组推荐爱好者基于类库做EA开发的使用、提高和扩展,因为这更加安全、可靠、高效和优雅。

MT5CTP类库在<include\mt5ctp\>目录下,列表如下:

类库文件名类名说明备注
AccountInfo.mqhCAccountInfo账户类:提取账户信息V1.20
DealInfo.mqhCDealInfo成交类:提取成交信息V1.20
HistoryOrderInfo.mqhCHistoryOrderInfo报单类:提取报单信息V1.20
OrderInfo.mqhCOrderInfo挂单类:未成交报单信息V1.20
mtctp.mqhMT4CTPMT4源码适配本手册不涉及
mt5ctp.mqhMT5CTP基础函数库本手册不涉及
PositionInfo.mqhCPositionInfo持仓类:提取持仓信息V1.20
SymbolInfo.mqhCSymbolInfo合约类:提取合约信息V1.20
toolbox.mqh交易管理工具(界面)本手册不涉及
JAson.mqhCJAValJson类:第三方库本手册不涉及
Trade.mqhCTrade交易类:交易驱动V1.20

开发手册主要介绍上述加粗的7个类库1.20版本的使用。按照EA设计、开发、测试、部署等流程和习惯,先从交易合约入手,然后是交易账户(资金和持仓),再然后是交易,最后是报单和成交统计分析。开发手册也按照这个顺序展开,首先列出类函数和功能简介,然后针对问题,提供解决方案的方式来展示其使用方法,务求清晰明了。

第一章 交易合约:CSymbolInfo类

为了便于记忆,我们库文件名和类名与mt5原生的类库保持一致,CSymbolInfo类也遵循这一原则,CSymbolInfo类用于EA中驱动交易是安全的,如果是用来做指标设计和开发,你可以直接使用mt5原生函数和类库就可以。也就是说,本项目由两套交易合约数据提取的方案:mt5原生函数和CSymbolInfo类和MT5CTP项目提供的CSymbolInfo类,都可用,特别声明:MT5CTP项目提供的CSymbolInfo类用于EA更安全可靠。

CSymbolInfo类功能函数表:

函数名参数返回值功能说明
Symbolvoidstring取得交易合约代码
Namevoidstring取得交易合约名称
ExchangeIDvoidstring取得交易所代码
ExchangeInstIDvoidstring取得合约在交易所的代码
ProductIDvoidstring取得合约的产品代码
ProductNamevoidstring取得合约的产品名称
ExchangeProductIDvoidstring取得产品在交易所的代码
UnderlyingInstrIDvoidstring取得合约的基础商品代码
Currencyvoidstring取得合约的交易币种
CreateDatevoidstring取得合约的创建日
OpenDatevoidstring取得合约的上市日
ExpireDatevoidstring取得合约的到期日
StartDelivDatevoidstring取得合约的开始交割日
EndDelivDatevoidstring取得合约的结束交割日
EnterTimevoidstring取得合约的【状态】变化的时间
TradingDayvoidstring取得合约行情的当前交易日
ActionDayvoidstring取得合约行情的当前业务日期
UpdateTimevoidstring取得合约行情的更新时间
SessionStartintstring取得合约交易时段的开始时间
SessionEndintstring取得合约交易时段的结束时间
PriceTickvoiddouble取得合约的最小变动价位
UnderlyingMultiplevoiddouble取得合约的合约基础商品乘数
StrikePricevoiddouble取得合约的执行价(期权)
LastPricevoiddouble取得合约的最新价
PreSettlementvoiddouble取得合约的昨结算价
PreClosevoiddouble取得合约的昨收盘价
Openvoiddouble取得合约的今开盘价
Highvoiddouble取得合约的最高价
Lowvoiddouble取得合约的最低价
Closevoiddouble取得合约的收盘价
Settlementvoiddouble取得合约的结算价
UpperLimitvoiddouble取得合约的涨停板价
LowerLimitvoiddouble取得合约的跌停板价
Bidvoiddouble取得合约的申买价
Askvoiddouble取得合约的申卖价
Bid2voiddouble取得合约的申买价2
Ask2voiddouble取得合约的申卖价2
Bid3voiddouble取得合约的申买价3
Ask3voiddouble取得合约的申卖价3
Bid4voiddouble取得合约的申买价4
Ask4voiddouble取得合约的申卖价4
Bid5voiddouble取得合约的申买价5
Ask5voiddouble取得合约的申卖价5
AvgPricevoiddouble取得合约的日均价
Turnovervoiddouble取得合约的成交金额
PreOpenInterestvoiddouble取得合约的昨持仓量
OpenInterestvoiddouble取得合约的持仓量
PreDeltavoiddouble取得合约的昨虚实度(期权)
Deltavoiddouble取得合约的虚实度(期权)
LongMarginRatioByMoneyvoiddouble取得合约的多头保证金率
LongMarginRatioByVolumevoiddouble取得合约的多头保证金费
ShortMarginRatioByMoneyvoiddouble取得合约的空头保证金率
ShortMarginRatioByVolumevoiddouble取得合约的空头保证金费
ExchangeLongMarginRatioByMoneyvoiddouble取得合约的交易所多头保证金率
ExchangeLongMarginRatioByVolumevoiddouble取得合约的交易所多头保证金费
ExchangeShortMarginRatioByMoneyvoiddouble取得合约的交易所空头保证金率
ExchangeShortMarginRatioByVolumevoiddouble取得合约的交易所空头保证金费
OpenRatioByMoneyvoiddouble取得合约的开仓手续费率
OpenRatioByVolumevoiddouble取得合约的开仓手续费
CloseRatioByMoneyvoiddouble取得合约的平仓手续费率
CloseRatioByVolumevoiddouble取得合约的平仓手续费
CloseTodayRatioByMoneyvoiddouble取得合约的平今仓手续费率
CloseTodayRatioByVolumevoiddouble取得合约的平今仓手续费
OrderCommByVolumevoiddouble取得合约的报单手续费
OrderActionCommByVolumevoiddouble取得合约的撤单手续费
ProductClassvoidchar取得合约的产品类型
ProductClassDescriptionvoidstring合约产品类型说明
DeliveryYearvoidlong取得合约的交割年份
DeliveryMonthvoidlong取得合约的交割月份
MaxMarketOrderVolumevoidlong取得合约的市价最大下单量
MinMarketOrderVolumevoidlong取得合约的市价最小下单量
MaxLimitOrderVolumevoidlong取得合约的限价最大下单量
MinLimitOrderVolumevoidlong取得合约的限价最小下单量
ContractSizevoidlong取得合约的数量/乘数
Digitsvoidlong取得合约的小数点位数
InstLifePhasevoidchar取得合约的生命周期状态
InstLifePhaseDescriptionvoidstring合约生命周期状态说明
IsTradingvoidbool取得合约当前是否交易
PositionTypevoidchar取得合约的持仓类型
PositionTypeDescriptionvoidstring合约持仓类型说明
PositionDateTypevoidchar取得合约的持仓日期类型
PositionDateTypeDescriptionvoidstring合约持仓日期类型说明
CloseDealTypevoidchar取得合约的平仓处理类型
CloseDealTypeDescriptionvoidstring合约平仓处理类型说明
MortgageFundUseRangevoidchar取得合约的质押资金可用范围
MortgageFundUseRangeDescriptionvoidstring合约质押资金可用范围说明
MaxMarginSideAlgorithmvoidchar取得合约的大额单边保证金算法
MaxMarginSideAlgorithmDescriptionvoidstring合约大额单边保证金算法说明
OptionsTypevoidchar取得合约的期权类型
OptionsTypeDescriptionvoidstring合约期权类型说明
CombinationTypevoidchar取得组合类型
CombinationTypeDescriptionvoidstring组合类型说明
IsIndexvoidbool是否指数合约
IsMainvoidbool是否主力合约
IsSubMarketvoidbool是否已订阅行情
SymbolExistsvoidbool是否交易时间
Statusvoidchar取得合约的交易状态
StatusDescriptionvoidstring合约交易状态说明
EnterReasonvoidchar取得合约进入交易本状态原因
EnterReasonDescriptionvoidstring合约进入交易本状态原因说明
Volumevoidlong取得合约的日成交数量
UpdateMillisecvoidlong取得合约最新行情的毫秒数
BidVolumevoidlong取得合约行情的申买量
AskVolumevoidlong取得合约行情的申卖量
Bid2Volumevoidlong取得合约行情的申买量2
Ask2Volumevoidlong取得合约行情的申卖量2
Bid3Volumevoidlong取得合约行情的申买量3
Ask3Volumevoidlong取得合约行情的申卖量3
Bid4Volumevoidlong取得合约行情的申买量4
Ask4Volumevoidlong取得合约行情的申卖量4
Bid5Volumevoidlong取得合约行情的申买量5
Ask5Volumevoidlong取得合约行情的申卖量5
SessionsTotalvoidint取得合约的交易时段数
SessionStartTimeintdatetime合约交易时段开始时间/本地
SessionEndTimeintdatetime合约交易时段结束时间/本地
NormalizePricedoubledouble按合约tick格式化合约价格
Selectstringbool是否选中/可选参数:合约代码


第二章 交易账户:CAccountInfo类

CAccountInfo类用来操作和提取账户属性和资金数据。功能函数表:

函数名参数返回值功能说明
Loginvoidstring取得登陆账户ID
BrokerIDvoidstring取得经纪商ID
TradingDayvoidstring取得交易日
LoginTimevoidstring取得登陆时间
CurrencyIDvoidstring取得币种代码
SystemNamevoidstring取得交易系统名称
FrontIDvoidlong取得用户前置
SessionIDvoidlong取得用户会话
MaxOrderRefvoidlong取得最大报单引用
AccountTypevoidchar取得账户类型
AccountTypeDescriptionvoidstring账户类型注释
PreBalancevoiddouble取得昨结算权益
PreMarginvoiddouble取得昨保证金占用
Balancevoiddouble取得动态权益
Availablevoiddouble取得可用资金
Marginvoiddouble取得保证金占用
Commissionvoiddouble取得手续费
DeliveryMarginvoiddouble取得交割保证金
Depositvoiddouble取得入金
Withdrawvoiddouble取得出金
FrozenMarginvoiddouble取得保证金冻结
FrozenCommissionvoiddouble取得手续费冻结
CloseProfitvoiddouble取得平仓盈亏
PositionProfitvoiddouble取得持仓盈亏
AccountExistsvoidbool账户是否登陆


第三章 账户持仓:CPositionInfo类

CPositionInfo类是【MT5CTP】项目比较核心的一个类,EA中使用非常频繁,开发手册尽量详尽的介绍,先把类函数列表出来。

函数名参数返回值功能说明
Ticketvoidstring取得持仓编码(mt5ctp系统)
Symbolvoidstring取得持仓的合约代码
BrokerIDvoidstring取得持仓的经纪公司代码
InvestorIDvoidstring取得持仓的投资者代码
TradingDayvoidstring取得交易日
ExchangeIDvoidstring取得持仓的交易所代码
InvestUnitIDvoidstring取得持仓的投资单元代码
LongFrozenAmountvoiddouble取得持仓的开仓冻结金额/多
ShortFrozenAmountvoiddouble取得持仓的开仓冻结金额/空
OpenAmountvoiddouble取得持仓的开仓金额
CloseAmountvoiddouble取得持仓的平仓金额
Pricevoiddouble取得持仓的持仓均价
PositionCostvoiddouble取得持仓的持仓成本
PreMarginvoiddouble取得持仓的昨结算保证金
Marginvoiddouble取得持仓的保证金
FrozenMarginvoiddouble取得持仓的冻结的保证金
FrozenCashvoiddouble取得持仓的冻结的资金
FrozenCommissionvoiddouble取得持仓的冻结的手续费
CashInvoiddouble取得持仓的资金差额
Commissionvoiddouble取得持仓的手续费
CloseProfitvoiddouble取得持仓的平仓盈亏
PositionProfitvoiddouble取得持仓的持仓盈亏
PreSettlementPricevoiddouble取得持仓的昨结算价
SettlementPricevoiddouble取得持仓的结算价
OpenCostvoiddouble取得持仓的开仓成本
OpenProfitvoiddouble取得持仓的开仓盈亏
CloseProfitByDatevoiddouble取得持仓的逐日盯市平仓盈亏
CloseProfitByTradevoiddouble取得持仓的逐笔对冲平仓盈亏
MarginRateByMoneyvoiddouble取得持仓的保证金率
MarginRateByVolumevoiddouble取得持仓的保证金率(按手数)
StrikeFrozenAmountvoiddouble取得持仓的执行冻结金额
PositionCostOffsetvoiddouble取得持仓的大商所持仓成本差值
StopLossvoiddouble取得持仓的止损价
TakeProfitvoiddouble取得持仓的止赢价
TasPositionCostvoiddouble取得tas持仓成本
ToTalvoidint取得持仓总数
Indexvoidint取得持仓序号/用于持仓操作
PositionTypevoidENUM_POSITION_TYPE取得持仓多空方向
Directionvoidchar取得持仓多空方向
DirectionDescriptionvoidstring持仓多空方向注释
Hedgevoidchar取得持仓投机套保标志
HedgeDescriptionvoidstring持仓投机套保标志注释
PositionDatevoidchar取得持仓日期类型
PositionDateDescriptionvoidstring持仓日期类型注释
YdPositionvoidlong取得持仓昨仓数量
Positionvoidlong取得持仓数量
LongFrozenvoidlong取得持仓多头冻结数量
ShortFrozenvoidlong取得持仓空头冻结数量
OpenVolumevoidlong取得持仓开仓量
CloseVolumevoidlong取得持仓平仓量
SettlementIDvoidlong取得持仓的结算编号
CombPositionvoidlong取得持仓组合持仓数量
CombLongFrozenvoidlong取得持仓组合多头冻结数量
CombShortFrozenvoidlong取得持仓组合空头冻结数量
TodayPositionvoidlong取得今日持仓数量
StrikeFrozenvoidlong取得执行冻结数量
AbandonFrozenvoidlong取得放弃执行冻结数量
YdStrikeFrozenvoidlong取得执行冻结的昨仓数量
TasPositionvoidlong取得tas持仓手数
Selectstringboolticket方式选中持仓
SelectByIndexintboolindex方式选中持仓


第四章 报单信息: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类的功能函数及调用方法,功能函数:

函数名参数返回值功能说明
Ticketvoidstring取得报单mt5ctp系统编码
BrokerIDvoidstring取得报单经纪商ID
InvestorIDvoidstring取得报单投资者代码
Symbolvoidstring取得报单合约代码
UserIDvoidstring取得报单用户代码
Offsetvoidstring取得报单组合开平标志
OpenClosevoidlong取得报单mt5ctp系统开平
Hedgevoidstring取得组合投机套保标志
GTDDatevoidstring取得GTD日期
BusinessUnitvoidstring取得业务单元
OrderLocalIDvoidstring取得本地报单编号
ExchangeIDvoidstring取得交易所代码
ParticipantIDvoidstring取得会员代码
ClientIDvoidstring取得客户代码
ExchangeInstIDvoidstring取得合约在交易所的代码
TraderIDvoidstring取得交易所交易员代码
TradingDayvoidstring取得报单交易日
OrderSysIDvoidstring取得交易所报单编号
InsertDatevoidstring取得报单日期”20201218”
InsertTimevoidstring取得委托时间”09:36:36”
ActiveTimevoidstring取得激活时间
SuspendTimevoidstring取得挂起时间
UpdateTimevoidstring取得最后修改时间
CancelTimevoidstring取得报单撤销时间
ActiveTraderIDvoidstring取得最后修改交易所交易员代码
UserProductInfovoidstring取得用户端产品信息
StatusMsgvoidstring取得报单状态信息
ActiveUserIDvoidstring取得操作用户代码
RelativeOrderSysIDvoidstring取得报单相关报单
BranchIDvoidstring取得营业部编号
InvestUnitIDvoidstring取得投资单元代码
AccountIDvoidstring取得资金账号
CurrencyIDvoidstring取得币种代码
IPAddressvoidstring取得报单IP地址
MacAddressvoidstring取得报单Mac地址
LimitPricevoiddouble取得报单价格
StopPricevoiddouble取得报单触发价
StopLossvoiddouble取得报单止损价(mt5ctp系统)
TakeProfitvoiddouble取得报单止赢价(mt5ctp系统)
ToTalvoidint取得工作订单总数
Indexvoidint取得报单序号/用于订单操作
Timevoiddatetime取得报单时间
OrderRefvoidlong取得报单引用
OrderPriceTypevoidchar取得报单价格条件
OrderPriceTypeDescriptionvoidstring报单价格条件说明
OrderTypeMt5voidENUM取得报单买卖方向(MT5)
Directionvoidchar取得报单买卖方向(CTP)
DirectionDescriptionvoidstring报单买卖方向(CTP)说明
TimeConditionvoidchar取得报单有效期类型
TimeConditionDescriptionvoidstring报单有效期类型说明
VolumeTotalvoidlong取得报单数量
VolumeTradedvoidlong取得报单成交数量
Volumevoidlong取得报单剩余/工作中数量
MinVolumevoidlong取得报单最小成交量
VolumeConditionvoidchar取得报单成交量类型
VolumeConditionDescriptionvoidstring报单成交量类型说明
ContingentConditionvoidchar取得报单触发条件
ContingentConditionDescriptionvoidstring报单触发条件说明
ForceCloseReasonvoidchar取得报单强平原因
ForceCloseReasonDescriptionvoidstring报单强平原因说明
IsAutoSuspendvoidbool取得报单是否自动挂起
RequestIDvoidlong取得报单请求编号
InstallIDvoidlong取得报单安装编号
OrderSubmitStatusvoidchar取得报单提交状态
OrderSubmitStatusDescriptionvoidstring报单提交状态说明
NotifySequencevoidlong取得报单提示序号
SettlementIDvoidlong取得报单结算编号
OrderSourcevoidchar取得报单来源
OrderSourceDescriptionvoidstring报单来源说明
OrderStatusvoidchar取得报单状态
OrderStatusDescriptionvoidstring报单状态说明
OrderTypevoidchar取得报单状态
OrderTypeDescriptionvoidstring报单状态说明
SequenceNovoidlong取得序号
FrontIDvoidlong取得前置编号
SessionIDvoidlong取得会话编号
UserForceClosevoidbool取得用户强评标志
BrokerOrderSeqvoidlong取得经纪公司报单编号
ZCETotalTradedVolumevoidlong取得郑商所成交数量
IsSwapOrdervoidbool取得互换单标志
Selectstringbool用ticket选中报单
SelectByIndexintbool用index选中报单


第五章 成交信息:CDealInfo类

【MT5CTP】的CDealInfo类与MT5的原生类库类似都是取得订单成交信息。这个类库的功能比较简单,工作机制和原理与CPositionInfo、COrderInfo、CHistoryOrderInfo类库一致,就不做更多深入的介绍。类库的功能函数:

函数名参数返回值功能说明
Ticketvoidstring取得成交mt5ctp系统编码
Ordervoidstring取得报单mt5ctp系统编码
Symbolvoidstring取得成交合约代码
ExchangeInstIDvoidstring取得成交合约在交易所的代码
ExchangeIDvoidstring取得成交合约的交易所代码
InvestorIDvoidstring取得成交投资者代码
UserIDvoidstring报单成交用户代码
BrokerIDvoidstring取得成交经纪公司代码
TradeIDvoidstring取得成交编号
OrderSysIDvoidstring取得报单编号
OrderLocalIDvoidstring取得本地报单编号
TradeDatevoidstring取得成交日期
TradeTimevoidstring取得成交时间
TradingDayvoidstring取得交易日
BusinessUnitvoidstring取得业务单元
InvestUnitIDvoidstring取得投资单元代码
Pricevoiddouble取得成交价
ToTalvoidint取得成交记录总数
Timevoiddatetime取得成交日期时间
Directionvoidchar取得买卖方向
DirectionDescriptionvoidstring买卖方向说明
Offsetvoidchar取得开平仓
OffsetDescriptionvoidstring开平仓说明
Hedgevoidchar取得投机套保标志
HedgeDescriptionvoidstring投机套保标志说明
TradeTypevoidchar取得成交类型
TradeTypeDescriptionvoidstring成交类型说明
TradingRolevoidchar取得交易角色
TradingRoleDescriptionvoidstring交易角色说明
PriceSourcevoidchar取得成交价格来源
PriceSourceDescriptionvoidstring成交价格来源说明
TradeSourcevoidchar取得成交来源
TradeSourceDescriptionvoidstring成交来源说明
Volumevoidlong取得成交数量
OrderRefvoidlong取得报单引用
SequenceNovoidlong取得成交序号
SettlementIDvoidlong取得结算编号
BrokerOrderSeqvoidlong取得经纪公司报单序号
Selectstringbool用ticket选中成交
SelectByIndexintbool用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】项目提供了各种可能。


文章最后编辑时间:2022-09-10 10:24:57