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

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

image.png

注意要选择如下组件安装

image.png

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


image.png
image.png

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

image.png

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


image.png

3.3 调试正常

image.png

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

bool satifyOpenBuy()
  {
   bool result=false;
   if(h4_rates[0].low<h4_bollLow[0] && m30_fast[0]>m30_slow[0] && m30_kdj_main[0]>m30_kdj_signal[0] && m30_kdj_main[1]<m30_kdj_signal[1])
     {
      result=true;
     }
   return result;
  }

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

#include <vector>
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<MqlRates> v_h4_rates(h4_rates, h4_rates + arrSize);
       reverse(v_h4_rates.begin(), v_h4_rates.end());
       vector<double> v_h4_bollLow(h4_bollLow, h4_bollLow + arrSize);
       reverse(v_h4_bollLow.begin(), v_h4_bollLow.end());
       vector<double> v_m30_fast(m30_fast, m30_fast + arrSize);
       reverse(v_m30_fast.begin(), v_m30_fast.end());
       vector<double> v_m30_slow(m30_slow, m30_slow + arrSize);
       reverse(v_m30_slow.begin(), v_m30_slow.end());
       vector<double> v_m30_kdj_main(m30_kdj_main, m30_kdj_main + arrSize);
       reverse(v_m30_kdj_main.begin(), v_m30_kdj_main.end());
       vector<double> 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].low<v_h4_bollLow[0] && v_m30_fast[0]>v_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 <vector>
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<double> v_aArr(aArr, aArr + aArrSize);
       reverse(v_aArr.begin(), v_aArr.end());
       double aSum = 0;
       for (int i = 0;i<aArrSize;i++)
       {
              aSum = aSum + aArr[i];
       }
       double bSum = 0;
       for (int i = 0;i<bArrSize;i++)
       {
              bSum = bSum + bArr[i];
       }
       for (int i = 0;i<cArrSize;i++)
       {
       }
       return(v_aArr[0]);
}
//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<MqlRates> v_h4_rates(h4_rates, h4_rates + arrSize);
       reverse(v_h4_rates.begin(), v_h4_rates.end());
       vector<double> v_h4_bollLow(h4_bollLow, h4_bollLow + arrSize);
       reverse(v_h4_bollLow.begin(), v_h4_bollLow.end());
       vector<double> v_m30_fast(m30_fast, m30_fast + arrSize);
       reverse(v_m30_fast.begin(), v_m30_fast.end());
       vector<double> v_m30_slow(m30_slow, m30_slow + arrSize);
       reverse(v_m30_slow.begin(), v_m30_slow.end());
       vector<double> v_m30_kdj_main(m30_kdj_main, m30_kdj_main + arrSize);
       reverse(v_m30_kdj_main.begin(), v_m30_kdj_main.end());
       vector<double> 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].low<v_h4_bollLow[0] && v_m30_fast[0]>v_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 <wz\Trade.mqh>
#include <wz\Kline.mqh>

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].low<h4_bollLow[0] && m30_fast[0]>m30_slow[0] && m30_kdj_main[0]>m30_kdj_signal[0] && m30_kdj_main[1]<m30_kdj_signal[1])
     {
      result=true;
     }
   return result;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool satifyCloseBuy()
  {
   bool result=false;
   if(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_slow[0] && m30_kdj_main[0]<m30_kdj_signal[0] && m30_kdj_main[1]>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]<m30_kdj_signal[1])
     {
      result=true;
     }
   return result;
  }
//+------------------------------------------------------------------+

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容