//+------------------------------------------------------------------+ //| RawTrading.mq5 | //| René Richartz | //| http://forexfox.info | //+------------------------------------------------------------------+ #property copyright "René Richartz" #property link "http://forexfox.info" #property version "2.00" #include #include #include #include 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); } //+------------------------------------------------------------------+