680 lines
49 KiB
MQL5
680 lines
49 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| RawTrading.mq5 |
|
|
//| René Richartz |
|
|
//| http://forexfox.info |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "René Richartz"
|
|
#property link "http://forexfox.info"
|
|
#property version "2.00"
|
|
|
|
#include <trade\Trade.mqh>
|
|
#include <trade\SymbolInfo.mqh>
|
|
#include <Trade\AccountInfo.mqh>
|
|
#include <Database.mqh>
|
|
|
|
CPositionInfo m_position;
|
|
CTrade m_trade;
|
|
CSymbolInfo m_symbol;
|
|
CAccountInfo m_account;
|
|
|
|
input group "Parameter"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
input double Pips2Trade = 5.0; // Pips Abstand zu Close Price (Entry Level)
|
|
input double atrRatio = 2.0; // StopLoss & TakeProfit Faktor ATR
|
|
input double atrEntryFactor = 1.0; // Body Size Min Entry Faktor ATR
|
|
input double atrExitFactor = 0.1; // Body Size Min + Exit Faktor ATR
|
|
|
|
input bool TradeShort = false;
|
|
input bool TradeLong = false;
|
|
|
|
input double LotSize = 0.1;
|
|
|
|
input int mvShort = 12;
|
|
input int mvMid = 20;
|
|
input int mvLong = 40;
|
|
input int ATR = 14;
|
|
|
|
input group "Sonstiges"
|
|
input int indicator_width1 = 10;
|
|
input int indicator_width2 = 2;
|
|
input int myRates = 15;
|
|
input double TrendLineSize = 0.002;
|
|
|
|
string dbFileName = "Logging.sqlite";
|
|
int myMagic = 4711;
|
|
int myDigits = 4;
|
|
datetime lastbar_timeopen;
|
|
MqlDateTime myLastTime;
|
|
int mql_program;
|
|
|
|
double myPips2Trade, myatrRatio, myatrEntryFactor, myatrExitFactor, myErgebnis, myProfit, myLotSize;
|
|
string myTimeFrame;
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Expert initialization function |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
//--- create timer
|
|
EventSetTimer(60 * 15);
|
|
|
|
MathSrand(10);
|
|
myMagic = MathRand();
|
|
m_trade.SetExpertMagicNumber(myMagic);
|
|
|
|
myDigits = _Digits - 1;
|
|
|
|
mql_program = MQLInfoInteger(MQL_OPTIMIZATION);
|
|
|
|
//--- Wenn Trading, dann Testergebnisse laden
|
|
if(mql_program == 0)
|
|
if(!dbLoadTestResult())
|
|
{
|
|
Print("DBLOAD:");
|
|
ExpertRemove();
|
|
return(INIT_FAILED);
|
|
|
|
}
|
|
else
|
|
{
|
|
//--- **************************************
|
|
//--- Parameterzuordnung zu Parameterfeldern
|
|
//--- **************************************
|
|
// Chart Timeframe setzen
|
|
long chartID = ChartID();
|
|
|
|
if(myTimeFrame == "PERIOD_M30")
|
|
ChartSetSymbolPeriod(chartID, _Symbol, PERIOD_M30);
|
|
|
|
if(myTimeFrame == "PERIOD_H1")
|
|
ChartSetSymbolPeriod(chartID, _Symbol, PERIOD_H1);
|
|
|
|
if(myTimeFrame == "PERIOD_H2")
|
|
ChartSetSymbolPeriod(chartID, _Symbol, PERIOD_H2);
|
|
|
|
if(myTimeFrame == "PERIOD_H4")
|
|
ChartSetSymbolPeriod(chartID, _Symbol, PERIOD_H4);
|
|
|
|
|
|
if(myProfit > 600.0)
|
|
myLotSize = 0.02;
|
|
else
|
|
myLotSize = 0.01;
|
|
|
|
Comment("Init : Database -- " + DoubleToString(myPips2Trade,0) + "," + DoubleToString(myatrRatio,1) + "," + DoubleToString(myatrEntryFactor,1) + "," + DoubleToString(myatrExitFactor,1) + "," + DoubleToString(ChartID(),0) + "," + myTimeFrame);
|
|
}
|
|
|
|
if(mql_program == 1)
|
|
{
|
|
//--- **************************************
|
|
//--- Parameterzuordnung zu EA-Feldern
|
|
myPips2Trade = Pips2Trade;
|
|
myatrRatio = atrRatio;
|
|
myatrEntryFactor = atrEntryFactor;
|
|
myatrExitFactor = atrExitFactor;
|
|
myLotSize = LotSize;
|
|
//--- **************************************
|
|
}
|
|
|
|
//---
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert deinitialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
//--- destroy timer
|
|
EventKillTimer();
|
|
dbSaveTestResult();
|
|
|
|
|
|
CDatabase db(dbFileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
|
|
if(!db.IsAvaliable()) //check is avaliable
|
|
return;
|
|
|
|
string request = "DELETE FROM TESTERRESULT WHERE Symbol = '" + _Symbol + "' AND TimeFrame = '" + EnumToString(_Period) + "' AND Ergebnis < 2.0";
|
|
db.Execute(request);
|
|
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Expert tick function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTick()
|
|
{
|
|
//---
|
|
//---
|
|
|
|
MqlDateTime tm;
|
|
TimeLocal(tm);
|
|
|
|
bool dayChange = false;
|
|
if(tm.day != myLastTime.day)
|
|
{
|
|
dayChange = true;
|
|
}
|
|
TimeLocal(myLastTime);
|
|
|
|
|
|
if(tm.hour == 23 && tm.day_of_week == FRIDAY)
|
|
if(m_position.Select(_Symbol))
|
|
{
|
|
m_trade.PositionClose(_Symbol, -1);
|
|
return;
|
|
}
|
|
|
|
if(tm.day_of_week == SATURDAY)
|
|
return;
|
|
|
|
if(tm.day_of_week == SUNDAY)
|
|
return;
|
|
|
|
|
|
// if(dayChange)
|
|
// Sleep(100 * 60 * 15);
|
|
|
|
// Stop Loss
|
|
if(m_position.Select(_Symbol))
|
|
{
|
|
//Print(_Symbol + ":" + EnumToString(_Period) + " Offene Position, lösche Pending Orders");
|
|
deletePending();
|
|
}
|
|
|
|
if(isNewBar())
|
|
{
|
|
|
|
// Candle 1 is last candle
|
|
MqlRates rates[];
|
|
ArraySetAsSeries(rates, true);
|
|
int copied = CopyRates(_Symbol, _Period, 0, myRates, rates);
|
|
if(copied < myRates)
|
|
return;
|
|
|
|
//--- Heikin Ashi
|
|
double haClose = (rates[1].open + rates[1].high + rates[1].low + rates[1].close) / 4;
|
|
double haOpen = (rates[2].open + rates[2].close) / 2;
|
|
double haHigh = MathMax(rates[1].high, MathMax(haOpen, haClose));
|
|
double haLow = MathMin(rates[1].low, MathMin(haOpen, haClose));
|
|
|
|
bool haBuy = haClose > haOpen && haLow == haOpen;
|
|
bool haSell = haOpen > haClose && haHigh == haOpen;
|
|
|
|
//--- Trendbestimmung
|
|
double mvaShort = myMVA(mvShort);
|
|
double mvaLong = myMVA(mvLong);
|
|
|
|
bool Uptrend = ((mvaShort > mvaLong) && (rates[1].low > mvaShort));
|
|
bool Downtrend = ((mvaShort < mvaLong) && (rates[1].high < mvaShort));
|
|
|
|
if(Uptrend && haBuy)
|
|
{
|
|
DrawTrendLine(rates[1].time, rates[1].high, rates[1].time, NormalizeDouble(rates[1].high + TrendLineSize, _Digits), clrGreen);
|
|
DrawHAcandle(rates[1].time, haOpen, haHigh, haLow, haClose, clrBlue);
|
|
}
|
|
|
|
if(Downtrend && haSell)
|
|
{
|
|
DrawHAcandle(rates[1].time, haOpen, haHigh, haLow, haClose, clrRed);
|
|
DrawTrendLine(rates[1].time, rates[1].low, rates[1].time, NormalizeDouble(rates[1].low - TrendLineSize, _Digits), clrYellow);
|
|
}
|
|
|
|
double ATR14 = myATR(14);
|
|
|
|
// Cleanup
|
|
//Print(_Symbol + ":" + EnumToString(_Period) + " Neue Bar, lösche Pending Orders");
|
|
deletePending();
|
|
|
|
|
|
// Closing
|
|
if(m_position.Select(_Symbol))
|
|
{
|
|
|
|
}
|
|
|
|
// Changing
|
|
if(m_position.Select(_Symbol))
|
|
{
|
|
// Offene Buy Position = 0
|
|
if(m_position.PositionType() == 1)
|
|
{
|
|
|
|
}
|
|
|
|
if(m_position.PositionType() == 0)
|
|
{
|
|
//
|
|
}
|
|
//Sleep(100 * 60);
|
|
}
|
|
|
|
// Opening
|
|
if(!m_position.Select(_Symbol))
|
|
{
|
|
RefreshRates();
|
|
double Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
|
double Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
|
datetime Expiring = TimeCurrent() + PERIOD_H8;
|
|
// Sell Position
|
|
if(Downtrend && haSell)
|
|
{
|
|
double SellPrice = NormalizeDouble(rates[1].close - (myPips2Trade / 10000), myDigits);
|
|
if(Bid < SellPrice)
|
|
return;//SellPrice = Bid;
|
|
double SellSL = NormalizeDouble(SellPrice + myatrRatio * ATR14, myDigits);
|
|
double SellTP = NormalizeDouble(SellPrice - myatrRatio * ATR14, myDigits);
|
|
Print(DoubleToString(_Digits,0) + ":" + DoubleToString(myDigits,0));
|
|
Print(_Symbol + ":" + EnumToString(_Period) + "OPENING SELLSTOP AT (" + DoubleToString(Bid) + ") " + DoubleToString(SellPrice) + "- SL " + DoubleToString(SellSL) + "- TP " + DoubleToString(SellTP));
|
|
if(TradeShort)
|
|
int test = m_trade.SellStop(myLotSize, SellPrice, _Symbol, SellSL, SellTP, ORDER_TIME_DAY, Expiring, NULL);
|
|
|
|
}
|
|
|
|
// Buy Position
|
|
if(Uptrend && haBuy)
|
|
{
|
|
double BuyPrice = NormalizeDouble(rates[1].close + (myPips2Trade / 10000), myDigits);
|
|
if(Ask > BuyPrice)
|
|
return; //BuyPrice = Ask;
|
|
double BuySL = NormalizeDouble(BuyPrice - myatrRatio * ATR14, myDigits);
|
|
double BuyTP = NormalizeDouble(BuyPrice + myatrRatio * ATR14, myDigits);
|
|
Print(DoubleToString(_Digits,0) + ":" + DoubleToString(myDigits,0));
|
|
Print(_Symbol + ":" + EnumToString(_Period) + "OPENING BUYSTOP AT (" + DoubleToString(Ask) + ") " + DoubleToString(BuyPrice) + "- SL " + DoubleToString(BuySL) + "- TP " + DoubleToString(BuyTP));
|
|
if(TradeLong)
|
|
int test = m_trade.BuyStop(myLotSize, BuyPrice, _Symbol, BuySL, BuyTP, ORDER_TIME_DAY, Expiring, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dayChange = false;
|
|
|
|
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Timer function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTimer()
|
|
{
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TradeTransaction function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTradeTransaction(const MqlTradeTransaction& trans,
|
|
const MqlTradeRequest& request,
|
|
const MqlTradeResult& result)
|
|
{
|
|
//---
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Tester function |
|
|
//+------------------------------------------------------------------+
|
|
double OnTester()
|
|
{
|
|
//---
|
|
double ret = 0.0;
|
|
//---
|
|
|
|
//---
|
|
return(ret);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TesterInit function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTesterInit()
|
|
{
|
|
//---
|
|
CDatabase db(dbFileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
|
|
if(!db.IsAvaliable()) //check is avaliable
|
|
return;
|
|
|
|
string request = "DELETE FROM TESTERRESULT WHERE Symbol = '" + _Symbol + "' AND TimeFrame = '" + EnumToString(_Period) + "'";
|
|
db.Execute(request);
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TesterPass function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTesterPass()
|
|
{
|
|
//---
|
|
// NIX
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| TesterDeinit function |
|
|
//+------------------------------------------------------------------+
|
|
void OnTesterDeinit()
|
|
{
|
|
//---
|
|
// NIX
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool RefreshRates()
|
|
{
|
|
|
|
//--- refresh rates
|
|
if(!m_symbol.RefreshRates())
|
|
{
|
|
Print(__FILE__, " ", __FUNCTION__, ", ERROR: ", "RefreshRates error");
|
|
return(false);
|
|
}
|
|
//--- protection against the return value of "zero"
|
|
if(m_symbol.Ask() == 0 || m_symbol.Bid() == 0)
|
|
{
|
|
Print(__FILE__, " ", __FUNCTION__, ", ERROR: ", "Ask == 0.0 OR Bid == 0.0");
|
|
return(false);
|
|
}
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool isNewBar()
|
|
{
|
|
static datetime bartime = 0; // store open time of the current bar
|
|
//--- get open time of the zero bar
|
|
datetime currbar_time = iTime(_Symbol, _Period, 0);
|
|
//--- if open time changes, a new bar has arrived
|
|
if(bartime != currbar_time)
|
|
{
|
|
bartime = currbar_time;
|
|
lastbar_timeopen = bartime;
|
|
//--- display data on open time of a new bar in the log
|
|
|
|
//--- we have a new bar
|
|
return (true);
|
|
}
|
|
//--- no new bar
|
|
return (false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double myMVA(int counts)
|
|
{
|
|
|
|
// create an Array for several prices
|
|
double myMovingAverageArray[];
|
|
// define the properties of the Moving Average
|
|
int movingAverageDefinition = iMA(_Symbol, _Period, counts, 0, MODE_SMA, PRICE_CLOSE);
|
|
// sort the price array from the current candle downwards
|
|
ArraySetAsSeries(myMovingAverageArray, true);
|
|
// Defined EA, one line,current candle,3 candles, store result
|
|
CopyBuffer(movingAverageDefinition, 0, 0, 3, myMovingAverageArray);
|
|
// calculate EA for the current candle
|
|
double myMovingAverageValue = myMovingAverageArray[0];
|
|
return myMovingAverageValue;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double myATR(int counts)
|
|
{
|
|
|
|
// create an Array for several prices
|
|
double myPriceArrayATR[];
|
|
// define the properties of the AverageTrueRangeValue EA
|
|
int AverageTrueRangeDefinition = iATR(_Symbol, _Period, counts);
|
|
// sort the price array from the current candle downwards
|
|
ArraySetAsSeries(myPriceArrayATR, true);
|
|
// Defined MA1, one line,current candle,3 candles, store result
|
|
CopyBuffer(AverageTrueRangeDefinition, 0, 0, 3, myPriceArrayATR);
|
|
// Get the value of the current candle
|
|
double AverageTrueRangeValue = NormalizeDouble(myPriceArrayATR[0], 5);
|
|
return AverageTrueRangeValue;
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void DrawHAcandle(const datetime &time, const double &open_price, const double &high_price, const double &low_price, const double &close_price, const color candle_color)
|
|
{
|
|
|
|
string object_name1 = "body_" + DoubleToString(time);
|
|
|
|
if(ObjectFind(0, object_name1))
|
|
ObjectDelete(0, object_name1);
|
|
|
|
if(!ObjectCreate(0, object_name1, OBJ_TREND, 0, time, open_price, time, close_price))
|
|
Print(__FUNCTION__, ": error ", GetLastError());
|
|
|
|
ObjectSetInteger(0, object_name1, OBJPROP_WIDTH, indicator_width1);
|
|
ObjectSetInteger(0, object_name1, OBJPROP_COLOR, candle_color);
|
|
ObjectSetInteger(0, object_name1, OBJPROP_RAY, true);
|
|
ObjectSetInteger(0, object_name1, OBJPROP_HIDDEN, true);
|
|
ObjectSetInteger(0, object_name1, OBJPROP_SELECTABLE, false);
|
|
|
|
string object_name2 = "wick_" + TimeToString(time);
|
|
|
|
if(ObjectFind(0, object_name2))
|
|
ObjectDelete(0, object_name2);
|
|
|
|
if(!ObjectCreate(0, object_name2, OBJ_TREND, 0, time, high_price, time, low_price))
|
|
Print(__FUNCTION__, ": error ", GetLastError());
|
|
|
|
ObjectSetInteger(0, object_name2, OBJPROP_WIDTH, indicator_width2);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_COLOR, candle_color);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_RAY, true);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_HIDDEN, true);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_SELECTABLE, false);
|
|
|
|
|
|
return;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void DrawTrendLine(const datetime Time1, const double Price1, const datetime Time2, const double Price2, const color candle_color)
|
|
{
|
|
|
|
string object_name2 = ("TrendLine " + TimeToString(Time1) + DoubleToString(Price1,myDigits));
|
|
|
|
if(ObjectFind(0, object_name2))
|
|
ObjectDelete(0, object_name2);
|
|
|
|
if(!ObjectCreate(0, object_name2, OBJ_TREND, 0, Time1, Price1, Time2, Price2))
|
|
Print(__FUNCTION__, ": error ", GetLastError());
|
|
|
|
ObjectSetInteger(0, object_name2, OBJPROP_WIDTH, 5);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_COLOR, candle_color);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_RAY, true);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_HIDDEN, true);
|
|
ObjectSetInteger(0, object_name2, OBJPROP_SELECTABLE, false);
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool deletePending()
|
|
{
|
|
// Pending Orders schließen
|
|
int total_p = 0;
|
|
ulong ticket;
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
{
|
|
ticket = OrderGetTicket(i);
|
|
if(ticket > 0)
|
|
{
|
|
if(OrderGetInteger(ORDER_MAGIC) == myMagic && OrderGetString(ORDER_SYMBOL) == _Symbol && ticket != 0)
|
|
{
|
|
m_trade.OrderDelete(ticket);
|
|
Print("Delete ", ticket, " ", i);
|
|
Sleep(200);
|
|
}
|
|
}
|
|
}
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| TestErgebnis in Datenbank schreiben |
|
|
//+------------------------------------------------------------------+
|
|
void dbSaveTestResult()
|
|
{
|
|
Print("DBLogTestResult" + DoubleToString(TesterStatistics(STAT_TRADES),0));
|
|
|
|
MqlDateTime tm;
|
|
TimeCurrent(tm);
|
|
CDatabase db(dbFileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
|
|
if(!db.IsAvaliable()) //check is avaliable
|
|
return;
|
|
if(!db.HasTable("TesterResult"))
|
|
db.Execute("CREATE TABLE TesterResult (ID INT, DATE Text, Symbol Text, TimeFrame Text, Ergebnis NUM, Profit NUM, ProfitFaktor NUM, Trades INT, TradesLost INT, TradesWon INT, myPips2Trade NUM, myatrRatio NUM, myatrEntryFactor NUM, myatrExitFactor NUM);");
|
|
|
|
|
|
|
|
string request = StringFormat("insert into TesterResult (ID , DATE , Symbol , TimeFrame , Ergebnis , Profit , ProfitFaktor , Trades , TradesLost , TradesWon , myPips2Trade , myatrRatio , myatrEntryFactor , myatrExitFactor )"
|
|
+ " values ( %d, '" + TimeToString(TimeCurrent()) + "', '" + _Symbol + "','" + EnumToString(_Period) + "', %.2f, %.2f, %.2f, %d, %d, %d, %.2f, %.2f, %.2f, %.2f)"
|
|
, rand(), TesterStatistics(STAT_RECOVERY_FACTOR), TesterStatistics(STAT_PROFIT), TesterStatistics(STAT_PROFIT_FACTOR), TesterStatistics(STAT_TRADES), TesterStatistics(STAT_LOSS_TRADES), TesterStatistics(STAT_TRADES) - TesterStatistics(STAT_LOSS_TRADES), myPips2Trade, myatrRatio, myatrEntryFactor, myatrExitFactor);
|
|
|
|
|
|
db.Execute(request);
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
bool dbLoadTestResult()
|
|
{
|
|
|
|
//--- create or open the database in the common terminal folder
|
|
int db = DatabaseOpen(dbFileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
|
|
|
|
// Retry 1
|
|
if(db == INVALID_HANDLE)
|
|
{
|
|
db = DatabaseOpen(dbFileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
|
|
Print("retry1");
|
|
Sleep(2000);
|
|
}
|
|
|
|
// Retry 2
|
|
if(db == INVALID_HANDLE)
|
|
{
|
|
Print("retry2");
|
|
db = DatabaseOpen(dbFileName, DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
|
|
Sleep(2000);
|
|
}
|
|
|
|
// Retry 3
|
|
if(db == INVALID_HANDLE)
|
|
{
|
|
Print("retry3");
|
|
Print("DB: ", dbFileName, " open failed with code ", GetLastError());
|
|
return(false);
|
|
}
|
|
|
|
int request = DatabasePrepare(db, "SELECT MAX(Ergebnis), MAX(Profit), myPips2Trade, myatrRatio, myatrEntryFactor, myatrExitFactor, TimeFrame FROM TesterResult where Symbol = '" + _Symbol + "' and Ergebnis> 3.0");
|
|
if(request == INVALID_HANDLE)
|
|
{
|
|
Print("DB: ", dbFileName, " request failed with code ", GetLastError());
|
|
Print("select");
|
|
DatabaseClose(db);
|
|
return(false);
|
|
}
|
|
|
|
|
|
|
|
//--- print all entries with the salary greater than 15000
|
|
int x = DatabaseRead(request);
|
|
Print("DB: " + DoubleToString(x,0) + " Datensätze");
|
|
|
|
//--- read the values of each field from the obtained entry
|
|
if(DatabaseColumnDouble(request, 0, myErgebnis) &&
|
|
DatabaseColumnDouble(request, 1, myProfit) &&
|
|
DatabaseColumnDouble(request, 2, myPips2Trade) &&
|
|
DatabaseColumnDouble(request, 3, myatrRatio) &&
|
|
DatabaseColumnDouble(request, 4, myatrEntryFactor) &&
|
|
DatabaseColumnDouble(request, 5, myatrExitFactor) &&
|
|
DatabaseColumnText(request, 6, myTimeFrame) &&
|
|
x == 1)
|
|
{
|
|
//--- remove the query after use
|
|
DatabaseFinalize(request);
|
|
//--- close the database
|
|
DatabaseClose(db);
|
|
Print(myTimeFrame);
|
|
return(true);
|
|
}
|
|
else
|
|
{
|
|
Print(": DatabaseRead() failed with code ", GetLastError());
|
|
DatabaseFinalize(request);
|
|
DatabaseClose(db);
|
|
return(false);
|
|
}
|
|
return true;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
double last_deal()
|
|
{
|
|
double deal_price;
|
|
// --- time interval of the trade history needed
|
|
datetime end=TimeCurrent(); // current server time
|
|
datetime start=end-PeriodSeconds(PERIOD_D1);// decrease 1 day
|
|
//--- request of trade history needed into the cache of MQL5 program
|
|
HistorySelect(start,end);
|
|
//--- get total number of deals in the history
|
|
int deals=HistoryDealsTotal();
|
|
//--- get ticket of the deal with the last index in the list
|
|
ulong deal_ticket=HistoryDealGetTicket(deals-1);
|
|
if(deal_ticket>0) // deal has been selected, let's proceed ot
|
|
{
|
|
//--- ticket of the order, opened the deal
|
|
ulong order=HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
|
|
long order_magic=HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
|
|
long pos_ID=HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
|
|
deal_price=HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
|
|
double deal_volume=HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
|
|
PrintFormat("******** Deal: #%d opened by order: #%d with ORDER_MAGIC: %d was in position: #%f price: #%f volume:",
|
|
deals-1,order,order_magic,pos_ID,deal_price,deal_volume);
|
|
|
|
}
|
|
else // error in selecting of the deal
|
|
{
|
|
PrintFormat("Total number of deals %d, error in selection of the deal"+
|
|
" with index %d. Error %d",deals,deals-1,GetLastError());
|
|
}
|
|
return(deal_price);
|
|
}
|
|
//+------------------------------------------------------------------+
|