【外汇EA】:EA智能交易软件 简单的订单管理(二)
小明学外汇EA编程 2019-09-09 13:25:33 交流微信号:FX263cn 外汇EA EA智能交易软件
//+------------------------------------------------------------------+
//| 如果执行达到此点, | //| 说明没有挂单和开仓。 | //+------------------------------------------------------------------+ //---- 放置BuyStop 和 SellStop: double _OpenPriceLevel, _StopLossLevel, _TakeProfitLevel; _OpenPriceLevel = NormalizeDouble( Ask + Luft*Point, Digits ); if ( StopLoss > 0 ) { _StopLossLevel = NormalizeDouble( _OpenPriceLevel - StopLoss*Point, Digits ); } else { _StopLossLevel = 0.0; } if ( TakeProfit > 0 ) { _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel + TakeProfit*Point, Digits ); } else { _TakeProfitLevel = 0.0; } if ( OrderSend ( Symbol(), OP_BUYSTOP, Lot, _OpenPriceLevel, 5, _StopLossLevel, _TakeProfitLevel, "", _MagicNumber ) < 0 ) { Alert( "OrderSend Error #", GetLastError() ); return(-1); } _OpenPriceLevel = NormalizeDouble(Bid - Luft*Point, Digits); if ( StopLoss > 0 ) { _StopLossLevel = NormalizeDouble( _OpenPriceLevel + StopLoss*Point, Digits ); } else { _StopLossLevel = 0.0; } if ( TakeProfit > 0 ) { _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel - TakeProfit*Point, Digits ); } else { _TakeProfitLevel = 0.0; } if ( OrderSend ( Symbol(), OP_SELLSTOP, Lot, _OpenPriceLevel, 5, _StopLossLevel, _TakeProfitLevel, "", _MagicNumber ) < 0 ) { Alert( "OrderSend Error #", GetLastError() ); return(-1); } return(0); }
现在让我们写出可以简化控制建仓代码的函数,它必须用每个类型的定单进行搜索,然后将这些信息存储在全局变量里,程序如下:
// 在定单特性中的整体变量会被储存: int _BuyTicket = 0, _SellTicket = 0, _BuyStopTicket = 0; int _SellStopTicket = 0, _BuyLimitTicket = 0, _SellLimitTicket = 0; double _BuyLots = 0.0, _SellLots = 0.0, _BuyStopLots = 0.0; double _SellStopLots = 0.0, _BuyLimitLots = 0.0, _SellLimitLots = 0.0; double _BuyOpenPrice = 0.0, _SellOpenPrice = 0.0, _BuyStopOpenPrice = 0.0; double _SellStopOpenPrice = 0.0, _BuyLimitOpenPrice = 0.0, _SellLimitOpenPrice = 0.0; double _BuyStopLoss = 0.0, _SellStopLoss = 0.0, _BuyStopStopLoss = 0.0; double _SellStopStopLoss = 0.0, _BuyLimitStopLoss = 0.0, _SellLimitStopLoss = 0.0; double _BuyTakeProfit = 0.0, _SellTakeProfit = 0.0, _BuyStopTakeProfit = 0.0; double _SellStopTakeProfit = 0.0, _BuyLimitTakeProfit = 0.0, _SellLimitTakeProfit = 0.0; datetime _BuyOpenTime = -1, _SellOpenTime = -1, _BuyStopOpenTime = -1; datetime _SellStopOpenTime = -1, _BuyLimitOpenTime = -1, _SellLimitOpenTime = -1; double _BuyProfit = 0.0, _SellProfit = 0.0, _BuySwap = 0.0, _SellSwap = 0.0; double _BuyCommission = 0.0, _SellCommission = 0.0; string _BuyComment = "", _SellComment = "", _BuyStopComment = ""; string _SellStopComment = "", _BuyLimitComment = "", _SellLimitComment = ""; datetime _BuyStopExpiration = -1, _SellStopExpiration = -1; datetime _BuyLimitExpiration = -1, _SellLimitExpiration = -1; void OneTypeOrdersInit( int magic ) { // 变量归零: _BuyTicket = 0; _SellTicket = 0; _BuyStopTicket = 0; _SellStopTicket = 0; _BuyLimitTicket = 0; _SellLimitTicket = 0; _BuyLots = 0.0; _SellLots = 0.0; _BuyStopLots = 0.0; _SellStopLots = 0.0; _BuyLimitLots = 0.0; _SellLimitLots = 0.0; _BuyOpenPrice = 0.0; _SellOpenPrice = 0.0; _BuyStopOpenPrice = 0.0; _SellStopOpenPrice = 0.0; _BuyLimitOpenPrice = 0.0; _SellLimitOpenPrice = 0.0; _BuyStopLoss = 0.0; _SellStopLoss = 0.0; _BuyStopStopLoss = 0.0; _SellStopStopLoss = 0.0; _BuyLimitStopLoss = 0.0; _SellLimitStopLoss = 0.0; _BuyTakeProfit = 0.0; _SellTakeProfit = 0.0; _BuyStopTakeProfit = 0.0; _SellStopTakeProfit = 0.0; _BuyLimitTakeProfit = 0.0; _SellLimitTakeProfit = 0.0; _BuyOpenTime = -1; _SellOpenTime = -1; _BuyStopOpenTime = -1; _SellStopOpenTime = -1; _BuyLimitOpenTime = -1; _SellLimitOpenTime = -1; _BuyProfit = 0.0; _SellProfit = 0.0; _BuySwap = 0.0; _SellSwap = 0.0; _BuyCommission = 0.0; _SellCommission = 0.0; _BuyComment = ""; _SellComment = ""; _BuyStopComment = ""; _SellStopComment = ""; _BuyLimitComment = ""; _SellLimitComment = ""; _BuyStopExpiration = -1; _SellStopExpiration = -1; _BuyLimitExpiration = -1; _SellLimitExpiration = -1; int _GetLastError = 0, _OrdersTotal = OrdersTotal(); for ( int z = _OrdersTotal - 1; z >= 0; z -- ) { if ( !OrderSelect( z, SELECT_BY_POS ) ) { _GetLastError = GetLastError(); Print("OrderSelect(", z, ",SELECT_BY_POS) - Error #", _GetLastError ); continue; } if ( OrderMagicNumber() == magic && OrderSymbol() == Symbol() ) { switch ( OrderType() ) { case OP_BUY: _BuyTicket = OrderTicket(); _BuyLots = NormalizeDouble( OrderLots(), 1 ); _BuyOpenPrice = NormalizeDouble( OrderOpenPrice(), Digits ); _BuyStopLoss = NormalizeDouble( OrderStopLoss(), Digits ); _BuyTakeProfit = NormalizeDouble( OrderTakeProfit(), Digits ); _BuyOpenTime = OrderOpenTime(); _BuyProfit = NormalizeDouble( OrderProfit(), 2 ); _BuySwap = NormalizeDouble( OrderSwap(), 2 ); _BuyCommission = NormalizeDouble( OrderCommission(), 2 ); _BuyComment = OrderComment(); break; case OP_SELL: _SellTicket = OrderTicket(); _SellLots = NormalizeDouble( OrderLots(), 1 ); _SellOpenPrice = NormalizeDouble( OrderOpenPrice(), Digits ); _SellStopLoss = NormalizeDouble( OrderStopLoss(), Digits ); _SellTakeProfit = NormalizeDouble( OrderTakeProfit(), Digits ); _SellOpenTime = OrderOpenTime(); _SellProfit = NormalizeDouble( OrderProfit(), 2 ); _SellSwap = NormalizeDouble( OrderSwap(), 2 ); _SellCommission = NormalizeDouble( OrderCommission(), 2 ); _SellComment = OrderComment(); break; case OP_BUYSTOP: _BuyStopTicket = OrderTicket(); _BuyStopLots = NormalizeDouble( OrderLots(), 1 ); _BuyStopOpenPrice = NormalizeDouble( OrderOpenPrice(), Digits ); _BuyStopStopLoss = NormalizeDouble( OrderStopLoss(), Digits ); _BuyStopTakeProfit = NormalizeDouble( OrderTakeProfit(), Digits ); _BuyStopOpenTime = OrderOpenTime(); _BuyStopComment = OrderComment(); _BuyStopExpiration = OrderExpiration(); break; case OP_SELLSTOP: _SellStopTicket = OrderTicket(); _SellStopLots = NormalizeDouble( OrderLots(), 1 ); _SellStopOpenPrice = NormalizeDouble( OrderOpenPrice(), Digits ); _SellStopStopLoss = NormalizeDouble( OrderStopLoss(), Digits ); _SellStopTakeProfit = NormalizeDouble( OrderTakeProfit(), Digits ); _SellStopOpenTime = OrderOpenTime(); _SellStopComment = OrderComment(); _SellStopExpiration = OrderExpiration(); break; case OP_BUYLIMIT: _BuyLimitTicket = OrderTicket(); _BuyLimitLots = NormalizeDouble( OrderLots(), 1 ); _BuyLimitOpenPrice = NormalizeDouble( OrderOpenPrice(), Digits ); _BuyLimitStopLoss = NormalizeDouble( OrderStopLoss(), Digits ); _BuyLimitTakeProfit = NormalizeDouble( OrderTakeProfit(), Digits ); _BuyLimitOpenTime = OrderOpenTime(); _BuyLimitComment = OrderComment(); _BuyLimitExpiration = OrderExpiration(); break; case OP_SELLLIMIT: _SellLimitTicket = OrderTicket(); _SellLimitLots = NormalizeDouble( OrderLots(), 1 ); _SellLimitOpenPrice = NormalizeDouble( OrderOpenPrice(), Digits ); _SellLimitStopLoss = NormalizeDouble( OrderStopLoss(), Digits ); _SellLimitTakeProfit = NormalizeDouble( OrderTakeProfit(), Digits ); _SellLimitOpenTime = OrderOpenTime(); _SellLimitComment = OrderComment(); _SellLimitExpiration = OrderExpiration(); break; } } } }
现在我们将函数用到智能交易程序中:
extern int _MagicNumber = 1123; extern double Lot = 0.1; extern int StopLoss = 60; // 止损点的间距(0 - d无) extern int TakeProfit = 100; // 赢利点的间距 (0 - 无) extern int TrailingStop = 50; //追踪止损点 (0 - 无) extern int Luft = 20; // 挂单交易放置水平的间距 #include <OneTypeOrdersControl.mq4> int start() { int _GetLastError = 0; //---- 记住开仓的参量(如果可用) OneTypeOrdersInit( _MagicNumber ); //---- 如果我们两个都是挂单交易,退出 //---- 等待他们开启 if ( _BuyStopTicket > 0 && _SellStopTicket > 0 ) return(0); //---- 如果 BUY 仓位开仓 if ( _BuyTicket > 0 ) { //---- 如果SellStop 还没有删除,删除它: if ( _SellStopTicket > 0 ) { if ( !OrderDelete( _SellStopTicket ) ) { Alert( "OrderDelete 错误#", GetLastError() ); return(-1); } } //---- 检测止损被移动: //---- 如果追踪止损不是很小, if ( TrailingStop > MarketInfo( Symbol(), MODE_STOPLEVEL ) ) { //---- 如果赢利仓位超过追踪止损点, if ( NormalizeDouble( Bid - _BuyOpenPrice, Digits ) > NormalizeDouble( TrailingStop*Point, Digits ) ) { //---- 如果新止损水平超过当前仓位 //---- (或者当前仓位没有止损), if(NormalizeDouble( Bid - TrailingStop*Point, Digits ) > _BuyStopLoss || _BuyStopLoss <= 0.0 ) { //---- 修改定单 if ( !OrderModify( _BuyTicket, _BuyOpenPrice, NormalizeDouble( Bid - TrailingStop*Point, Digits ), _BuyTakeProfit, 0 ) ) { Alert( "OrderModify 错误#", GetLastError() ); return(-1); } } } } //---- 如果没有开仓仓位,退出,无事可做 return(0); } //---- 这个单元格与BUY仓位的单元格相似 //---- 这就是我们不能做标注的原因... if ( _SellTicket > 0 ) { if ( _BuyStopTicket > 0 ) { if ( !OrderDelete( _BuyStopTicket ) ) { Alert( "OrderDelete错误 #", GetLastError() ); return(-1); } } if(TrailingStop > MarketInfo( Symbol(), MODE_STOPLEVEL)) { if(NormalizeDouble( _SellOpenPrice - Ask, Digits ) > NormalizeDouble( TrailingStop*Point, Digits ) ) { if(NormalizeDouble( Ask + TrailingStop*Point, Digits ) < _SellStopLoss || _SellStopLoss <= 0.0 ) { if(!OrderModify( _SellTicket, _SellOpenPrice, NormalizeDouble( Ask + TrailingStop*Point, Digits ), _SellTakeProfit, 0 ) ) { Alert( "OrderModify Error #", GetLastError() ); return(-1); } } } } return(0); }
5. 总结
最后,我想来比较一下使用函数与否在搜索定单时的速度。为此,我们用相同的版本来连续测试 “Every tick” 模式10次(用_MagicNumber最优化),用 MetaTrader 软件来计算时间 — 时间时自己计算的。
结果如下:
智能交易 |
10 测试的时间 (mm:ss) |
CrossMACD_beta
|
07:42 |
CrossMACD |
11:37 |
DoublePending_beta
|
08:18 |
DoublePending |
09:42 |
【版权声明】
本文仅代表作者观点,不代表本站立场。Fx263.com对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证,且不构成任何投资建议,请读者仅作参考,并自行承担全部风险与责任。Fx263.com作为信息内容发布平台,页面展示内容的目的在于传播更多信息,不代表Fx263.com立场;本站会员及自媒体人所发的稿件所载明的信息与本网无关,如文章涉及版权,请联系本站处理。
【风险提示】
请通过正规渠道参与外汇保证金交易。目前通过网络平台提供、参与外汇保证金交易均属非法。请提高意识,谨防损失!外汇、贵金属和差价合约(OTC场外交易)是杠杆产品,存在较高的风险,可能会导致亏损您的投资本金,请理性投资。