RawTrading/RawTrading.mq5
super.admin ab24b2345d convert
2025-05-30 16:20:06 +02:00

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);
}
//+------------------------------------------------------------------+