MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)

2017/5/7
MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)
一.安装dll开发工具 visual studio 2017 (enterprise)

MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第1张图片
image.png

注意要选择如下组件安装

MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第2张图片
image.png

2.创建如下类型的dll项目


MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第3张图片
image.png
MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第4张图片
image.png

3.开始写代码
3.1注意编译成64位的(MT5是64位的),已经将需要使用的函数在如下文件公共出来

MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第5张图片
image.png

3.2,将生成好的dll文件放入mt5中


MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第6张图片
image.png

3.3 调试正常

MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密)_第7张图片
image.png

4.替换EA里面的 满足多单开单函数
4.1 mt5函数

bool satifyOpenBuy()
  {
   bool result=false;
   if(h4_rates[0].lowm30_slow[0] && m30_kdj_main[0]>m30_kdj_signal[0] && m30_kdj_main[1]

4.2替换后c++函数(注意序列化不支持,需要dll函数里面自己处理)

#include 
using namespace std;

//2.入栈出栈
#pragma pack(push,1)
struct MqlRates
{
       __int64     time;         // 周期开始时间
       double   open;         // 开盘价
       double   high;         // 周期最高价
       double   low;          // 周期最低价
       double   close;        // 收盘价
       unsigned __int64     tick_volume;  // 订单交易量
       int      spread;       // 点差
       unsigned __int64     real_volume;  // 交易量
};
#pragma pack(pop)
//bool satifyOpenBuy(MqlRates &h4_rates[], double &h4_bollLow[], double &m30_fast[], double &m30_slow[], double &m30_kdj_main[], double &m30_kdj_signal[], int arrSize);
extern "C" BOOL PASCAL EXPORT satifyOpenBuy(MqlRates *h4_rates, double *h4_bollLow, double *m30_fast, double *m30_slow, double *m30_kdj_main, double *m30_kdj_signal, int arrSize)
{
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       vector v_h4_rates(h4_rates, h4_rates + arrSize);
       reverse(v_h4_rates.begin(), v_h4_rates.end());
       vector v_h4_bollLow(h4_bollLow, h4_bollLow + arrSize);
       reverse(v_h4_bollLow.begin(), v_h4_bollLow.end());
       vector v_m30_fast(m30_fast, m30_fast + arrSize);
       reverse(v_m30_fast.begin(), v_m30_fast.end());
       vector v_m30_slow(m30_slow, m30_slow + arrSize);
       reverse(v_m30_slow.begin(), v_m30_slow.end());
       vector v_m30_kdj_main(m30_kdj_main, m30_kdj_main + arrSize);
       reverse(v_m30_kdj_main.begin(), v_m30_kdj_main.end());
       vector v_m30_kdj_signal(m30_kdj_signal, m30_kdj_signal + arrSize);
       reverse(v_m30_kdj_signal.begin(), v_m30_kdj_signal.end());
       BOOL a = FALSE;
       if (v_h4_rates[0].lowv_m30_slow[0] && v_m30_kdj_main[0] > v_m30_kdj_signal[0] && v_m30_kdj_main[1] < v_m30_kdj_signal[1])
       {
              a = TRUE;
       }
       else
       {
              a = FALSE;
       }
       return(a);
}

4.3 别忘了将函数公开出来

5.完整代码如下 (注意序列化不支持,需要dll函数里面自己处理)
5.1//testMT5Dll.def

; testMT5Dll.def : 声明 DLL 的模块参数。
LIBRARY
EXPORTS
    ; 此处可以是显式导出
add
getString
arrDeal
satifyOpenBuy

5.2// testMT5Dll.cpp

// testMT5Dll.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "testMT5Dll.h"
#include 
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//2.入栈出栈
#pragma pack(push,1)
struct MqlRates
{
       __int64     time;         // 周期开始时间
       double   open;         // 开盘价
       double   high;         // 周期最高价
       double   low;          // 周期最低价
       double   close;        // 收盘价
       unsigned __int64     tick_volume;  // 订单交易量
       int      spread;       // 点差
       unsigned __int64     real_volume;  // 交易量
};
#pragma pack(pop)
//
//TODO:  如果此 DLL 相对于 MFC DLL 是动态链接的,
//            则从此 DLL 导出的任何调入
//            MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
//            该函数的最前面。
//
//            例如:
//
//            extern "C" BOOL PASCAL EXPORT ExportedFunction()
//            {
//                   AFX_MANAGE_STATE(AfxGetStaticModuleState());
//                   // 此处为普通函数体
//            }
//
//            此宏先于任何 MFC 调用
//            出现在每个函数中十分重要。  这意味着
//            它必须作为函数中的第一个语句
//            出现,甚至先于所有对象变量声明,
//            这是因为它们的构造函数可能生成 MFC
//            DLL 调用。
//
//            有关其他详细信息,
//            请参阅 MFC 技术说明 33 和 58。
//
// CtestMT5DllApp
BEGIN_MESSAGE_MAP(CtestMT5DllApp, CWinApp)
END_MESSAGE_MAP()
// CtestMT5DllApp 构造
CtestMT5DllApp::CtestMT5DllApp()
{
       // TODO:  在此处添加构造代码,
       // 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CtestMT5DllApp 对象
CtestMT5DllApp theApp;
// CtestMT5DllApp 初始化
BOOL CtestMT5DllApp::InitInstance()
{
       CWinApp::InitInstance();
       return TRUE;
}
//double add(double a,double b);
extern "C" double PASCAL EXPORT add(double a, double b)
{
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       // 此处为普通函数体
       return a + b;
}
//string getString(string  str);
extern "C" WCHAR* PASCAL EXPORT getString(WCHAR*  str)
{
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       return(str);
}
//double  arrDeal(double &aArr[],int arrSize,int &bArr[],int bArrSize,string &cArr[],int cArrSize);
extern "C" double PASCAL EXPORT arrDeal(double *aArr, int aArrSize, int *bArr, int bArrSize, WCHAR* *cArr, int cArrSize)
{
       AFX_MANAGE_STATE(AfxGetStaticModuleState());
       //1.倒叙
       vector v_aArr(aArr, aArr + aArrSize);
       reverse(v_aArr.begin(), v_aArr.end());
       double aSum = 0;
       for (int i = 0;i v_h4_rates(h4_rates, h4_rates + arrSize);
       reverse(v_h4_rates.begin(), v_h4_rates.end());
       vector v_h4_bollLow(h4_bollLow, h4_bollLow + arrSize);
       reverse(v_h4_bollLow.begin(), v_h4_bollLow.end());
       vector v_m30_fast(m30_fast, m30_fast + arrSize);
       reverse(v_m30_fast.begin(), v_m30_fast.end());
       vector v_m30_slow(m30_slow, m30_slow + arrSize);
       reverse(v_m30_slow.begin(), v_m30_slow.end());
       vector v_m30_kdj_main(m30_kdj_main, m30_kdj_main + arrSize);
       reverse(v_m30_kdj_main.begin(), v_m30_kdj_main.end());
       vector v_m30_kdj_signal(m30_kdj_signal, m30_kdj_signal + arrSize);
       reverse(v_m30_kdj_signal.begin(), v_m30_kdj_signal.end());
       BOOL a = FALSE;
       if (v_h4_rates[0].lowv_m30_slow[0] && v_m30_kdj_main[0] > v_m30_kdj_signal[0] && v_m30_kdj_main[1] < v_m30_kdj_signal[1])
       {
              a = TRUE;
       }
       else
       {
              a = FALSE;
       }
       return(a);
}

5.3 替换后EA代码testDllEA.mq5

//+------------------------------------------------------------------+
//|                                                    testDllEA.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#import "testMT5Dll.dll"
double add(double a,double b);
string getString(string  str);
double  arrDeal(double &aArr[],int arrSize,int &bArr[],int bArrSize,string &cArr[],int cArrSize);
bool satifyOpenBuy(MqlRates &h4_rates[], double &h4_bollLow[], double &m30_fast[], double &m30_slow[], double &m30_kdj_main[], double &m30_kdj_signal[], int arrSize);
#import

#include 
#include 

input int magic=170501;
input double lots=0.1;//开单量
input int slPoint=200;//止损点数
input int tpPoint=200;//止盈点数
input int fast_period=5;//小均线周期
input int slow_period=10;//大均线周期
input int boll_period=20;//布林带周期
input double boll_deviations=2;//布林带偏差
input int kdj_kPeriod=5;//KDJ K period
input int kdj_dPeriod=3;//KDJ D period
input int kdj_jPeriod=3;//KDJ J period

Trade td;//交易对象
Kline kl;//行情对象
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//为了函数间可以访问数组,声明生全局变量(注意指标里面都做过倒序处理)
//1.定义获取指标数据的数组
//数据索引最大是1,所有只需要获取2个值即可
int count=2;
double m30_fast[];
double m30_slow[];

double h4_fast[];
double h4_slow[];

double m30_bollUp[],m30_bollLow[],m30_bollMid[];
double h4_bollUp[],h4_bollLow[],h4_bollMid[];

double m30_kdj_main[],m30_kdj_signal[];
double h4_kdj_main[],h4_kdj_signal[];

MqlRates m30_rates[];
MqlRates h4_rates[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//2.获取指标值
   kl.MA(m30_fast,count,Symbol(),PERIOD_M30,fast_period,0,MODE_SMA,PRICE_CLOSE);
   kl.MA(m30_slow,count,Symbol(),PERIOD_M30,slow_period,0,MODE_SMA,PRICE_CLOSE);

   kl.MA(h4_fast,count,Symbol(),PERIOD_H4,fast_period,0,MODE_SMA,PRICE_CLOSE);
   kl.MA(h4_slow,count,Symbol(),PERIOD_H4,slow_period,0,MODE_SMA,PRICE_CLOSE);

   kl.Bands(m30_bollUp,m30_bollLow,m30_bollMid,count,Symbol(),PERIOD_M30,boll_period,0,boll_deviations,PRICE_CLOSE);
   kl.Bands(h4_bollUp,h4_bollLow,h4_bollMid,count,Symbol(),PERIOD_H4,boll_period,0,boll_deviations,PRICE_CLOSE);

   kl.Stochastic(m30_kdj_main,m30_kdj_signal,count,Symbol(),PERIOD_M30,kdj_kPeriod,kdj_dPeriod,kdj_jPeriod,MODE_SMA,STO_LOWHIGH);
   kl.Stochastic(h4_kdj_main,h4_kdj_signal,count,Symbol(),PERIOD_H4,kdj_kPeriod,kdj_dPeriod,kdj_jPeriod,MODE_SMA,STO_LOWHIGH);

   kl.getRates(m30_rates,count,Symbol(),PERIOD_M30);
   kl.getRates(h4_rates,count,Symbol(),PERIOD_H4);

//3.条件判断进行开仓和平仓
/*if(satifyOpenBuy())
     {
      td.buyPlus(Symbol(),lots,slPoint,tpPoint,Symbol()+"buy",magic);
     }*/
//3.1 用dll函数实现satifyOpenBuy
   if(satifyOpenBuy(h4_rates,h4_bollLow,m30_fast,m30_slow,m30_kdj_main,m30_kdj_signal,count)==true)
     {
      td.buyPlus(Symbol(),lots,slPoint,tpPoint,Symbol()+"buy",magic);
     }
   /*if(satifyCloseBuy())
     {
      td.closeAllBuy(Symbol(),magic);
     }
   if(satifyOpenSell())
     {
      td.sellPlus(Symbol(),lots,slPoint,tpPoint,Symbol()+"sell",magic);
     }
   if(satifyCloseSell())
     {
      td.closeAllSell(Symbol(),magic);
     }*/
  }
//+------------------------------------------------------------------+
bool satifyOpenBuy()
  {
   bool result=false;
   if(h4_rates[0].lowm30_slow[0] && m30_kdj_main[0]>m30_kdj_signal[0] && m30_kdj_main[1]m30_kdj_signal[1])
     {
      result=true;
     }
   return result;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool satifyOpenSell()
  {
   bool result=false;
   if(h4_rates[0].high>h4_bollUp[0] && m30_fast[0]m30_kdj_signal[1])
     {
      result=true;
     }
   return result;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool satifyCloseSell()
  {
   bool result=false;
   if(m30_kdj_main[0]>m30_kdj_signal[0] && m30_kdj_main[1]

如果您发现本文对你有所帮助,如果您认为其他人也可能受益,请把它分享出去。

你可能感兴趣的:(MT5入门到精通之十七(动态链接库,使用windows系统自带函数功能或用于加密))