//+------------------------------------------------------------------+ //| ea_template.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //| Пример советника для использования с моделями нейронныхсетей, | //| представленнымив книге "Нейросети в алготрейдинге на MQL5" | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //--- input parameters sinput string Model = "our_model.net"; sinput int BarsToPattern = 40; sinput bool Common = true; input ENUM_TIMEFRAMES TimeFrame = PERIOD_M5; input double TradeLevel = 0.9; input double Lot = 0.01; input int MaxTP = 500; input double ProfitMultiply = 0.8; input int MinTarget = 100; input int StopLoss = 300; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include #include CNet *net; CTrade *trade; datetime lastbar = 0; int h_RSI; int h_MACD; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- net = new CNet(); if(CheckPointer(net) == POINTER_INVALID) { PrintFormat("Error of create Net: %d", GetLastError()); return INIT_FAILED; } if(!net.Load(Model, Common)) { PrintFormat("Error of load mode %s: %d", Model, GetLastError()); return INIT_FAILED; } //--- h_RSI = iRSI(_Symbol, TimeFrame, 12, PRICE_TYPICAL); if(h_RSI == INVALID_HANDLE) { PrintFormat("Error of load indicator %s", "RSI"); return INIT_FAILED; } h_MACD = iMACD(_Symbol, TimeFrame, 12, 48, 12, PRICE_TYPICAL); if(h_MACD == INVALID_HANDLE) { PrintFormat("Error of load indicator %s", "MACD"); return INIT_FAILED; } //--- trade = new CTrade(); if(CheckPointer(trade) == POINTER_INVALID) { PrintFormat("Error of create CTrade: %d", GetLastError()); return INIT_FAILED; } if(!trade.SetTypeFillingBySymbol(_Symbol)) return INIT_FAILED; //--- lastbar = TimeCurrent(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(CheckPointer(net) == POINTER_DYNAMIC) delete net; if(CheckPointer(trade) == POINTER_DYNAMIC) delete trade; IndicatorRelease(h_RSI); IndicatorRelease(h_MACD); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(lastbar >= iTime(_Symbol, TimeFrame, 0)) return; lastbar = iTime(_Symbol, TimeFrame, 0); //--- double macd_main[], macd_signal[], rsi[]; if(h_RSI == INVALID_HANDLE || CopyBuffer(h_RSI, 0, 1, BarsToPattern, rsi) <= 0) { PrintFormat("Error of load indicator %s data", "RSI"); return; } if(h_MACD == INVALID_HANDLE || CopyBuffer(h_MACD, MAIN_LINE, 1, BarsToPattern, macd_main) <= 0 || CopyBuffer(h_MACD, SIGNAL_LINE, 1, BarsToPattern, macd_signal) <= 0) { PrintFormat("Error of load indicator %s data", "MACD"); return; } CBufferDouble *input_data = new CBufferDouble(); if(CheckPointer(input_data) == POINTER_INVALID) { PrintFormat("Error of create Input data array: %d", GetLastError()); return; } for(int i = 0; i < BarsToPattern; i++) { if(!input_data.Add(rsi[i])) { PrintFormat("Error of add Input data to array: %d", GetLastError()); delete input_data; return; } if(!input_data.Add(macd_main[i])) { PrintFormat("Error of add Input data to array: %d", GetLastError()); delete input_data; return; } if(!input_data.Add(macd_signal[i])) { PrintFormat("Error of add Input data to array: %d", GetLastError()); delete input_data; return; } if(!input_data.Add(macd_main[i] - macd_signal[i])) { PrintFormat("Error of add Input data to array: %d", GetLastError()); delete input_data; return; } } if(CheckPointer(net) == POINTER_INVALID) { delete input_data; return; } if(!net.FeedForward(input_data)) { PrintFormat("Error of Feed Forward: %d", GetLastError()); delete input_data; return; } if(!net.GetResults(input_data)) { PrintFormat("Error of Get Result: %d", GetLastError()); delete input_data; return; } if(input_data.At(0) > 0.0) { bool opened = false; for(int i = 0; i < PositionsTotal(); i++) { if(PositionGetSymbol(i) != _Symbol) continue; if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) opened = true; } if(opened) { delete input_data; return; } if(input_data.At(0) < TradeLevel || input_data.At(1) < (MinTarget * SymbolInfoDouble(_Symbol, SYMBOL_POINT))) { delete input_data; return; } double tp = SymbolInfoDouble(_Symbol, SYMBOL_BID) + MathMin(input_data.At(1) * ProfitMultiply, MaxTP * SymbolInfoDouble(_Symbol, SYMBOL_POINT)); double sl = SymbolInfoDouble(_Symbol, SYMBOL_BID) - StopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT); trade.Buy(Lot, _Symbol, 0, sl, tp); } if(input_data.At(0) < 0) { bool opened = false; for(int i = 0; i < PositionsTotal(); i++) { if(PositionGetSymbol(i) != _Symbol) continue; if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) opened = true; } if(opened) { delete input_data; return; } if(input_data.At(0) > -TradeLevel || input_data.At(1) > -(MinTarget * SymbolInfoDouble(_Symbol, SYMBOL_POINT))) { delete input_data; return; } double tp = SymbolInfoDouble(_Symbol, SYMBOL_BID) + MathMax(input_data.At(1) * ProfitMultiply, -MaxTP * SymbolInfoDouble(_Symbol, SYMBOL_POINT)); double sl = SymbolInfoDouble(_Symbol, SYMBOL_BID) + StopLoss * SymbolInfoDouble(_Symbol, SYMBOL_POINT); trade.Sell(Lot, _Symbol, 0, sl, tp); } delete input_data; } //+------------------------------------------------------------------+