结果相当简单,只有4个主区块。 现在,请跟随着每个结构的步骤来创建代码:
1. 原始数据的检索 这条代码通常从智能交易系统移到另一个稍微更改的另一个代码-实际上为检索的标准区块:
若Bars
若获利
2. 为了加快数据存取,设置内部变量 在程序代码中,很有必要存取指标值或处理计算值。为了简化代码和加速存储,初始状态下,数据嵌套在内部变量里。
MacdCurrent=iMACD(12,26,9,MODE_MAIN,0); // MACD value on the current bar
MacdPrevious=iMACD(12,26,9,MODE_MAIN,1); // MACD value on the previous bar
SignalCurrent=iMACD(12,26,9,MODE_SIGNAL,0); // Signal Line value on the current bar
SignalPrevious=iMACD(12,26,9,MODE_SIGNAL,1);// Signal Line value on the previous bar
MaCurrent=iMA(MATrendPeriod,MODE_EMA,0); // moving average value on the current bar
MaPrevious=iMA(MATrendPeriod,MODE_EMA,1); // moving average value on the previous bar
现在,不用晦涩难懂的iMACD(12,26,9,MODE_MAIN,0) 符号,我们在程序中用简单的写入字符 MacdCurrent程序文本取而代之。所有的智能交易系统中的变量都依据MQL II语言进行基本的解释。所以,我们在程序的开头加入这段说明。
var: MacdCurrent(0), MacdPrevious(0), SignalCurrent(0), SignalPrevious(0);
var: MaCurrent(0), MaPrevious(0);
MQL 4语言还另外推出了另外一个用户自定义变量概念,它可以在程序外设定,而不会对任何系统程序下的源程序文本造成干扰。这个特点使程序更具灵活性。 MATrendPeriod变量就是这种类型的一个用户自定义变量,所以,我们在程序的开头加入这段说明。
defines: MATrendPeriod(56);
3. 检查交易终端-是否可用? 若是,那么:
在智能交易系统里,我们只能使用当前头寸而不能操作延迟的订单。然而,为了安全起见,我们介绍如何利用交易终端建检查前期提交的订单。
If TotalTrades
{
检查: 账户的可用资金等。在分析市场状况之前,最好先检查一下你的账户的资金情况, 以确保账户中有充足的开仓头寸的资金。
如果净保证金
可否做多头(买入)? 多头买入的条件:MACD指标在0轴以下,为向上趋势且与向下趋势的信号线相交。这和我们在MQL II语言中所描述的一样(注意:我们可以按照原已保存在变量中的这个指标值进行操作。)
If MacdCurrentSignalCurrent and
MacdPrevious
Abs(MacdCurrent)>(MACDOpenLevel*Point) and // the indicator plotted a decent 'hillock'
MaCurrent>MaPrevious then // 'bull' trend
{
SetOrder(OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,RED); // executing
Exit; // exiting, since after the execution of a trade
// there is a 10-second trading timeout
};
前面我们提到了一种监控图表中所要显示“小丘”的大小的一种方法。MACDOpenLevel 变量是一个用户定义变量,可以在不影响程序文本的情况下,进行更改,以确保更多的灵活性。在程序的开始部分,我们加入一段这个变量的描述(以及下面所用到的变量描述)。
defines: MACDOpenLevel(3), MACDCloseLevel(2);
是否可以做空头(卖出)?空头卖出的条件:MACD指标在0轴以上,为向下趋势且与向上趋势的信号线相交。符号表示如下:
If MacdCurrent>0 and MacdCurrent
MacdPrevious>SignalPrevious and MacdCurrent>(MACDOpenLevel*Point) and
MaCurrent
{
SetOrder(OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,RED); // executing
Exit; // exiting
};
Exit; // no new positions opened - just exit
};
4. 控制循环周期中前期已开仓的头寸
for cnt=1 to TotalTrades
{
if OrderValue(cnt,VAL_TYPE)
OrderValue(cnt,VAL_SYMBOL)=Symbol then // position from "our" chart?
{
CNT是周期变量,是在程序的开始部分加以描述的,具体如下: var: Cnt(0);
若是多头买入
If OrderValue(cnt,VAL_TYPE)=OP_BUY then // long position opened
{
是否需要平仓?存在平仓的条件:MACD指针与信号线相交,MACD指针在0轴以上,为向下趋势且与向上趋势的信号线相交。
If MacdCurrent>0 and MacdCurrent
MacdPrevious>SignalPrevious and MacdCurrent>(MACDCloseLevel*Point) then
{
CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Bid,3,Violet);
Exit; // exit
};
是否应该需要重新设定移动止损点?仅在持仓并已超过移动止损点数点并获利的情况下,而且新的移动止损点比前期的要更有理一些,我们才重新设置移动止损点。
If TrailingStop>0 then // if trailing stops are used
{
If (Bid-OrderValue(cnt,VAL_OPENPRICE))>(Point*TrailingStop) then
{
If OrderValue(cnt,VAL_STOPLOSS)
{
ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),
Bid-Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);
Exit;
};
};
};
}
若是处在空头部位
else // otherwise it is a short position
{
是否应该平仓?出现空头的条件: MACD指针与信号线相交,MACD指针在0轴以下,为向上趋势且与向下趋势的信号线相交。
If MacdCurrentSignalCurrent and
MacdPrevious(MACDCloseLevel*Point) then
{
CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Ask,3,Violet);
Exit; // exit
};
是否应该重新设定移动止损点?仅在持仓并已超过移动止损点数点并获利的情况下,而且新的移动止损点比前期的要更有理一些,我们才重新设置移动止损点。
If TrailingStop>0 then // the user has put a trailing stop in his settings
{ // so, we set out to check it
If (OrderValue(cnt,VAL_OPENPRICE)-Ask)>(Point*TrailingStop) then
{
If OrderValue(cnt,VAL_STOPLOSS)=0 or
OrderValue(cnt,VAL_STOPLOSS)>(Ask+Point*TrailingStop) then
{
ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),
Ask+Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);
Exit;
};
};
};
// end. 结束所有的花括号,但仍然有效。
};
};
};
所以,按照步骤,循序渐进地学习,我们已经学会了编写智能交易系统。
第三步:将所有程序代码集合起来
我们将前面章节的所有的代码集合起来:
defines: MACDOpenLevel(3),MACDCloseLevel(2);
defines: MATrendPeriod(56);
var: MacdCurrent(0),MacdPrevious(0),SignalCurrent(0),SignalPrevious(0);
var: MaCurrent(0),MaPrevious(0);
var: cnt(0);
// 原始数据检查
//确保智能交易系统在正常图表上运行,这很重要。
// 用户正确设置外部变量 (单位数, 止损,
// 获利、移动止损)
// 在我们看来,我们只需检查获利就行了
若Bars
//简化和加速操作程序,我们需要作必要的保存
//临时变量中的指标数据
MacdCurrent=iMACD(12,26,9,0,MODE_MAIN);
MacdPrevious=iMACD(12,26,9,1,MODE_MAIN);
SignalCurrent=iMACD(12,26,9,0,MODE_SIGNAL);
SignalPrevious=iMACD(12,26,9,1,MODE_SIGNAL);
MaCurrent=iMA(MATrendPeriod,MODE_EMA,0);
MaPrevious=iMA(MATrendPeriod,MODE_EMA,1);
//现在我们必须检查交易终端的状况
// 我们要看一看是否还有任何前期开仓部位或订单。
如果总交易
{//没有已开仓订单
// 为了安全期间,我们要确保账户有充足的资金。.
//比如说,取值为“1000”,通常可能就是提交1个单位
如果净保证金
//检查做多头(买入)的可能性
If MacdCurrentSignalCurrent and
MacdPrevious(MACDOpenLevel*Point) and
MaCurrent>MaPrevious then
{
SetOrder(OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*Point,RED); // 执行
Exit; // 既然交易已经执行,退出
// 有10秒钟的交易暂停时间
};
//检查空头(卖出)的可能性
If MacdCurrent>0 and MacdCurrent
MacdPrevious>SignalPrevious and MacdCurrent>(MACDOpenLevel*Point) and
MaCurrent
{
SetOrder(OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point,RED); // executing
Exit; // exiting
};
//这里我们完成了对新的开仓部位可行性检查
//没有新的开仓部位,我们就用退出命令退出程序
//没有要分析的任何东西
Exit;
};
//我们进入到智能交易系统的重要部分-控制开仓部位
// 正确进入市场很重要,但是退出市场更重要。
for cnt=1 to TotalTrades
{
if OrderValue(cnt,VAL_TYPE)
OrderValue(cnt,VAL_SYMBOL)=Symbol then // 工具匹配吗?
{
If OrderValue(cnt,VAL_TYPE)=OP_BUY then // 多头开仓
{
// 我们检查-可能,尚有时间平仓吗?
If MacdCurrent>0 and MacdCurrent
MacdPrevious>SignalPrevious and MacdCurrent>(MACDCloseLevel*Point) then
{
CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Bid,3,Violet);
Exit; // 退出
};
// 我们检查-可能,我可能已经或该是设置移动止损的时候了吗?
If TrailingStop>0 then //用户已经将移动止损进行了设置
{ // 所以,我们开始着手检查
If (Bid-OrderValue(cnt,VAL_OPENPRICE))>(Point*TrailingStop) then
{
If OrderValue(cnt,VAL_STOPLOSS)
{
ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),
Bid-Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);
Exit;
};
};
};
}
else // 否则,就是多头。
{
// 我们检查-可能,尚有时间平仓吗?
If MacdCurrentSignalCurrent and
MacdPrevious(MACDCloseLevel*Point) then
{
CloseOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_LOTS),Ask,3,Violet);
Exit; // 退出
};
//我们检查-可能,我可能已经或该是设置移动止损的时候了吗?
If TrailingStop>0 then // 用户已经把移动止损进行了设置
{ // 所以,我开始着手检查。
If (OrderValue(cnt,VAL_OPENPRICE)-Ask)>(Point*TrailingStop) then
{
If OrderValue(cnt,VAL_STOPLOSS)=0 or
OrderValue(cnt,VAL_STOPLOSS)>(Ask+Point*TrailingStop) then
{
ModifyOrder(OrderValue(cnt,VAL_TICKET),OrderValue(cnt,VAL_OPENPRICE),
Ask+Point*TrailingStop,OrderValue(cnt,VAL_TAKEPROFIT),Red);
Exit;
};
};
};
};
};
};
// 结束 。