一个神经网络的EA的示例(含源码)——Combo_Right.mq4

2013年01月27日 14:18:05
标签： 神经网络/示例/源码/EA

1。“如果有飞机，为什么还要教人类去飞？”

2。大家都说做单子最重要的是“顺势而为”，但更需要解决的是∶
“一个基于趋势的交易系统是不能成功交易在盘整(sideways trends)，

3。训练神经网络需要用多长的历史数据，提出了并不是用的历史数据越长越好，另外也不是训练的间隔越短越好，文中提出了什么情况下有需再训练它。

The problem is stated for this automated trading system (ATS) as follows:
(ATS)自动的(智能的，采用神经网络的)交易系统的问题表述如下

Let's consider we have a basic trading system - BTS. It is necessary to create and teach a neural network in order it to do things that cannot be done with the BTS. This must result in creation of a trading system consisting of two combined and mutually complementary BTS and NN (neural network).

Or, the English of this is: There is no need to discover the continents again, they were all
discovered. Why to teach somebody to run fast, if we have a car, or to fly, if we have a plane?

Once we have a trend-following ATS, we just have to teach the neural network in countertrend strategy. This is necessary, because a system intended for trend-based trading cannot trade on sideways trends or recognize market setbacks or reversals. You can, of course, take two ATSes - a trend-following one and a countertrend one - and attach them to the same chart. On the other hand, you can teach a neural network to complement your existing trading system.

For this purpose, we designed a two-layer neural network consisting of two perceptrons in the lower layer and one perceptron in the upper layer.

The output of the neural network can be in one of these three states:

Entering the market with a long position
(Entering)市场是处在多向仓

Entering the market with a short position
(Entering)市场是处在空向仓

Indeterminate state

Actually, the third state is the state of passing control over to the BTS, whereas in the first two states the trade signals are given by the neural network.

The teaching of the neural network is divided into three stages, each stage for teaching one perceptron. At any stage, the optimized BTS must be present for perceptrons to know what it can do.

The separate teaching of perceptrons by a genetic algorithm is determined by the lack of this algorithm, namely: The amount of inputs searched in with the help of such algorithm is limited. However, each teaching stage is coherent and the neural network is not too large, so the whole optimization does not take too much time.

The very first stage, preceding the teaching of an NN, consists in optimization of the BTS.

In order not to lose ourselves, we will record the stage number in the input of the ATS identified as "pass". Identifiers of inputs corresponding with the stage number will and in the number equal to this stage number.

Thus, let's start preparations for optimization and teaching the NN. Let's set the initial deposit as \$1000000 (in order not to create an artificial margin call during optimization) and the input to be optimized as "Balance" in Expert Advisor properties on the tab of "Testing" in the Strategy Tester, and start genetic algorithm.

Let's go to the "Inputs" tab of the EA's properties and specify the volume of positions to be opened by assigning the value 1 to the identifier "lots".

Optimization will be performed according to the model: "Open prices only (fastest method to analyze the bar just completed, only for EAs that explicitly control bar opening)", since this method is available in the ATS algorithm.

Stage 1 of optimization. Optimization of the BTS:

Set the value 1 for the input "pass".

We will optimize only inputs that correspond with the first stage, i.e., that end in 1. Thus, we check only these inputs for optimization, and uncheck all others.

tp1 - TakeProfit of the BTS. It is optimized with the values within the range of 10 to 100, step 1
tp1，BTS的所取的止盈值（TakeProfit）。在step 1，优化的值的范围在10到100，
sl1 - StopLoss of the BTS. It is optimized with the values within the range of 10 to 100, step 1
sl1，BTS的所取的止损值（StopLoss）。在step 1，优化的值的范围在10到100 。
p1 - period of CCI used in the BTS. It is optimized with the values within the range of 3 to 100, step 1
p1， 用于BTS的CCI的周期值。在step 1 ，优化的值的范围在 3到100
Below are the results of the BTS optimization: Stage 2. Teaching the perceptron responsible for short positions:

Set the value 2 (according to the stage number) for the input "pass".

Uncheck the inputs checked for optimization in the previous stage. Just in case, save in a file the inputs obtained at the previous stage.

Check the inputs for optimization according to our rule: their identifiers must end in 2:

x12, x22, x32, x42 - weight numbers of the perceptron that recognizes short positions. It is optimized with the values within the range of 0 to 200, step 1
x12, x22, x32, x42 是识别并开空仓的感知机的权重，它们的值在step 1时被优化在范围0 to 200
tp2 - TakeProfit of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1
tp2  (TakeProfit) 是感知机所开的仓的止盈值，它们的值在step 1时被优化在范围10 to 100。
sl2 - StopLoss of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1
sl2 (StopLos) 在 step 1它是感知机所开的仓的止损值，被优化值的范围在 10 to 100
p2 - the period of the values of price difference to be analyzed by the perceptron. It is optimized with the values within the range of 3 to 100, step 1.
p2 感知机所分析的价格差的周期值 (iiCCI()函数的一个参数∶period - Averaging period for calculation)，在step 1 它的值所优化的范围在3 to 100
Let's start teaching it using optimization with a genetic algorithm. The obtained results are given below:  Stage 3. Teaching the perceptron responsible for long positions:

Set the value 3 (according to the stage number) for the input "pass".

Uncheck the inputs checked for optimization in the previous stage. Just in case, save in a file the inputs obtained at the previous stage.

Check the inputs for optimization according to our rule: their identifiers must end in 3:

x13, x23, x33, x43 - weight numbers of the perceptron that recognizes long positions. It is optimized with the values within the range of 0 to 200, step 1.
x13, x23, x33, x43是识别多仓的感知机的权重，它们的值在step 1时被优化时得到的范围在0 to 200
tp3 - TakeProfit of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1
tp 3  (TakeProfit) 是感知机所开的仓的“止盈值”，它的值在step 1时被优化时的范围是在10 to 100。
sl3 - StopLoss of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1
sl3 (StopLoss) 是感知机所开的仓的“止盈值”，它们的值在step 1时被优化为范围是10 to 100。
p3 - the period of the values of price difference to be analyzed by the perceptron . It is optimized with the values within the range of 3 to 100, step 1.
p3 --感知机所分析的价差的周期值。它在步骤 1 优化时得到的值的范围是 3 to 100 。
Let's start teaching it using optimization with a genetic algorithm. The obtained results are given below:  Stage 4 (final). Teaching the first layer, i.e., teaching the perceptron that is in the upper layer:

Set the value 4 (according to the stage number) for the input "pass".

Uncheck the inputs checked for optimization in the previous stage. Just in case, save in a file the inputs obtained at the previous stage.

Check the inputs for optimization according to our rule: their identifiers must end in 4:

x14, x24, x34, x44 - weight numbers of the perceptron of the first layer. It is optimized with the values within the range of 0 to 200, step 1.
x14, x24, x34, x44 是第一层感知机参数的权重值。在步骤 1 时它们被优化的值的范围在0 to 200 。
p4 - the period of the values of price difference to be analyzed by the perceptron. It is optimized with the values within the range of 3 to 100, step 1.
p4 被感知机分析的价差的值的周期。在步骤 1 它的值的范围被优化在 3 to 100 。
Let's start teaching it using optimization with a genetic algorithm. The obtained results are given below:  That's all, the neural network has been taught.

The ATS has one more non-optimizable input, mn - Magic Number. It is the identifier of positions for a trading system not to mix its orders with the orders opened manually or by other ATSes. The value of the magic number must be unique and not coincide with the magic numbers of positions that have not been opened by this specific Expert Advisor.

P.S.

The size of the initial deposit is found as the doubled absolute drawdown, i.e., we consider some safety resources for it.

The EA given in the source codes is not optimized.

If you need to replace the built-in BTS with the algorithm of another trading system, you must modify the contents of the function basicTradingSystem().

In order not to enter the initial and the final values and the values of steps for optimization, you can take the ready file combo.set, place it in the folder \tester MT4, and upload to the EA's properties in Tester.

Re-optimization of the EA is to be performed at a weekend, i.e., on Saturday or on Sunday, but only if the results of the preceding week were unprofitable. The presence of losses means that the market has changed, and the re-optimization is necessary. The presence of profits means that the ATS does not need any re-optimization and recognizes market patterns quite well.

```//+------------------------------------------------------------------+
//|                                                  Combo_Right.mq4 |
//|                               Copyright ?2008, Yury V. Reshetov |
//+------------------------------------------------------------------+

//---- input parameters
extern double       tp1 = 50;
extern double       sl1 = 50;
extern int          p1 = 10;
extern int          x12 = 100;
extern int          x22 = 100;
extern int          x32 = 100;
extern int          x42 = 100;
extern double       tp2 = 50;
extern double       sl2 = 50;
extern int          p2 = 20;
extern int          x13 = 100;
extern int          x23 = 100;
extern int          x33 = 100;
extern int          x43 = 100;
extern double       tp3 = 50;
extern double       sl3 = 50;
extern int          p3 = 20;
extern int          x14 = 100;
extern int          x24 = 100;
extern int          x34 = 100;
extern int          x44 = 100;
extern int          p4 = 20;
extern int          pass = 1;
extern double       lots = 0.01;
extern int          mn = 888;
static int          prevtime = 0;
static double       sl = 10;
static double       tp = 10;

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
if (Time == prevtime) return(0);
prevtime = Time;

again();
return(0);
}
//----
int total = OrdersTotal();
for (int i = 0; i < total; i++) {
if (OrderSymbol() == Symbol() && OrderMagicNumber() == mn) {
return(0);
}
}

sl = sl1;
tp = tp1;

int ticket = -1;

RefreshRates();

if (Supervisor() > 0) {
ticket = OrderSend(Symbol(), OP_BUY, lots, Ask, 1, Bid - sl * Point, Bid + tp * Point, WindowExpertName(), mn, 0, Blue);
if (ticket < 0) {
again();
}
} else {
ticket = OrderSend(Symbol(), OP_SELL, lots, Bid, 1, Ask + sl * Point, Ask - tp * Point, WindowExpertName(), mn, 0, Red);
if (ticket < 0) {
again();
}
}
//-- Exit --
return(0);
}
//+--------------------------- getLots ----------------------------------+

double Supervisor() {
if (pass == 4) {
if (perceptron3() > 0) {
if (perceptron2() > 0) {
sl = sl3;
tp = tp3;
return(1);
}
} else {
if (perceptron1() < 0) {
sl = sl2;
tp = tp2;
return(-1);
}
}
}

if (pass == 3) {
if (perceptron2() > 0) {
sl = sl3;
tp = tp3;
return(1);
} else {
}
}

if (pass == 2) {
if (perceptron1() < 0) {
sl = sl2;
tp = tp2;
return(-1);
} else {
}

}
}

double perceptron1()   {
double       w1 = x12 - 100;
double       w2 = x22 - 100;
double       w3 = x32 - 100;
double       w4 = x42 - 100;
double a1 = Close - Open[p2];
double a2 = Open[p2] - Open[p2 * 2];
double a3 = Open[p2 * 2] - Open[p2 * 3];
double a4 = Open[p2 * 3] - Open[p2 * 4];
return(w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
}

double perceptron2()   {
double       w1 = x13 - 100;
double       w2 = x23 - 100;
double       w3 = x33 - 100;
double       w4 = x43 - 100;
double a1 = Close - Open[p3];
double a2 = Open[p3] - Open[p3 * 2];
double a3 = Open[p3 * 2] - Open[p3 * 3];
double a4 = Open[p3 * 3] - Open[p3 * 4];
return(w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
}

double perceptron3()   {
double       w1 = x14 - 100;
double       w2 = x24 - 100;
double       w3 = x34 - 100;
double       w4 = x44 - 100;
double a1 = Close - Open[p4];
double a2 = Open[p4] - Open[p4 * 2];
double a3 = Open[p4 * 2] - Open[p4 * 3];
double a4 = Open[p4 * 3] - Open[p4 * 4];
return(w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
}