323 lines
14 KiB
MQL5
323 lines
14 KiB
MQL5
|
//****** project (module expert): tf-test-g1_module_exp.mq5
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| The program code is generated Modular project generator |
|
||
|
//| Copyright 2010-2017, Sergey Pavlov (DC2008) |
|
||
|
//| http://www.mql5.com/ru/users/dc2008 |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property copyright "Copyright 2010-2017, Sergey Pavlov (DC2008)"
|
||
|
#property link "http://www.mql5.com/ru/users/dc2008"
|
||
|
#property link "1.00"
|
||
|
#property link "Example of a multimodule expert: project TF-TEST-G1 Main module."
|
||
|
#property link "The project uses 7 external modules."
|
||
|
//---
|
||
|
#include <Trade\Trade.mqh>
|
||
|
//---
|
||
|
MqlTick last_tick;
|
||
|
CTrade trade;
|
||
|
//---
|
||
|
input string e_ordner="Shared Projects\\Indicatoren\\3133\\";
|
||
|
input int e_bands_period=80; // Moving average period
|
||
|
int e_bands_shift=0; // shift
|
||
|
input double e_deviation=3.0; // Number of standard deviations
|
||
|
input ENUM_APPLIED_PRICE e_applied_price=PRICE_CLOSE; // Price type
|
||
|
input bool on_module=true; // whether or not to use plug-ins
|
||
|
//---
|
||
|
double lot=0.01; // Fixed lot
|
||
|
double min_lot=0.01; // Minimum allowable lot
|
||
|
bool on_trade=false; // Trade function flag
|
||
|
//--- Variable for storing the indicator iBands handle
|
||
|
int handle_Bands;
|
||
|
//--- module 1
|
||
|
bool on_lot=false;
|
||
|
int handle_m1;
|
||
|
//--- module 2
|
||
|
bool on_SL=false;
|
||
|
int handle_m2;
|
||
|
//--- module 3
|
||
|
bool on_TP=false;
|
||
|
int handle_m3;
|
||
|
//--- module 4
|
||
|
bool on_Trail=false;
|
||
|
int handle_m4;
|
||
|
//--- module 5
|
||
|
bool on_signals=false;
|
||
|
int handle_m5;
|
||
|
//--- module 6
|
||
|
bool on_Filter=false;
|
||
|
int handle_m6;
|
||
|
//--- module 7
|
||
|
bool on_Breakeven=false;
|
||
|
int handle_m7;
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Structure of trading signals |
|
||
|
//+------------------------------------------------------------------+
|
||
|
struct sSignal
|
||
|
{
|
||
|
bool Buy; // Buy signal
|
||
|
bool Sell; // Sell signal
|
||
|
};
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Trading signals generator |
|
||
|
//+------------------------------------------------------------------+
|
||
|
sSignal Buy_or_Sell()
|
||
|
{
|
||
|
sSignal res= {false,false};
|
||
|
//--- MODULE 5
|
||
|
if(on_signals)
|
||
|
{
|
||
|
// If there is an additional module
|
||
|
double buffer_m5[];
|
||
|
ArraySetAsSeries(buffer_m5,true);
|
||
|
if(CopyBuffer(handle_m5,0,0,1,buffer_m5)<0) return(res);
|
||
|
Print(__FUNCTION__+" buffer_m5 : "+(string)buffer_m5[0]);
|
||
|
if(buffer_m5[0]<-1) res.Sell=true;
|
||
|
if(buffer_m5[0]>1) res.Buy=true;
|
||
|
}
|
||
|
//--- MODULE 6
|
||
|
if(on_Filter)
|
||
|
{
|
||
|
// If there is an additional module
|
||
|
double buffer_m6[];
|
||
|
ArraySetAsSeries(buffer_m6,true);
|
||
|
if(CopyBuffer(handle_m6,0,0,1,buffer_m6)<0) return(res);
|
||
|
lot=buffer_m6[0];
|
||
|
if(buffer_m6[0]<1) res.Buy=false;
|
||
|
if(buffer_m6[0]>-1) res.Sell=false;
|
||
|
}
|
||
|
//---
|
||
|
//--- Indicator buffers
|
||
|
double UpperBuffer[];
|
||
|
double LowerBuffer[];
|
||
|
double MiddleBuffer[];
|
||
|
ArraySetAsSeries(MiddleBuffer,true);
|
||
|
CopyBuffer(handle_Bands,0,0,1,MiddleBuffer);
|
||
|
ArraySetAsSeries(UpperBuffer,true);
|
||
|
CopyBuffer(handle_Bands,1,0,1,UpperBuffer);
|
||
|
ArraySetAsSeries(LowerBuffer,true);
|
||
|
CopyBuffer(handle_Bands,2,0,1,LowerBuffer);
|
||
|
//--- Timeseries
|
||
|
double L[];
|
||
|
double H[];
|
||
|
ArraySetAsSeries(L,true);
|
||
|
CopyLow(_Symbol,_Period,0,1,L);
|
||
|
ArraySetAsSeries(H,true);
|
||
|
CopyHigh(_Symbol,_Period,0,1,H);
|
||
|
if(H[0]>UpperBuffer[0]&& L[0]>MiddleBuffer[0]) res.Sell=true;
|
||
|
if(L[0]<LowerBuffer[0] && H[0]<MiddleBuffer[0]) res.Buy=true;
|
||
|
//---
|
||
|
return(res);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Expert initialization function |
|
||
|
//+------------------------------------------------------------------+
|
||
|
int OnInit()
|
||
|
{
|
||
|
//--- Create the indicator handle
|
||
|
handle_Bands=iBands(_Symbol,_Period,e_bands_period,e_bands_shift,e_deviation,e_applied_price);
|
||
|
if(handle_Bands==INVALID_HANDLE)
|
||
|
return(INIT_FAILED);
|
||
|
else
|
||
|
on_trade=true;
|
||
|
if(on_module)
|
||
|
{
|
||
|
//--- MODULE 1
|
||
|
//--- check: whether there is an external module?
|
||
|
handle_m1=iCustom(NULL,0,e_ordner+"tf-test-g1_module_MM_ind");
|
||
|
if(handle_m1!=INVALID_HANDLE)
|
||
|
on_lot=true;
|
||
|
//--- MODULE 2
|
||
|
//--- check: whether there is an external module?
|
||
|
handle_m2=iCustom(NULL,0,e_ordner+"tf-test-g1_module_SL_ind");
|
||
|
if(handle_m2!=INVALID_HANDLE)
|
||
|
on_SL=true;
|
||
|
//--- MODULE 3
|
||
|
//--- check: whether there is an external module??
|
||
|
handle_m3=iCustom(NULL,0,e_ordner+"tf-test-g1_module_TP_ind");
|
||
|
if(handle_m3!=INVALID_HANDLE)
|
||
|
on_TP=true;
|
||
|
//--- MODULE 4
|
||
|
//--- check: whether there is an external module?
|
||
|
handle_m4=iCustom(NULL,0,e_ordner+"tf-test-g1_module_Trail_ind");
|
||
|
if(handle_m4!=INVALID_HANDLE)
|
||
|
on_Trail=true;
|
||
|
//--- MODULE 5
|
||
|
//--- check: whether there is an external module?
|
||
|
handle_m5=iCustom(NULL,0,e_ordner+"tf-test-g1_module_signals_ind");
|
||
|
if(handle_m5!=INVALID_HANDLE)
|
||
|
on_signals=true;
|
||
|
//--- MODULE 6
|
||
|
//--- check: whether there is an external module?
|
||
|
handle_m6=iCustom(NULL,0,e_ordner+"tf-test-g1_module_Filter_ind");
|
||
|
if(handle_m6!=INVALID_HANDLE)
|
||
|
on_Filter=true;
|
||
|
//--- MODULE 7
|
||
|
//--- check: whether there is an external module?
|
||
|
handle_m7=iCustom(NULL,0,e_ordner+"tf-test-g1_module_Breakeven_ind");
|
||
|
if(handle_m7!=INVALID_HANDLE)
|
||
|
on_Breakeven=true;
|
||
|
}
|
||
|
//--- Minimum allowable volume for trading operationsn
|
||
|
min_lot=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
|
||
|
return(INIT_SUCCEEDED);
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Expert tick function |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void OnTick()
|
||
|
{
|
||
|
double Equity=AccountInfoDouble(ACCOUNT_EQUITY);
|
||
|
//--- MODULE 1
|
||
|
if(on_lot)
|
||
|
{
|
||
|
// If there is an additional module
|
||
|
double buffer_m1[];
|
||
|
ArraySetAsSeries(buffer_m1,true);
|
||
|
if(CopyBuffer(handle_m1,0,0,1,buffer_m1)<0) return;
|
||
|
lot=buffer_m1[0];
|
||
|
}
|
||
|
//--- MODULE 4
|
||
|
if(on_Trail)
|
||
|
if(PositionSelect(_Symbol))
|
||
|
if(PositionGetDouble(POSITION_PROFIT)>0)
|
||
|
{
|
||
|
// If there is an additional module
|
||
|
double buffer_m4[];
|
||
|
ArraySetAsSeries(buffer_m4,true);
|
||
|
if(CopyBuffer(handle_m4,0,0,1,buffer_m4)<0) return;
|
||
|
double TR=buffer_m4[0];
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
|
||
|
if(PositionGetDouble(POSITION_PRICE_CURRENT)-TR*_Point>PositionGetDouble(POSITION_PRICE_OPEN))
|
||
|
{
|
||
|
double price_SL=PositionGetDouble(POSITION_PRICE_CURRENT)-TR*_Point;
|
||
|
if(price_SL>PositionGetDouble(POSITION_SL))
|
||
|
trade.PositionModify(_Symbol,NormalizeDouble(price_SL,Digits()),0);
|
||
|
}
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
|
||
|
if(PositionGetDouble(POSITION_PRICE_CURRENT)+TR*_Point<PositionGetDouble(POSITION_PRICE_OPEN))
|
||
|
{
|
||
|
double price_SL=PositionGetDouble(POSITION_PRICE_CURRENT)+TR*_Point;
|
||
|
if(price_SL<PositionGetDouble(POSITION_SL) || PositionGetDouble(POSITION_SL)==NULL)
|
||
|
trade.PositionModify(_Symbol,NormalizeDouble(price_SL,Digits()),0);
|
||
|
}
|
||
|
}
|
||
|
//--- MODULE 7
|
||
|
if(on_Breakeven)
|
||
|
if(PositionSelect(_Symbol))
|
||
|
if(PositionGetDouble(POSITION_PROFIT)>0)
|
||
|
{
|
||
|
// If there is an additional module
|
||
|
double buffer_m7[];
|
||
|
ArraySetAsSeries(buffer_m7,true);
|
||
|
if(CopyBuffer(handle_m7,0,0,1,buffer_m7)<0) return;
|
||
|
double TRB=buffer_m7[0];
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
|
||
|
if(PositionGetDouble(POSITION_PRICE_CURRENT)-TRB*_Point>PositionGetDouble(POSITION_PRICE_OPEN))
|
||
|
{
|
||
|
double price_SL=PositionGetDouble(POSITION_PRICE_CURRENT)-5*_Point;
|
||
|
if(price_SL>PositionGetDouble(POSITION_SL))
|
||
|
trade.PositionModify(_Symbol,NormalizeDouble(price_SL,Digits()),PositionGetDouble(POSITION_TP));
|
||
|
}
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
|
||
|
if(PositionGetDouble(POSITION_PRICE_CURRENT)+TRB*_Point<PositionGetDouble(POSITION_PRICE_OPEN))
|
||
|
{
|
||
|
double price_SL=PositionGetDouble(POSITION_PRICE_CURRENT)+5*_Point;
|
||
|
if(price_SL<PositionGetDouble(POSITION_SL) || PositionGetDouble(POSITION_SL)==NULL)
|
||
|
trade.PositionModify(_Symbol,NormalizeDouble(price_SL,Digits()),PositionGetDouble(POSITION_TP));
|
||
|
}
|
||
|
}
|
||
|
//---
|
||
|
if(lot<min_lot) lot=min_lot;
|
||
|
//---
|
||
|
if(on_trade)
|
||
|
{
|
||
|
sSignal signal=Buy_or_Sell();
|
||
|
//--- The value of the required and free margin
|
||
|
double margin,free_margin=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
|
||
|
//--- BUY
|
||
|
if(signal.Buy)
|
||
|
{
|
||
|
if(!PositionSelect(_Symbol))
|
||
|
{
|
||
|
SymbolInfoTick(_Symbol,last_tick);
|
||
|
if(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,NormalizeDouble(lot,2),last_tick.ask,margin))
|
||
|
if(margin<Equity)
|
||
|
trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,NormalizeDouble(lot,2),last_tick.ask,0,0,"BUY: new position");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(PositionGetDouble(POSITION_PROFIT)<0) return;
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
|
||
|
{
|
||
|
trade.PositionClose(_Symbol);
|
||
|
SymbolInfoTick(_Symbol,last_tick);
|
||
|
if(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,NormalizeDouble(lot,2),last_tick.ask,margin))
|
||
|
if(margin<Equity)
|
||
|
trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,NormalizeDouble(lot,2),last_tick.ask,0,0,"BUY: reversal");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//--- SELL
|
||
|
if(signal.Sell)
|
||
|
{
|
||
|
if(!PositionSelect(_Symbol))
|
||
|
{
|
||
|
SymbolInfoTick(_Symbol,last_tick);
|
||
|
if(OrderCalcMargin(ORDER_TYPE_SELL,_Symbol,NormalizeDouble(lot,2),last_tick.bid,margin))
|
||
|
if(margin<Equity)
|
||
|
trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,NormalizeDouble(lot,2),last_tick.bid,0,0,"SELL: new position");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(PositionGetDouble(POSITION_PROFIT)<0) return;
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
|
||
|
{
|
||
|
trade.PositionClose(_Symbol);
|
||
|
SymbolInfoTick(_Symbol,last_tick);
|
||
|
if(OrderCalcMargin(ORDER_TYPE_SELL,_Symbol,NormalizeDouble(lot,2),last_tick.bid,margin))
|
||
|
if(margin<Equity)
|
||
|
trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,NormalizeDouble(lot,2),last_tick.bid,0,0,"SELL: reversal");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Trade function |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void OnTrade()
|
||
|
{
|
||
|
if(on_SL && on_TP) // If there is an additional module
|
||
|
{
|
||
|
//--- MODULE 2
|
||
|
double buffer_m2[];
|
||
|
ArraySetAsSeries(buffer_m2,true);
|
||
|
if(CopyBuffer(handle_m2,0,0,1,buffer_m2)<0) return;
|
||
|
double SL=buffer_m2[0];
|
||
|
//--- MODULE 3
|
||
|
double buffer_m3[];
|
||
|
ArraySetAsSeries(buffer_m3,true);
|
||
|
if(CopyBuffer(handle_m3,0,0,1,buffer_m3)<0) return;
|
||
|
double TP=buffer_m3[0];
|
||
|
//--- Position modification
|
||
|
if(PositionSelect(_Symbol))
|
||
|
if(PositionGetDouble(POSITION_SL)==0)
|
||
|
{
|
||
|
//--- BUY
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
|
||
|
{
|
||
|
double priceTP=PositionGetDouble(POSITION_PRICE_OPEN)+TP*_Point;
|
||
|
double priceSL=PositionGetDouble(POSITION_PRICE_OPEN)-SL*_Point;
|
||
|
trade.PositionModify(_Symbol,NormalizeDouble(priceSL,Digits()),NormalizeDouble(priceTP,Digits()));
|
||
|
}
|
||
|
//--- SELL
|
||
|
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
|
||
|
{
|
||
|
double priceTP=PositionGetDouble(POSITION_PRICE_OPEN)-TP*_Point;
|
||
|
double priceSL=PositionGetDouble(POSITION_PRICE_OPEN)+SL*_Point;
|
||
|
trade.PositionModify(_Symbol,NormalizeDouble(priceSL,Digits()),NormalizeDouble(priceTP,Digits()));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|