新版MQL语言程序设计:通用且灵活的多功能平仓函数的设计与代码实现

平仓函数的重写设计与代码实现

  • MT4与MT5提供的交易函数只有简单的接口,不能适应快速开发。
  • 交易策略需要按仓位类型,按产品符号,按魔术编号,按仓位注释等多功能多条件的平仓。
  • 将所有平仓条件抽象成为函数的参数,封装成为一个通用的跨平台的平仓函数
  • 代码实现如下:

// 定义常量
#define _Deviation  50

// 定义订单遍历宏,实现跨平台编译
#ifdef __MQL4__
#define ForEachPositionDown(i) for (int i=OrdersTotal()-1; i>=0; i--)
#endif
#ifdef __MQL5__
#define ForEachPositionDown(i) for (int i=PositionsTotal()-1; i>=0; i--)
#endif

// 根据指定魔术编号数组,产品符合数组,订单订单注释数组平仓多头仓位
// 本函数为通用函数,兼容MT4与MT5平台
// 数组为空的时,默认全局,如此便实现了各种条件的组合筛选
bool BuyClose(ulong &magic[], string &symbol[], string &comment[]) export
{
    bool ret = true;
    // 从最新时间到过去,遍历所有的仓位
    ForEachPositionDown(i)
    {
        // 根据索引选择仓位
        if ( CheckPositionSelectedByPos(i) )
        {
            // 判断是否符合魔术编号匹配,不符合返回继续循环
            if ( !CheckPositionSelectedMagic(magic) )     continue;

            // 判断是否符合产品符号匹配,不符合返回继续循环
            if ( !CheckPositionSelectedSymbol(symbol) )   continue;

            // 判断是否符合产品符号匹配,不符合返回继续循环
            if ( !CheckPositionSelectedComment(comment) ) continue;
            
            // 判断是否选择了多头仓位
            if ( !CheckSelectedBuy() ) continue;

            // 以上条件全部符合以后,执行仓位平仓,将执行结果保存ret变量
            // 只有所有符合条件的仓位全部平仓,ret的结果为true,否则false
            ret = ret && SelectedPositionClose();
        }
    }
    //
    return (ret);
}
// 筛选仓位是否符合魔术编号数组
// 通用MT4和MT5函数,可跨平台编译
bool CheckPositionSelectedMagic(ulong &magic[]) export
{
    int arr_len = ArraySize(magic);
    if (arr_len == 0) return (true);
#ifdef __MQL4__
    if (MathQuery(magic, OrderMagicNumber()) == -1) return (false);
#endif
#ifdef __MQL5__
    ulong pos_magic = PositionGetInteger(POSITION_MAGIC);
    if (MathQuery(magic, pos_magic) == -1) return (false);
#endif
    return (true);
}
// 筛选仓位是否符合产品符号数组
// 通用MT4和MT5函数,可跨平台编译
bool CheckPositionSelectedSymbol(string &symbol[]) export
{
    int arr_len = ArraySize(symbol);
    if (arr_len == 0) return (true);
    string sym = "";
#ifdef __MQL4__
    sym = ::OrderSymbol();
#endif
#ifdef __MQL5__
    sym = ::PositionGetString(POSITION_SYMBOL);
#endif
    //
    if (!ArrayContains(symbol, sym)) return (false);
    return (true);
}
// 筛选仓位是否符合订单注释数组
// 通用MT4和MT5函数,可跨平台编译
bool CheckPositionSelectedComment(string &comment[]) export
{
    int arr_len = ArraySize(comment);
    if (arr_len == 0) return (true);
    // 检查仓位注释是否在筛选的注释数组中
    if (!ArrayContains(comment, SelectedPositionComment())) return (false);
    return (true);
}
// 判断选择的是不是多单,跨平台编译MT4与MT5函数
bool CheckSelectedBuy(void) export
{
#ifdef __MQL4__
    if (OrderType() != OP_BUY) return (false);
#endif
#ifdef __MQL5__
    ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); 
    if (type != POSITION_TYPE_BUY) return (false);
#endif
    return (true);
}
// 平仓指定选择的仓位
int SelectedPositionClose(void) export
{
#ifdef __MQL4__
    double close_price;
    if (OrderType() == OP_BUY) 
        close_price = SymbolInfoDouble(OrderSymbol(), SYMBOL_BID);
    else if (OrderType() == OP_SELL)
        close_price = SymbolInfoDouble(OrderSymbol(), SYMBOL_ASK);
    else 
        return (-1);
    if ( !OrderClose(OrderTicket(), OrderLots(), close_price, _Deviation, clrNONE) )
    {
        Print("OrderClose failed with error #", GetLastError()); 
        return (0);
    }
#endif
#ifdef __MQL5__
    MqlTradeRequest request;
    MqlTradeResult  result;
    ZeroMemory(request);
    ZeroMemory(result);
    ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); 
    string symbol     = PositionGetString(POSITION_SYMBOL);
    request.action    = TRADE_ACTION_DEAL;
    request.position  = PositionGetInteger(POSITION_TICKET);
    request.symbol    = symbol;
    request.volume    = PositionGetDouble(POSITION_VOLUME);
    request.deviation = _Deviation;
    //
    if (type == POSITION_TYPE_BUY)
    {
        request.price = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_BID);
        request.type  = ORDER_TYPE_SELL;
    }
    if (type == POSITION_TYPE_SELL)
    {
        request.price = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_ASK);
        request.type  = ORDER_TYPE_BUY;
    }
    if ( !FillingCheck(symbol, request, result) ) return (0);
    //
    if (!OrderSend(request, result))
    {
        PrintFormat( "OrderSend error %d", GetLastError() );
        PrintFormat("retcode=%u  deal=%I64u  order=%I64u", result.retcode, result.deal, result.order);
        return (0);
    }
#endif
    return (1);
}

SellClose 函数的设计思想与以上相同,这里不再代码演示
注意里面部分被调用的函数在前面的文章中已经展示,这里不再写出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迈达量化

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值