MT4-程序的基本结构

使用MQ4语言编制自动交易系统的基本知识.


Title 编制自动交易系统的基本知识
一个交易系统大致包括以下几个方面:

1 开仓策略,即什么条件满足时开仓, 如某条线和某条线上交叉或下交叉,

2 平仓策略,即什么条件满足时平仓, 包括止赢设置,止损设置,和跟踪止赢设置三个方面.

3 资金管理, 其中一个方面就是下单的大小

4 时间管理, 如持仓时间,开平仓时间间隔等

5 账户状态分析,如交易历史,当前资金/仓位/各仓为盈亏状态等.


当然一个交易系统不必包括全部内容,本文做为入门知识也仅通过实例介绍交易系统程序的基本构成.
-------------
//+------------------------------------------------------------------+
//|                          Designed by OKwh, China              |
//|                  Copyright 2007, OKwh Dxdcn                    |
//|                                blog.sina/FXTrade |
//+------------------------------------------------------------------+
#property  copyright "Copyright 2007 , Dxd, China."
#property  link      "blog.sina/FXTrade ,  www.mql4/users/DxdCn"
#define MAGICMA 200610011231
//+------------------------------------------------------------------+
//| 注意没有指标文件那些property                  |
/
/+------------------------------------------------------------------+
extern int whichmethod = 1;  //1~4 种下单方式  1 仅开仓, 2 有止损无止赢, 3 有止赢无止损, 4 有止赢也有止损
extern double TakeProfit = 100;  //中国校园网止赢点数
extern  double StopLoss = 20;    //止损点数
extern double MaximumRisk    = 0.3; //资金控制,控制下单量
extern double TrailingStop =25;    //跟踪止赢点数设置
extern  int maxOpen = 3;  //最多开仓次数限制
extern  int maxLots = 5;  //最多单仓持仓量限制
extern int bb = 0;      //非零就允许跟踪止赢
extern double MATrendPeriod=26;//使用26均线 开仓条件参数  本例子

int i, p2, xxx,p1, res;
double Lots;
datetime lasttime;      //时间控制, 仅当一个时间周期完成才检查条件
int init()  //初始化
{
Lots = 1;
lasttime = NULL;
return(0);
}
int deinit() { return(0); } //反初始化
//主程序
int start()
{
CheckForOpen();    //开仓 平仓 条件检查 和操作
if (bb>0)  CTP();  //跟踪止赢
return(0);
}
//+------下面是各子程序--------------------------------------------+
double LotsOptimized()  //确定下单量,开仓调用 资金控制
{
double lot=Lots;
int  orders=HistoryTotal();  // history orders total
int  losses=0;            // number of losses orders without a break
//MarketInfo(Symbol(),MODE_MINLOT);    相关信息
//MarketInfo(Symbol(),MODE_MAXLOT);
//MarketInfo(Symbol(),MODE_LOTSTEP);
lot=NormalizeDouble(MaximumRisk * AccountBalance()/AccountLeverage(),1);    //开仓量计算
if(lot<0.1) lot=0.1;
if(lot>maxLots) lot=maxLots;
return(lot);
}
 
/
/平仓持有的买单
void CloseBuy()
{
if (OrdersTotal( ) > 0 ) 
{
  for(i=OrdersTotal()-1;i>=0;i--)
  {
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)    break;
  if(OrderType()==OP_BUY)
  {
    OrderClose(OrderTicket(),OrderLots(),Bid,3,White);
    Sleep(5000);
  }
  }
}
}
//平仓持有的卖单
void CloseSell()
{
if (OrdersTotal( ) > 0 ) 
{
  for(i=OrdersTotal()-1;i>=0;i--)
  {
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)    break;
  if(OrderType()==OP_SELL)
    {
    OrderClose(OrderTicket(),OrderLots(),Ask,3,White);
    Sleep(5000);
    }
  }
}
}
//判断是否买或卖或平仓
int buyorsell()  //在这个函数计算设置你的交易信号  这里使用MACD MA 做例子
{
  double MacdCurrent, MacdPrevious, SignalCurrent;
  double SignalPrevious, MaCurrent, MaPrevious;
  MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
  MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
  SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
  SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
  MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0);
  MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1);
if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious
    && MaCurrent>MaPrevious)
  return (1); // Ma在上升,Macd0线上,并且两线上交叉
if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious
    && MaCurrent<MaPrevious)
  return (-1); //
return (0); //不交易
}
int nowbuyorsell = 0;
void CheckForOpen()
{
if (Time[0] == lasttime ) return; //每时间周期检查一次  时间控制
lasttime = Time[0];
nowbuyorsell = buyorsell(); //获取买卖信号

if (nowbuyorsell == 1) //买 先结束已卖的
  CloseSell();
if (nowbuyorsell == -1) //卖 先结束已买的
    CloseBuy();
if (TimeDayOfWeek(CurTime()) == 1)
  {
  if (TimeHour(CurTime()) < 3 ) return; //周一早8点前不做 具体决定于你的时区和服务器的时区  时间控制
  }
if (TimeDayOfWeek(CurTime()) == 5)
  {
  if (TimeHour(CurTime()) > 19 ) return; //周五晚11点后不做
  }

if (OrdersTotal( ) >= maxOpen) return ; 
//如果已持有开仓次数达到最大,不做
if (nowbuyorsell==0) return;  //不交易
TradeOK();  //去下单交易
}
void TradeOK()  //去下单交易
{
int error ;
if (nowbuyorsell == 1) //
  {
    switch (whichmethod)
    {
    case 1:  res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);break;
    case 2:  res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,0,"",MAGICMA,0,Blue); break;
    case 3:  res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);break;
    case 4:  res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,Ask-StopLoss*Point,Ask+TakeProfit*Point,"",MAGICMA,0,Blue);break;
    default : res=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"",MAGICMA,0,Blue);break;
    }
    if (res <=0)
    {
    error=GetLastError();
    if(error==134)Print("Received 134 Error after OrderSend() !! ");        // not enough money
    if(error==135) RefreshRates();  // prices have changed
    }
    Sleep(5000);
    return ; 
  }
if (nowbuyorsell == -1) //
  {
    switch (whichmethod)
    {
    case 1:  res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); break;
爆破试验    case 2:  res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,0,"",MAGICMA,0,Red); break;
    case 3:  res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,Bid-TakeProfit*Point,"",MAGICMA,0,Red); break;
    case 4:  res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,Bid+StopLoss*Point,Bid-TakeProfit*Point,"",MAGICMA,0,Red); break;
    default : res=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"",MAGICMA,0,Red); break;
    }
    if (res <=0)
    {
    error=GetLastError();
    if(error==134) Print("Received 134 Error after OrderSend() !! ");        // not enough money
    if(error==135) RefreshRates();  // prices have changed
    }
    Sleep(5000);
    return ; 
  }
}
void CTP()  //跟踪止赢
{
bool bs = false;
for (int i = 0; i < OrdersTotal(); i++)
{
  if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)    break;
  if (OrderType() == OP_BUY)
  {
    if ((Bid - OrderOpenPrice()) > (TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT)))    //开仓价格 当前止损和当前价格比较判断是否要修改跟踪止赢设置
    {
    if (OrderStopLoss() < Bid - TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT))
    {
      bs = OrderModify(OrderTicket(), OrderOpenPrice(), Bid - TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Green);
于慧光    }
    }
  }
  else if (OrderType() == OP_SELL)
  {
    if ((OrderOpenPrice() - Ask) > (TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT)))  //开仓价格 当前止损和当前价格比较判断是否要修改跟踪止赢设置

    {
    if ((OrderStopLoss()) > (Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT)))
    {   
      bs = OrderModify(OrderTicket(), OrderOpenPrice(),
        Ask + TrailingStop * MarketInfo(OrderSymbol(), MODE_POINT), OrderTakeProfit(),0, Tan);
}
    }
  }
}
}
--------------
建议采用的EA逻辑
前提:制作常用函数库
1、仓位状态函数:判断仓位并输出持仓方向和持仓单Ticket号码
2、平仓函数:
3、入场条件计算函数
4、出场条件计算函数
EA建议逻辑图:
---------------
Start函数中
执行仓位状态函数
如果空仓
    入场条件计算函数
            满足多头条件则执行多头入场操作
            满足空头条件---则执行空头入场操作
    入场条件都不满足,直接返回
如果持仓
        根据持仓状态处理
        多单持仓----计算多单出场函数
        如果满足 则执行出场
        如果不满足,则直接返回
        空单持仓----计算空单出场函数
        如果满足 则执行出场
        如果不满足,则直接返回
------------------
  MT4大型浮雕作为一门语言包含的内容相当多,不过它基本上是与C语言类似,如果你学过C或者VB之类的基础编程,理解起来不是太难,在这里想短篇幅幅搞清楚所有MT4的语法似乎不太可能,建议大家不要想一口吃个胖子,MT4的基本语法在以后说明,更深入的部分将以还是在实际编程中逐步解决。
MT4程序基本结构一般从上到下包括4个部分(当然有些部分的位置是可以颠倒的,MT4是根据函数名字来寻,而不是根据位置)。按照一般的方便查看的结构程序设计原则,MT4从上到下的组成是:
第一部分:头代码部分
这里可以放置当前程序的属性,以及一些外部调用,同时在这里可以设置技术文件运行时可以改动的参数定义部分。
指标属性的设置一般每一行都用#property开头,后面是具体某个属性的设定,
例如:
#property indicator_chart_window 就表示当前指标运行的时候所显示的图线是放置在K线主图里面的
#property indicator_separate_window就表示当前指标运行的时候所显示的图线是放置在K线下面的独立附图里面的
#property indicator_buffers 4 表示本指标将会使用4条线,所以在这里用语句进行初始化设定
#property indicator_color1 Blue 表示第一条指标线是用蓝
#property indicator_color2 Red表示第一条指标线是用红
#property indicator_color3 Blue 参考上面
#property indicator_color4 Red 参考上面
#property indicator_style4 2 表示指标类型采用系统定义好的2号类型
头文件部分还有一个重要作用就是定义输入参数:
extern int fast=3;
extern double slow=7.34;
输入参数的定义每一行以extern开头,后面紧接着是参数的类型int整数double双精度实数,再后来是参数的名字以及设定他的初始数值。
说明:在这里设定的参数,当你在MetaTrader里面附加这个指标的时候,弹出的指标窗口“输入参数”里面就会显示出来。
头文件部分完成后,下面的三个部分是三个系统设定好名字的函数过程,不要更改名字,否则无法运行。你要做的只是在这三个函数过程内部添加你的代码,当然你也可以在这三个函数外面自己定义你的个性函数,然后再三个函数里面进行调用。
三个系统函数如下:
int init() 初始化函数,这个函数在治标被加载的时候运行一次,一般用于进行和图表有关的一些属性的设置。
int deinit() 预定义函数,一般很少使用,知道就行了,程序里面可以没有这个部分
int start() 最重要的程序部分都在这里,start函数在每来一个价格Tick的时候,都会运行一
次,这里面放置了主要的程序循环代码。因此你开发的指标图形才会在实时行情下不断变化。
一个MT4高三语文教学反思程序包含了以上部分后,就算完整了,剩下的工作主要在于结构流程的设计功夫。
MT4自定义指标一般由四个部分构成:
(1)文件头部
(2)参数、变量和数组的定义
(3)初始化函数init()
(4)主函数start()

一、文件头部,也称为预处理程序
预处理程序以“#”开头,行尾无语句结束符“;”
常用的预处理程序有:
1#property  indicator_chart_window
把指标显示在主图。如:均线、SRA等类指标用到此语句
2#property indicator_separate_window
把指标显示在副图。如:MACDRSI、威廉等类指标用到此语句
3#property indicator_buffers 3
显示3根指标线
4#property indicator_color1 Red
1根指标线的颜为Red
5#property  indicator_width1  1
1根指标线的粗细分别为四季养生论文1
6#property indicator_level1  0.00
0.00值位置横划1条虚线

二、参数、变量和数组的定义
全局性的参数、变量、数组在此定义,局部变量可在start()函数中定义

三、初始化函数init()
init()在自定义指标加载时运行一次。
初始化函数的功能是设置。如果自定义指标需要划线,则必然用到此函数

四、主函数start()
当数据有变动时,start()就被触发。数据变动一次,start()就运行一次。
自定义指标的编程主要依靠此函数进行。
start()函数的作用主要是取值和给指标线赋值,报警也在此函数内发起。

另外,还有一个反初始化函数deinit()
deinit()在自定义卸载时运行一次,可用以去除指标加载时init()所做的初始化操作。

本文发布于:2024-09-22 15:41:22,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/610467.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:指标   函数   部分   程序   运行   设置   参数
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议