679 lines
No EOL
45 KiB
MQL5
679 lines
No EOL
45 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| bb_trader.mq5 |
|
|
//| Copyright 2024, Competent Dilettante |
|
|
//| https://www.youtube.com/@competentdilettante |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2024, Competent Dilettante"
|
|
#property link "https://www.youtube.com/@competentdilettante"
|
|
#property version "1.00"
|
|
|
|
#define STRUCT_FILENAME "bb_files/struct.dat"
|
|
#define SET_FILENAME "bb_files/set_struct.dat"
|
|
|
|
enum ENUM_LIFETIME_SIGNAL{
|
|
LIFETIME_SIGNAL_DAY = 0, //Время жизни сигнала - день
|
|
LIFETIME_SIGNAL_WEEK, //Время жизни сигнала - неделя
|
|
LIFETIME_SIGNAL_TWO_WEEKS, //Время жизни сигнала - 2 недели
|
|
LIFETIME_SIGNAL_MONTH //Время жизни сигала - месяц
|
|
};
|
|
|
|
struct SSettings{
|
|
bool allowTrade;
|
|
double outComm;
|
|
int slipage;
|
|
ENUM_TIMEFRAMES slowTf;
|
|
int slowBBPeriod;
|
|
int slowBBShift;
|
|
int slowMAPeriod;
|
|
ENUM_TIMEFRAMES fastTf;
|
|
int fastBBPeriod;
|
|
int fastBBShift;
|
|
int fastAO_MA;
|
|
int slowAO_MA;
|
|
int fastMACD;
|
|
int slowMACD;
|
|
int smaMACD;
|
|
ENUM_LIFETIME_SIGNAL inLifeTime;
|
|
int inFiltr;
|
|
double inStopLevel;
|
|
double close50Percent;
|
|
double close30Percent;
|
|
double close20Percent;
|
|
double inRisk;
|
|
|
|
bool operator !=(const SSettings &other){
|
|
if(allowTrade == other.allowTrade
|
|
&& (int)(outComm * 100) == (int)(other.outComm * 100)
|
|
&& slipage == other.slipage
|
|
&& slowTf == other.slowTf
|
|
&& slowBBPeriod == other.slowBBPeriod
|
|
&& slowBBShift == other.slowBBShift
|
|
&& slowMAPeriod == other.slowMAPeriod
|
|
&& fastTf == other.fastTf
|
|
&& fastBBPeriod == other.fastBBPeriod
|
|
&& fastBBShift == other.fastBBShift
|
|
&& fastAO_MA == other.fastAO_MA
|
|
&& slowAO_MA == other.slowAO_MA
|
|
&& fastMACD == other.fastMACD
|
|
&& slowMACD == other.slowMACD
|
|
&& smaMACD == other.smaMACD
|
|
&& inLifeTime == other.inLifeTime
|
|
&& inFiltr == other.inFiltr
|
|
&& (int)(inStopLevel * 1000) == (int)(other.inStopLevel * 1000)
|
|
&& (int)(close50Percent * 1000) == (int)(other.close50Percent * 1000)
|
|
&& (int)(close30Percent * 1000) == (int)(other.close30Percent * 1000)
|
|
&& (int)(close20Percent * 1000) == (int)(other.close20Percent * 1000)
|
|
&& (int)(inRisk * 100) == (int)(other.close20Percent * 100)
|
|
) return false;
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
struct SFibo {
|
|
double zeroPoint;
|
|
double onePoint;
|
|
|
|
SFibo()
|
|
{
|
|
zeroPoint = 0;
|
|
onePoint = 0;
|
|
}
|
|
};
|
|
|
|
#include "MyExpertFunctions.mqh"
|
|
#include "AbsorbingFinder.mqh"
|
|
|
|
input group "Общие настройки"
|
|
input uint inMagic = 556; //Идентификатор позиций эксперта
|
|
input bool inAllowTrade = true; //Разрешение на открытие новых позиций
|
|
input double inOutComm = 0.0;
|
|
input int inSlipage = 10;
|
|
input group "Настройки старшего ТФ"
|
|
input ENUM_TIMEFRAMES slowTf = PERIOD_H4;
|
|
input int slowBBPeriod = 21;
|
|
input int slowBBShift = 1;
|
|
input int slowMAPeriod = 120;
|
|
input group "Настройки младшего ТФ"
|
|
input ENUM_TIMEFRAMES fastTf = PERIOD_M15;
|
|
input int fastBBPeriod = 21;
|
|
input int fastBBShift = 1;
|
|
input int fastAO_MA = 1;
|
|
input int slowAO_MA = 7;
|
|
input int fastMACD = 12;
|
|
input int slowMACD = 30;
|
|
input int smaMACD = 9;
|
|
input ENUM_LIFETIME_SIGNAL inLifeTime = LIFETIME_SIGNAL_WEEK; //Время жизни сигнала
|
|
input group "Настройки торговли"
|
|
input int inFiltr = 50;
|
|
input double inStopLevel = 0.306;
|
|
input double close50Percent = 1.618;
|
|
input double close30Percent = 2.618;
|
|
input double close20Percent = 4.236;
|
|
input double inRisk = 1.5; //Risk on one deal (%)
|
|
|
|
|
|
//Handle values
|
|
int slowMAHandle, slowBBHandle;
|
|
int fastBBHandle, AOHandle, fastAO_MAHandle,slowAO_MAHandle,MACDHandle;
|
|
|
|
//Position struct
|
|
MqlParam posParams[2];
|
|
|
|
//Signal flags
|
|
bool isSignal = false;
|
|
int signalFlag{0};
|
|
int globalFlag{0};
|
|
//Time flags
|
|
static datetime t{0},slowT{0},fastT{0};
|
|
//Fibo struct
|
|
SFibo points;
|
|
//Levels array
|
|
const double levelaArray[] {1.768,1.88,2.786,2.88,4.786,4.88};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//---
|
|
MqlParam params[];
|
|
::ArrayResize(params,4);
|
|
params[0].type = TYPE_INT;
|
|
params[0].integer_value = slowMAPeriod;
|
|
params[1].type = TYPE_INT;
|
|
params[1].integer_value = 0;
|
|
params[2].type = TYPE_INT;
|
|
params[2].integer_value = MODE_SMA;
|
|
params[3].type = TYPE_INT;
|
|
params[3].integer_value = PRICE_CLOSE;
|
|
::ResetLastError();
|
|
slowAO_MAHandle = std::GetHandle(_Symbol,slowTf,IND_MA,params);
|
|
if(slowAO_MAHandle == INVALID_HANDLE) {
|
|
::Print("MA on slow TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
params[0].integer_value = slowBBPeriod;
|
|
params[1].integer_value = slowBBShift;
|
|
params[2].type = TYPE_DOUBLE;
|
|
params[2].double_value = 2.0;
|
|
slowBBHandle = std::GetHandle(_Symbol,slowTf,IND_BANDS,params);
|
|
if(slowBBHandle == INVALID_HANDLE) {
|
|
::Print("BB on slow TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
params[0].integer_value = fastBBPeriod;
|
|
params[1].integer_value = fastBBShift;
|
|
fastBBHandle = std::GetHandle(_Symbol,fastTf,IND_BANDS,params);
|
|
if(fastBBHandle == INVALID_HANDLE) {
|
|
::Print("BB on fast TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
MqlParam array[];
|
|
AOHandle = std::GetHandle(_Symbol,fastTf,IND_AO,array);
|
|
if(AOHandle == INVALID_HANDLE) {
|
|
::Print("AO on fast TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
params[0].integer_value = fastAO_MA;
|
|
params[1].integer_value = 0;
|
|
params[2].type = TYPE_INT;
|
|
params[2].integer_value = MODE_SMA;
|
|
params[3].integer_value = AOHandle;
|
|
fastAO_MAHandle = std::GetHandle(_Symbol,fastTf,IND_MA,params);
|
|
if(fastAO_MAHandle == INVALID_HANDLE) {
|
|
::Print("Fast MA from AO on fast TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
params[0].integer_value = slowAO_MA;
|
|
slowAO_MAHandle = std::GetHandle(_Symbol,fastTf,IND_MA,params);
|
|
if(slowAO_MAHandle == INVALID_HANDLE) {
|
|
::Print("Slow MA from AO on fast TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
params[0].integer_value = fastMACD;
|
|
params[1].integer_value = slowMACD;
|
|
params[2].type = TYPE_INT;
|
|
params[2].integer_value = smaMACD;
|
|
params[3].integer_value = PRICE_CLOSE;
|
|
MACDHandle = std::GetHandle(_Symbol,fastTf,IND_MACD,params);
|
|
if(MACDHandle == INVALID_HANDLE) {
|
|
::Print("MACD on fast TF handlig error ",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
|
|
if(!::FileIsExist(STRUCT_FILENAME)) {
|
|
::Print("File ",STRUCT_FILENAME," not found! Creating new file");
|
|
if(!std::fileWriteBinStuct(STRUCT_FILENAME,points)) {
|
|
::Print("Creating file ",STRUCT_FILENAME," error #",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
}
|
|
::Print("File ",STRUCT_FILENAME," is in system");
|
|
if(!::FileIsExist(SET_FILENAME)){
|
|
SSettings sets;
|
|
setupSetStruct(sets);
|
|
if(!std::fileWriteBinStuct(SET_FILENAME,points)) {
|
|
::Print("Creating file ",SET_FILENAME," error #",::GetLastError());
|
|
return INIT_FAILED;
|
|
}
|
|
}
|
|
else{
|
|
::Print("File ",SET_FILENAME," is in system");
|
|
SSettings curSets,saveSets;
|
|
setupSetStruct(curSets);
|
|
std::fileReadBinStuct(SET_FILENAME,saveSets);
|
|
if(curSets != saveSets){
|
|
resetStructure();
|
|
std::fileWriteBinStuct(SET_FILENAME,curSets);
|
|
}
|
|
}
|
|
|
|
posParams[0].type = TYPE_STRING;
|
|
posParams[0].string_value = _Symbol;
|
|
posParams[1].type = TYPE_UINT;
|
|
posParams[1].integer_value = inMagic;
|
|
//---
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//---
|
|
std::fileWriteBinStuct(STRUCT_FILENAME,points);
|
|
SSettings sets;
|
|
setupSetStruct(sets);
|
|
std::fileWriteBinStuct(SET_FILENAME,sets);
|
|
//---
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
//---
|
|
//Block open position tracking
|
|
if(t != ::iTime(_Symbol,PERIOD_M1,0)) {
|
|
t = ::iTime(_Symbol,PERIOD_M1,0);
|
|
|
|
if(std::CountPositions(posParams) <= 0) {
|
|
points.onePoint = 0;
|
|
points.zeroPoint = 0;
|
|
} else {
|
|
if(!::PositionSelect(_Symbol)) {
|
|
t = 0;
|
|
}
|
|
|
|
double pos_sl = ::PositionGetDouble(POSITION_SL);
|
|
ulong pos_id = ::PositionGetInteger(POSITION_IDENTIFIER);
|
|
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)::PositionGetInteger(POSITION_TYPE);
|
|
double pos_volume = ::PositionGetDouble(POSITION_VOLUME);
|
|
if(pos_sl <= 0)
|
|
SetStop(::PositionGetInteger(POSITION_IDENTIFIER));
|
|
|
|
double l1{0.0},l2{0.0},l3{0.0};
|
|
int fibo = std::DistPrices(points.zeroPoint,points.onePoint,_Symbol);
|
|
if(pos_type == POSITION_TYPE_SELL) {
|
|
l1 = points.zeroPoint - LevelDist(fibo,close50Percent) * _Point;
|
|
l2 = points.zeroPoint - LevelDist(fibo,close30Percent) * _Point;
|
|
l3 = points.zeroPoint - LevelDist(fibo,close20Percent) * _Point;
|
|
} else {
|
|
l1 = points.zeroPoint + LevelDist(fibo,close50Percent) * _Point;
|
|
l2 = points.zeroPoint + LevelDist(fibo,close30Percent) * _Point;
|
|
l3 = points.zeroPoint + LevelDist(fibo,close20Percent) * _Point;
|
|
}
|
|
|
|
double close_level{0.0};
|
|
int count = GetClosedParts(pos_id,pos_volume);
|
|
if(count == 0) {
|
|
::Print("Error history access. Error ",::GetLastError());
|
|
t = 0;
|
|
return;
|
|
} else if(count == 1)
|
|
close_level = l1;
|
|
else if(close_level == 2)
|
|
close_level = l2;
|
|
else
|
|
close_level = l3;
|
|
|
|
if(pos_type == POSITION_TYPE_BUY) {
|
|
|
|
if(::iClose(_Symbol,PERIOD_M1,1) >= close_level) {
|
|
|
|
double lot{0.0};
|
|
if(close_level == l1)
|
|
lot = std::LotNormalize(pos_volume * 0.5,_Symbol);
|
|
else if(close_level == l2)
|
|
lot = std::LotNormalize(pos_volume * 0.3,_Symbol);
|
|
else
|
|
lot = pos_volume;
|
|
|
|
if(!std::Close_PartPosition(pos_id,lot,inSlipage)) {
|
|
t = 0;
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
if(::iClose(_Symbol,PERIOD_M1,1) <= close_level) {
|
|
|
|
double lot{0.0};
|
|
if(close_level == l1)
|
|
lot = std::LotNormalize(pos_volume * 0.5,_Symbol);
|
|
else if(close_level == l2)
|
|
lot = std::LotNormalize(pos_volume * 0.3,_Symbol);
|
|
else
|
|
lot = pos_volume;
|
|
|
|
if(!std::Close_PartPosition(pos_id,lot,inSlipage)) {
|
|
t = 0;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(slowT != ::iTime(_Symbol,slowTf,0)) {
|
|
slowT = ::iTime(_Symbol,slowTf,0);
|
|
|
|
double BBarrayUp[],BBarrayDn[];
|
|
if(!::CopyBuffer(slowBBHandle,1,0,2,BBarrayUp) || !::CopyBuffer(slowBBHandle,2,0,2,BBarrayDn)) {
|
|
slowT = 0;
|
|
return;
|
|
}
|
|
::ArraySetAsSeries(BBarrayUp,true);
|
|
::ArraySetAsSeries(BBarrayDn,true);
|
|
|
|
double MAarray[];
|
|
if(!::CopyBuffer(slowMAHandle,0,0,2,MAarray)) {
|
|
slowT = 0;
|
|
return;
|
|
}
|
|
::ArraySetAsSeries(MAarray,true);
|
|
|
|
if(::iClose(_Symbol,slowTf,1) > MAarray[1])
|
|
signalFlag = 1;
|
|
else if(::iClose(_Symbol,slowTf,1) < MAarray[1])
|
|
signalFlag = 2;
|
|
else
|
|
signalFlag = 0;
|
|
|
|
if(signalFlag == 1) {
|
|
if(::iClose(_Symbol,slowTf,1) < BBarrayDn[1])
|
|
isSignal = true;
|
|
} else if(signalFlag == 2) {
|
|
if(::iClose(_Symbol,slowTf,1) > BBarrayUp[1])
|
|
isSignal = true;
|
|
}
|
|
|
|
if(signalFlag > 0 && isSignal && globalFlag <= 0){
|
|
if(IsAbsorbingSignal(_Symbol,1)){
|
|
if(signalFlag == 1)
|
|
globalFlag = 1;
|
|
if(signalFlag == 2)
|
|
globalFlag = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(fastT != ::iTime(_Symbol,fastTf,0)) {
|
|
fastT = ::iTime(_Symbol,fastTf,0);
|
|
|
|
if(!inAllowTrade)
|
|
return;
|
|
|
|
if(std::CountPositions(posParams) > 0) {
|
|
ResetSignal();
|
|
return;
|
|
}
|
|
|
|
if(signalFlag <= 0 || !isSignal || globalFlag <= 0)
|
|
return;
|
|
|
|
double AOarray[],MACDarray[];
|
|
if(!::CopyBuffer(AOHandle,0,0,2,AOarray)) {
|
|
fastT = 0;
|
|
return;
|
|
}
|
|
::ArraySetAsSeries(AOarray,true);
|
|
|
|
if(!::CopyBuffer(MACDHandle,1,0,2,MACDarray)) {
|
|
fastT = 0;
|
|
return;
|
|
}
|
|
::ArraySetAsSeries(MACDarray,true);
|
|
|
|
if(isSignal && signalFlag == 1) {
|
|
|
|
if(AOarray[1] > 0 && MACDarray[1] > 50) {
|
|
ResetSignal();
|
|
return;
|
|
}
|
|
|
|
double s{0},z{0};
|
|
if(IsAbsorbingUp(_Symbol,fastTf,1,s,z)
|
|
|| IsDoubleAbsorbingUp(_Symbol,fastTf,1,s,z)
|
|
|| IsTripleAbsorbingUp(_Symbol,fastTf,1,s,z)) {
|
|
|
|
::Print("=== Absorbing up find ===");
|
|
::Print("Zero point = ",::DoubleToString(z,_Digits),"\tEnd point = ",::DoubleToString(s,_Digits));
|
|
|
|
if(AOarray[1] < 0 && MACDarray[1] < 50) {
|
|
points.zeroPoint = z;
|
|
points.onePoint = s;
|
|
int fibo = std::DistPrices(z,s,_Symbol);
|
|
int sl_dist = LevelDist(fibo,inStopLevel);
|
|
double sl = points.onePoint - sl_dist * _Point - inFiltr * _Point;
|
|
|
|
double cur = ::SymbolInfoDouble(_Symbol,SYMBOL_ASK);
|
|
double acc = ::AccountInfoDouble(ACCOUNT_BALANCE);
|
|
double lot = std::LotSize(_Symbol,ORDER_TYPE_BUY,cur,sl,acc,inRisk);
|
|
if(lot <= 0)
|
|
lot = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
|
|
ulong pos = std::Open_Buy_Pos(_Symbol,lot,inSlipage,inMagic);
|
|
if(pos <= 0) {
|
|
fastT = 0;
|
|
return;
|
|
}
|
|
if(!std::Position_SLTP(pos,sl,0.0)) {
|
|
fastT = 0;
|
|
return;
|
|
}
|
|
ResetSignal();
|
|
}
|
|
}
|
|
} else if(isSignal && signalFlag == 2) {
|
|
|
|
if(AOarray[1] < 0 && MACDarray[1] < 50) {
|
|
ResetSignal();
|
|
return;
|
|
}
|
|
|
|
double s{0},z{0};
|
|
if(IsAbsorbingDn(_Symbol,fastTf,1,s,z)
|
|
|| IsDoubleAbsorbingDn(_Symbol,fastTf,1,s,z)
|
|
|| IsTripleAbsorbingDn(_Symbol,fastTf,1,s,z)) {
|
|
|
|
::Print("=== Absorbing down find ===");
|
|
::Print("Zero point = ",::DoubleToString(z,_Digits),"\tEnd point = ",::DoubleToString(s,_Digits));
|
|
|
|
if(AOarray[1] > 0 && MACDarray[1] > 50) {
|
|
points.zeroPoint = z;
|
|
points.onePoint = s;
|
|
int fibo = std::DistPrices(z,s,_Symbol);
|
|
int sl_dist = LevelDist(fibo,inStopLevel);
|
|
double sl = points.onePoint + sl_dist * _Point + inFiltr * _Point;
|
|
|
|
double cur = ::SymbolInfoDouble(_Symbol,SYMBOL_BID);
|
|
double acc = ::AccountInfoDouble(ACCOUNT_BALANCE);
|
|
double lot = std::LotSize(_Symbol,ORDER_TYPE_SELL,cur,sl,acc,inRisk);
|
|
if(lot <= 0)
|
|
lot = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
|
|
ulong pos = std::Open_Sell_Pos(_Symbol,lot,inSlipage,inMagic);
|
|
if(pos <= 0) {
|
|
fastT = 0;
|
|
return;
|
|
}
|
|
if(!std::Position_SLTP(pos,sl,0.0)) {
|
|
fastT = 0;
|
|
return;
|
|
}
|
|
ResetSignal();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//---
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void SetStop(const ulong pos)
|
|
{
|
|
::ResetLastError();
|
|
if(!::PositionSelectByTicket(pos))
|
|
return;
|
|
|
|
int fibo_dist = std::DistPrices(points.onePoint,points.zeroPoint,_Symbol);
|
|
int sl_points = (int)::ceil(fibo_dist * inStopLevel);
|
|
|
|
if(!std::Position_SLTP(pos,sl_points,0)) {
|
|
::Print("Stop-loss set up failed. Error ",::GetLastError());
|
|
return;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void ResetSignal()
|
|
{
|
|
//points.onePoint = 0;
|
|
//points.zeroPoint = 0;
|
|
signalFlag = 0;
|
|
isSignal = false;
|
|
globalFlag = 0;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int LevelDist(const int size,const double dec)
|
|
{
|
|
return ((int)(::ceil(size * dec)));
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
void resetStructure(){
|
|
points.onePoint = 0;
|
|
points.zeroPoint = 0;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int GetClosedParts(const ulong position,double &volume)
|
|
{
|
|
if(!::HistorySelectByPosition(position))
|
|
return 0;
|
|
|
|
int count = ::HistoryDealsTotal();
|
|
if(count == 2) {
|
|
for(int i = 0;i < count;i++) {
|
|
ulong deal = ::HistoryDealGetTicket(i);
|
|
if(::HistoryDealGetInteger(deal,DEAL_ENTRY) == DEAL_ENTRY_IN) {
|
|
volume = ::HistoryDealGetDouble(deal,DEAL_VOLUME);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
bool IsAbsorbingSignal(const string symbol,const int index){
|
|
|
|
if(signalFlag <= 0)
|
|
return false;
|
|
|
|
double open = ::iOpen(symbol,slowTf,1);
|
|
double close = ::iClose(symbol,slowTf,1);
|
|
if(signalFlag == 1 && open > close)
|
|
return false;
|
|
if(signalFlag == 2 && open < close)
|
|
return false;
|
|
|
|
if(signalFlag > 0){
|
|
|
|
int history = 0;
|
|
switch(inLifeTime){
|
|
case LIFETIME_SIGNAL_DAY:
|
|
history = 6;
|
|
break;
|
|
case LIFETIME_SIGNAL_WEEK:
|
|
history = 30;
|
|
break;
|
|
case LIFETIME_SIGNAL_TWO_WEEKS:
|
|
history = 60;
|
|
break;
|
|
case LIFETIME_SIGNAL_MONTH:
|
|
history = 120;
|
|
break;
|
|
}
|
|
|
|
double buffer[];
|
|
int ctrl_candle = 0;
|
|
if(signalFlag == 1){
|
|
if(!::CopyBuffer(slowBBHandle,2,0,history,buffer))
|
|
return false;
|
|
for(int i = 1;i < history;i++){
|
|
if(::iClose(symbol,slowTf,i) > buffer[i])
|
|
continue;
|
|
if(iOpen(symbol,slowTf,i) > ::iClose(symbol,slowTf,i)){
|
|
ctrl_candle = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(close > ::iOpen(symbol,slowTf,ctrl_candle))
|
|
return true;
|
|
}
|
|
else{
|
|
if(!::CopyBuffer(slowBBHandle,1,0,history,buffer))
|
|
return false;
|
|
for(int i = 1;i < history;i++){
|
|
if(::iClose(symbol,slowTf,i) < buffer[i])
|
|
continue;
|
|
if(iOpen(symbol,slowTf,i) < ::iClose(symbol,slowTf,i)){
|
|
ctrl_candle = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(close < ::iOpen(symbol,slowTf,ctrl_candle))
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
void setupSetStruct(SSettings &sets){
|
|
sets.allowTrade = inAllowTrade;
|
|
sets.fastAO_MA = fastAO_MA;
|
|
sets.fastBBPeriod = fastBBPeriod;
|
|
sets.fastBBShift = fastBBShift;
|
|
sets.fastMACD = fastMACD;
|
|
sets.fastTf = fastTf;
|
|
sets.slowBBPeriod = slowBBPeriod;
|
|
sets.slowBBShift = slowBBShift;
|
|
sets.slowMACD = slowMACD;
|
|
sets.slowMAPeriod = slowMAPeriod;
|
|
sets.slowAO_MA = slowAO_MA;
|
|
sets.slowTf = slowTf;
|
|
sets.slipage = inSlipage;
|
|
sets.inLifeTime = inLifeTime;
|
|
sets.inFiltr = inFiltr;
|
|
sets.inStopLevel = inStopLevel;
|
|
sets.smaMACD = smaMACD;
|
|
sets.close20Percent = close20Percent;
|
|
sets.close30Percent = close30Percent;
|
|
sets.close50Percent = close50Percent;
|
|
sets.outComm = inOutComm;
|
|
sets.inRisk = inRisk;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
void OnTradeTransaction(const MqlTradeTransaction &trans,const MqlTradeRequest &request,const MqlTradeResult &result){
|
|
|
|
if(trans.type == TRADE_TRANSACTION_DEAL_ADD){
|
|
ulong deal = trans.deal;
|
|
::HistoryDealSelect(deal);
|
|
string symbol = ::HistoryDealGetString(deal,DEAL_SYMBOL);
|
|
uint magic = (uint)::HistoryDealGetInteger(deal,DEAL_MAGIC);
|
|
if(symbol == _Symbol && magic == inMagic){
|
|
if(::HistoryDealGetInteger(deal,DEAL_REASON) == DEAL_REASON_SL){
|
|
ResetSignal();
|
|
resetStructure();
|
|
}
|
|
}
|
|
}
|
|
} |