| //+------------------------------------------------------------------+
|
| //| BollingerBandsEA.mq5 |
|
| //| Copyright 2024, Igor Widiger |
|
| //| https://www.mql5.com/en/users/deinschanz |
|
| //+------------------------------------------------------------------+
|
| #property copyright "Copyright 2024, Igor Widiger"
|
| #property link "https://www.mql5.com/en/users/deinschanz"
|
| #property version "2.00"
|
|
|
|
|
| input ulong Magic = 111111111111; // Magic number
|
| enum my_lots {
|
| fixed_volume = 1, // Fixed volume
|
| procent_volume = 2, // Procent volume
|
| };
|
| input my_lots volumetype = procent_volume; // Volume type
|
|
|
| input double Risk = 1; // Risk for Position
|
| input double Lots = 0.10; // Lots
|
| input int Stopp = 100; // Stoploss in points
|
| input int MinutesAfterSessionStart = 420; // Trading (minutes) begins after session start
|
| input int MinutesBeforSessionStart = 5; // Trading (minutes) end before session
|
| input bool ClosePos = false; // Close position after indicator
|
| input bool Trall = true; // Allow trailing stop?
|
| input int ProfitFactor = 2; // Profit factor (RR) after stop is pulled
|
| input bool Break = false; // Allow breakeven?
|
| input int ProfitFactor2 = 1; // Profit factor (RR) after stop is pulled
|
| input int ClosePosMinutes = 30; // Close position if it is in minus (after minutes)
|
|
|
|
|
| #include <Trade/Trade.mqh>
|
| #include <Trade/SymbolInfo.mqh>
|
|
|
|
|
| int handleBp, handleMa;
|
| static datetime timestamp;
|
| static double lot = 0;
|
|
|
| CTrade trade;
|
| CSymbolInfo m_symbol;
|
| CPositionInfo m_position;
|
| CHistoryOrderInfo m_history;
|
| CDealInfo m_deal;
|
|
|
| int OnInit() {
|
|
|
| handleBp = iBands(_Symbol,PERIOD_CURRENT,20,0,2.000,PRICE_CLOSE);
|
| handleMa = iMA(_Symbol,PERIOD_D1,100,0,MODE_SMA,PRICE_CLOSE);
|
|
|
| //---
|
| trade.SetExpertMagicNumber(Magic);
|
| //---
|
| trade.SetMarginMode();
|
| trade.SetTypeFillingBySymbol(m_symbol.Name());
|
|
|
| return(INIT_SUCCEEDED);
|
| }
|
|
|
| void OnDeinit(const int reason) {
|
|
|
|
|
| }
|
|
|
| void OnTick() {
|
|
|
|
|
| // Sessioncheck
|
| if(IsInTradingSession(_Symbol) == false) return;
|
|
|
| int bars = iBars(_Symbol,PERIOD_CURRENT);
|
|
|
| datetime time = iTime(_Symbol,PERIOD_CURRENT,0);
|
|
|
| double DayHigh = iHigh(NULL,PERIOD_D1,0); // Day High Period
|
| double DayLow = iLow(NULL,PERIOD_D1,0); // Day Low Period
|
| double DayHigh1 = iHigh(NULL,PERIOD_D1,1); // Day High Period
|
| double DayLow1 = iLow(NULL,PERIOD_D1,1); // Day Low Period
|
|
|
| double DayHighPrice = 0;
|
| double DayLowPrice = 0;
|
| double DayHighPrice1 = 0;
|
| double DayLowPrice1 = 0;
|
|
|
| if(timestamp != time) {
|
| timestamp = time;
|
|
|
| DayHighPrice = DayHigh;
|
| DayLowPrice = DayLow;
|
|
|
| DayHighPrice1 = DayHigh1;
|
| DayLowPrice1 = DayLow1;
|
|
|
| }
|
|
|
| double close1 = iClose(_Symbol,PERIOD_CURRENT,1);
|
| double high0 = iHigh(_Symbol,PERIOD_CURRENT,0);
|
| double low0 = iLow(_Symbol,PERIOD_CURRENT,0);
|
| double high1 = iHigh(_Symbol,PERIOD_CURRENT,1);
|
| double low1 = iLow(_Symbol,PERIOD_CURRENT,1);
|
|
|
| double ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
|
| ask = NormalizeDouble(ask,_Digits);
|
| double bid = SymbolInfoDouble(_Symbol,SYMBOL_BID);
|
| bid = NormalizeDouble(bid,_Digits);
|
|
|
|
|
| double bbUpper[], bbLowwer[], bbMiddle[];
|
| CopyBuffer(handleBp,BASE_LINE,1,2,bbMiddle);
|
| CopyBuffer(handleBp,UPPER_BAND,1,2,bbUpper);
|
| CopyBuffer(handleBp,LOWER_BAND,1,2,bbLowwer);
|
|
|
| // Range middle upper and lowwer line
|
| double rangeUpper = (bbUpper[1] - bbMiddle[1])/_Point;
|
| double rangeLowwer = (bbMiddle[1] -bbLowwer[1])/_Point;
|
|
|
| // Ma indikator
|
| double ma[];
|
| CopyBuffer(handleMa,MAIN_LINE,1,1,ma);
|
|
|
|
|
| // Close position after indicator
|
| if(ClosePos == true) {
|
| for(int i=PositionsTotal()-1; i>=0; i--) // Returns the number of open positions
|
| if(m_position.SelectByIndex(i)) {
|
| //---
|
| if(m_position.Symbol()== _Symbol && m_position.Magic()==Magic) { // Checks for symbol and magic number
|
| if(m_position.PositionType()==POSITION_TYPE_BUY) {
|
|
|
| if(bid >= bbMiddle[0]) {
|
| ClosePos(_Symbol);
|
| }
|
|
|
| } else {
|
| if(ask <= bbMiddle[0]) {
|
| ClosePos(_Symbol);
|
| }
|
|
|
| }
|
|
|
| }
|
| }
|
| }
|
|
|
| // Trailingstop
|
| if(Trall == true) {
|
| Trailing(_Symbol);
|
| }
|
| // Breakeven
|
| if(Break == true) {
|
| Breakeven(_Symbol);
|
| }
|
|
|
| // End trade after time if order is positiv
|
| datetime AktZeit=TimeCurrent();
|
| HistorySelect(0,TimeCurrent());
|
| for(int pos=HistoryDealsTotal()-1; pos>=0; pos--) {
|
| if(m_position.SelectByIndex(pos)) {
|
| // Read deal out and get deal time
|
| if(m_position.Symbol()==_Symbol && m_position.Magic()==Magic) {
|
| datetime close_time = m_position.Time();
|
| datetime adierentime = close_time + (ClosePosMinutes*60);
|
|
|
| if(AktZeit >= adierentime && AProfit() > 0) {
|
| ClosePos(_Symbol);
|
| return;
|
| }
|
| }
|
| }
|
| }
|
|
|
| // Start trading for profit the next day!
|
| if(Profit(0) > 0) {
|
| return;
|
| }
|
|
|
|
|
| if(CalculateOnePositions(_Symbol) >= 1)
|
| return;
|
|
|
| if(close1 > bbUpper[1] && bid > bbUpper[1] && rangeUpper > Stopp*2 && ask < ma[0]) {
|
| if(bid > DayHighPrice || bid > DayHighPrice1) {
|
|
|
| if(ProfitSell(0) < 0) return;
|
|
|
| double newSl = 0;
|
| if(high1 > high0) {
|
| newSl = high1;
|
| } else if(high1 < high0) {
|
| newSl = high0;
|
| } else {
|
| return; // Kein Trade
|
| }
|
|
|
| double sl = newSl + Stopp*_Point;
|
| double tp = DayLow;
|
|
|
|
|
|
|
| // Calculate SL in points
|
| double Points = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
| double SlPoints = (sl - ask) / _Point;
|
|
|
| if(volumetype == 2) {
|
| lot = NormalizeDouble(LotsByRisk(ORDER_TYPE_SELL,Risk,(int)SlPoints,_Symbol,Points),2);
|
| } else {
|
| lot= Lots;
|
| }
|
|
|
|
|
| double volume = lot;
|
| volume=LotCheck(volume, _Symbol);
|
| if(volume==0)
|
| return;
|
|
|
| if(!CheckStopLoss_Takeprofit(ORDER_TYPE_SELL,sl,tp)) {
|
| return;
|
| }
|
| double max_volume=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_LIMIT);
|
| double current_lots=getAllVolume();
|
|
|
| if(max_volume>0 && max_volume-volume<=0) {
|
| return;
|
| }
|
|
|
| trade.Sell(volume,_Symbol,bid,sl,tp);
|
| }
|
| } else if(close1 < bbLowwer[1] && ask < bbLowwer[1] && rangeLowwer > Stopp*2 && bid > ma[0]) {
|
| if(ask < DayLowPrice || ask < DayLowPrice1) {
|
|
|
| if(ProfitBuy(0) < 0) return;
|
|
|
| double newSl = 0;
|
| if(low1 > low0) {
|
| newSl = low0;
|
| } else if(low1 < low0) {
|
| newSl = low1;
|
| } else {
|
| return; // Kein Trade
|
| }
|
| double sl = newSl - Stopp*_Point;
|
| double tp = DayHigh;
|
|
|
| // Calculate SL in points
|
| double Points = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
|
| double SlPoints = (bid - sl)/_Point;
|
|
|
| if(volumetype == 2) {
|
| lot = NormalizeDouble(LotsByRisk(ORDER_TYPE_BUY,Risk,(int)SlPoints,_Symbol,Points),2);
|
| } else {
|
| lot= Lots;
|
| }
|
|
|
| double volume = lot;
|
| volume=LotCheck(volume, _Symbol);
|
| if(volume==0)
|
| return;
|
|
|
| if(!CheckStopLoss_Takeprofit(ORDER_TYPE_BUY,sl,tp)) {
|
| return;
|
| }
|
| double max_volume=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_LIMIT);
|
| double current_lots=getAllVolume();
|
|
|
| if(max_volume>0 && max_volume-volume<=0) {
|
| return;
|
| }
|
|
|
| trade.Buy(volume,_Symbol,ask,sl,tp);
|
| }
|
| }
|
|
|
|
|
|
|
|
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Calculate one positions |
|
| //+------------------------------------------------------------------+
|
| int CalculateOnePositions(string ssymBol) {
|
| int total=0;
|
| for(int i=PositionsTotal()-1; i>=0; i--)
|
| if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
|
| if(m_position.Symbol() == ssymBol && m_position.Magic()==Magic) { // Checks by magic number end Symbol
|
| total++;
|
| //---
|
| }
|
| return(total);
|
| }
|
| //+------------------------------------------------------------------+
|
| // Close position function
|
| void ClosePos(string symbolss) {
|
| for(int i=PositionsTotal()-1; i>=0; i--)
|
| if(m_position.SelectByIndex(i))
|
| if(m_position.Symbol()== _Symbol && m_position.Magic()==Magic) { // Checks by symbol and magic number
|
| trade.PositionClose(m_position.Ticket());
|
| }
|
| }
|
| //------------- Profit sell ausrechnen Funktion ---------------------------
|
| double ProfitSell(int ai_0) {
|
|
|
| // HistorySelect(von_datum,zum_datum);
|
| HistorySelect(iTime(_Symbol,PERIOD_D1,ai_0),iTime(_Symbol,PERIOD_D1,ai_0)+60*60*24);
|
| double gewonnene_trade=0.0;
|
| double verlorene_trade=0.0;
|
| double total_profit=0.0;
|
| uint total=HistoryDealsTotal();
|
| ulong ticket=0;
|
|
|
| //--- for all deals
|
| for(uint i=0; i<total; i++) {
|
| //--- Sucht nach Tickets die grösser als Null sind
|
| if((ticket=HistoryDealGetTicket(i))>0) {
|
| long entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
|
| if(entry==DEAL_ENTRY_IN)
|
| continue;
|
|
|
| string symbol = HistoryDealGetString(ticket,DEAL_SYMBOL);
|
| long order_magic = HistoryDealGetInteger(ticket,DEAL_MAGIC);
|
| double deal_commission = HistoryDealGetDouble(ticket,DEAL_COMMISSION);
|
| double deal_swap = HistoryDealGetDouble(ticket,DEAL_SWAP);
|
| double deal_profit = HistoryDealGetDouble(ticket,DEAL_PROFIT);
|
| double profit=deal_commission+deal_swap+deal_profit;
|
|
|
| ENUM_DEAL_TYPE deal_type= (ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket, DEAL_TYPE);
|
| long dreason= (int)HistoryDealGetInteger(ticket,DEAL_REASON);
|
|
|
| if(deal_type!=DEAL_TYPE_BUY)
|
| continue;
|
|
|
| if(order_magic==Magic) {
|
| //... processing of deal with some DEAL_MAGIC
|
| if(symbol==_Symbol && dreason==(DEAL_REASON_SL)) {
|
| if(profit<0.0)
|
| verlorene_trade+=profit;
|
| total_profit+=profit;
|
| }
|
| }
|
| }
|
| }
|
| return(total_profit);
|
| }
|
| //------------- Profit sell ausrechnen Funktion ---------------------------
|
| double ProfitBuy(int ai_0) {
|
|
|
| // HistorySelect(von_datum,zum_datum);
|
| HistorySelect(iTime(_Symbol,PERIOD_D1,ai_0),iTime(_Symbol,PERIOD_D1,ai_0)+60*60*24);
|
| double gewonnene_trade=0.0;
|
| double verlorene_trade=0.0;
|
| double total_profit=0.0;
|
| uint total=HistoryDealsTotal();
|
| ulong ticket=0;
|
|
|
| //--- for all deals
|
| for(uint i=0; i<total; i++) {
|
| //--- Searches for tickets greater than zero
|
| if((ticket=HistoryDealGetTicket(i))>0) {
|
| long entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
|
| if(entry==DEAL_ENTRY_IN)
|
| continue;
|
|
|
| string symbol = HistoryDealGetString(ticket,DEAL_SYMBOL);
|
| long order_magic = HistoryDealGetInteger(ticket,DEAL_MAGIC);
|
| double deal_commission = HistoryDealGetDouble(ticket,DEAL_COMMISSION);
|
| double deal_swap = HistoryDealGetDouble(ticket,DEAL_SWAP);
|
| double deal_profit = HistoryDealGetDouble(ticket,DEAL_PROFIT);
|
| double profit=deal_commission+deal_swap+deal_profit;
|
|
|
|
|
| ENUM_DEAL_TYPE deal_type= (ENUM_DEAL_TYPE)HistoryDealGetInteger(ticket, DEAL_TYPE);
|
| if(deal_type!=DEAL_TYPE_SELL)
|
| continue;
|
|
|
| long dreason= (int)HistoryDealGetInteger(ticket,DEAL_REASON);
|
|
|
| if(order_magic==Magic) {
|
| //... processing of deal with some DEAL_MAGIC
|
| if(symbol==_Symbol && dreason==(DEAL_REASON_SL)) {
|
| if(profit<0.0)
|
| verlorene_trade+=profit;
|
| total_profit+=profit;
|
| }
|
| }
|
| }
|
| }
|
| return(total_profit);
|
| }
|
| //------------- Profit ausrechnen Funktion ---------------------------
|
| double Profit(int ai_0) {
|
|
|
| // HistorySelect(von_datum,zum_datum);
|
| HistorySelect(iTime(_Symbol,PERIOD_D1,ai_0),iTime(_Symbol,PERIOD_D1,ai_0)+60*60*24);
|
| double gewonnene_trade=0.0;
|
| double verlorene_trade=0.0;
|
| double total_profit=0.0;
|
| uint total=HistoryDealsTotal();
|
| ulong ticket=0;
|
|
|
| //--- for all deals
|
| for(uint i=0; i<total; i++) {
|
| //--- Sucht nach Tickets die grösser als Null sind
|
| if((ticket=HistoryDealGetTicket(i))>0) {
|
| long entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
|
| if(entry==DEAL_ENTRY_IN)
|
| continue;
|
|
|
| string symbol = HistoryDealGetString(ticket,DEAL_SYMBOL);
|
| long order_magic = HistoryDealGetInteger(ticket,DEAL_MAGIC);
|
| double deal_commission = HistoryDealGetDouble(ticket,DEAL_COMMISSION);
|
| double deal_swap = HistoryDealGetDouble(ticket,DEAL_SWAP);
|
| double deal_profit = HistoryDealGetDouble(ticket,DEAL_PROFIT);
|
| double profit=deal_commission+deal_swap+deal_profit;
|
| if(order_magic==Magic) {
|
| //... processing of deal with some DEAL_MAGIC
|
| if(symbol==_Symbol) {
|
| if(profit>0.0)
|
| gewonnene_trade+=profit;
|
| if(profit<0.0)
|
| verlorene_trade+=profit;
|
| total_profit+=profit;
|
| }
|
| }
|
| }
|
| }
|
| return(total_profit);
|
| }
|
| //+------------------------------------------------------------------+
|
| double AProfit() {
|
| double pft=0;
|
| for(int i=PositionsTotal()-1; i>=0; i--) {
|
| ulong ticket=PositionGetTicket(i);
|
| if(ticket>0) {
|
| if(PositionGetInteger(POSITION_MAGIC)==Magic && PositionGetString(POSITION_SYMBOL)==_Symbol) {
|
| pft+=PositionGetDouble(POSITION_PROFIT);
|
| }
|
| }
|
| }
|
| return(pft);
|
| }
|
| //+------------------------------------------------------------------+
|
| // Trailing in % Function
|
| void Trailing(string symssBol) {
|
|
|
| int total=0;
|
| for(int j=PositionsTotal()-1; j>=0; j--)
|
| if(m_position.SelectByIndex(j)) // selects the position by index for further access to its properties
|
| if(m_position.Symbol()== symssBol && m_position.Magic()==Magic) { // Checks by symbol and magic number
|
| total++;
|
| }
|
|
|
| if(total<=0) {
|
| //Trailing no Positions
|
| return;
|
| }
|
|
|
| // Spannefunktion
|
| double RangeHigh = iHigh(NULL,PERIOD_D1,0);
|
| double RangeLow = iLow(NULL,PERIOD_D1,0);
|
| double RangeProzent = NormalizeDouble(((RangeHigh - RangeLow) / RangeHigh * 100),2);
|
| // 1
|
| double RangeHigh1 = iHigh(NULL,PERIOD_D1,1);
|
| double RangeLow1 = iLow(NULL,PERIOD_D1,1);
|
| double RangeProzent1 = NormalizeDouble(((RangeHigh1 - RangeLow1) / RangeHigh1 * 100),2);
|
| // 2
|
| double RangeHigh2 = iHigh(NULL,PERIOD_D1,2);
|
| double RangeLow2 = iLow(NULL,PERIOD_D1,2);
|
| double RangeProzent2 = NormalizeDouble(((RangeHigh2 - RangeLow2) / RangeHigh2 * 100),2);
|
| // 3
|
| double RangeHigh3 = iHigh(NULL,PERIOD_D1,3);
|
| double RangeLow3 = iLow(NULL,PERIOD_D1,3);
|
| double RangeProzent3 = NormalizeDouble(((RangeHigh3 - RangeLow3) / RangeHigh3 * 100),2);
|
| // 4
|
| double RangeHigh4 = iHigh(NULL,PERIOD_D1,4);
|
| double RangeLow4 = iLow(NULL,PERIOD_D1,4);
|
| double RangeProzent4 = NormalizeDouble(((RangeHigh4 - RangeLow4) / RangeHigh4 * 100),2);
|
|
|
| double RangeGes = (RangeProzent + RangeProzent1 + RangeProzent2 + RangeProzent3 + RangeProzent4)/5;
|
|
|
|
|
| // Trailling in procent
|
| int ProfitProzent;
|
| if(RangeProzent < RangeGes) {
|
| ProfitProzent = 50;
|
| } else {
|
| ProfitProzent = 75;
|
| }
|
|
|
| for(int i=PositionsTotal()-1; i>=0; i--) // Returns the number of open positions
|
|
|
| if(m_position.SelectByIndex(i)) {
|
| double price_current = m_position.PriceCurrent();
|
| double price_open = m_position.PriceOpen();
|
| double stop_loss = m_position.StopLoss();
|
| double take_profit = m_position.TakeProfit();
|
| datetime price_time = m_position.Time();
|
|
|
|
|
| //---
|
| if(m_position.Symbol()== symssBol && m_position.Magic()==Magic) { // Checks for symbol and magic number
|
| if(m_position.PositionType()==POSITION_TYPE_BUY) {
|
|
|
|
|
| int digits=(int)SymbolInfoInteger(symssBol,SYMBOL_DIGITS); // number of decimal places
|
| double point=SymbolInfoDouble(symssBol,SYMBOL_POINT); // point
|
| double Ask = NormalizeDouble(SymbolInfoDouble(symssBol,SYMBOL_ASK),digits); // Define Ask
|
| double Bid = NormalizeDouble(SymbolInfoDouble(symssBol,SYMBOL_BID),digits); // Define Bid
|
| double priceRangePoints = (Ask - price_open)/point;
|
| double price = price_open + (priceRangePoints/100*ProfitProzent)*point;
|
|
|
| // SL Range Buy
|
| double NeuSl = (((price_open - stop_loss)/point)*ProfitFactor);
|
| double SlRangeBuy = price_open + NeuSl * point;
|
|
|
|
|
| if(price > SlRangeBuy && price > stop_loss) {
|
| trade.PositionModify(m_position.Ticket(),price+(100/ProfitProzent)*_Point,take_profit);
|
| }
|
|
|
| } else if(m_position.PositionType()==POSITION_TYPE_SELL) {
|
|
|
| int digits=(int)SymbolInfoInteger(symssBol,SYMBOL_DIGITS); // number of decimal places
|
| double point=SymbolInfoDouble(symssBol,SYMBOL_POINT); // point
|
| double Ask = NormalizeDouble(SymbolInfoDouble(symssBol,SYMBOL_ASK),digits); // Define Ask
|
| double Bid = NormalizeDouble(SymbolInfoDouble(symssBol,SYMBOL_BID),digits); // Define Bid
|
| double priceRangePoints = (price_open - Bid)/point;
|
| double price = price_open - (priceRangePoints/100*ProfitProzent)*point;
|
|
|
| // SL Range Sell
|
| double NeuSl = (((stop_loss - price_open)/point)*ProfitFactor);
|
| double SlRangeSell = price_open - NeuSl * point;
|
|
|
|
|
| if(price < SlRangeSell && stop_loss > price) {
|
| trade.PositionModify(m_position.Ticket(),price-(100/ProfitProzent)*_Point,take_profit);
|
| }
|
| } else {
|
|
|
| }
|
| }
|
| }
|
| ChartRedraw(0);
|
|
|
| }
|
|
|
| // Breakeven
|
| void Breakeven(string symBreakeven) {
|
| for(int i=PositionsTotal()-1; i>=0; i--) // Returns the number of open positions
|
| if(m_position.SelectByIndex(i)) {
|
|
|
| double price_current = m_position.PriceCurrent();
|
| double price_open = m_position.PriceOpen();
|
| double stop_loss = m_position.StopLoss();
|
| double take_profit = m_position.TakeProfit();
|
|
|
| int digits = (int)SymbolInfoInteger(symBreakeven,SYMBOL_DIGITS); // number of decimal places
|
| double point = SymbolInfoDouble(symBreakeven,SYMBOL_POINT); // point
|
| ulong Spread = SymbolInfoInteger(_Symbol,SYMBOL_SPREAD); // Define Spread
|
|
|
| //---
|
| if(m_position.Symbol()== symBreakeven && m_position.Magic()==Magic) { // Checks for symbol and magic number
|
| if(m_position.PositionType()==POSITION_TYPE_BUY) {
|
|
|
| double SlNewPrice = 0.0;
|
| double SlRangeBuy = (price_open - stop_loss)/point;
|
| SlNewPrice = price_open + ((SlRangeBuy*ProfitFactor2)*point);
|
|
|
|
|
| if(stop_loss < price_open && price_current > SlNewPrice) {
|
| if(price_current > price_open)
|
| trade.PositionModify(m_position.Ticket(),price_open,take_profit);
|
| }
|
| } else {
|
|
|
| double SlNewPrice = 0.0;
|
| double SlRangeSell = (stop_loss - price_open)/point;
|
| SlNewPrice = price_open - ((SlRangeSell*ProfitFactor2)*point);
|
|
|
| if(stop_loss > price_open && price_current < SlNewPrice) {
|
| if(price_current< price_open)
|
| trade.PositionModify(m_position.Ticket(),price_open,take_profit);
|
| }
|
| }
|
| }
|
| }
|
| }
|
| //+------------------------------------------------------------------+
|
| bool IsInTradingSession(string symbole) {
|
| MqlDateTime mqt;
|
| if(TimeToStruct(TimeTradeServer(),mqt)) {
|
| //flatten
|
| ENUM_DAY_OF_WEEK dow=(ENUM_DAY_OF_WEEK)mqt.day_of_week;
|
| mqt.hour=0;
|
| mqt.min=0;
|
| mqt.sec=0;
|
| datetime base=StructToTime(mqt),get_from=0,get_to=0;
|
| //now loop in all the trading sessions
|
| uint session=0;
|
| while(SymbolInfoSessionTrade(symbole,dow,session,get_from,get_to)) {
|
| //so if this succeeds a session exists and fills up get from and get to , but it just fills up with hour , minute + second
|
| //that means we have to project it on the base time we flattened above for today
|
| get_from=(datetime)(base+get_from);
|
| get_to=(datetime)(base+get_to);
|
| //and we pump one session in
|
| session++;
|
| //and we check , if we happen to be inside that range , we return true because we can trade
|
| if(TimeTradeServer()>=get_from&&TimeTradeServer()<=get_to) {
|
|
|
| // Start trading after the specified time after the start of the season!
|
| datetime TimeStart = get_from + MinutesAfterSessionStart*60; // Start Trading
|
| datetime TimeSesEnd = get_to - MinutesBeforSessionStart*60; // Ends Trading
|
|
|
| // Trading Start
|
| if(TimeTradeServer()>=get_from && TimeTradeServer()<= TimeStart) {
|
| return(true);
|
| }
|
| // trading end
|
| if(TimeTradeServer()<=get_to && TimeTradeServer()>= TimeSesEnd) {
|
| return(true);
|
| }
|
|
|
| return(true);
|
| } else {
|
| // Print("market closed: ");
|
| }
|
| }
|
| }
|
| return(false);
|
| }
|
| //+------------------------------------------------------------------+
|
| //+------------------------------------------------------------------+
|
| //| Calculate Volume with stop in % |
|
| //+------------------------------------------------------------------+
|
| double LotsByRisk(int op_type,double risk,int sloss, string Sym_Name, double points) {
|
| double lot_min = SymbolInfoDouble(Sym_Name,SYMBOL_VOLUME_MIN);
|
| double lot_max = SymbolInfoDouble(Sym_Name,SYMBOL_VOLUME_MAX);
|
| double lot_step = SymbolInfoDouble(Sym_Name,SYMBOL_VOLUME_STEP);
|
| double lotcost = ((SymbolInfoDouble(Sym_Name, SYMBOL_TRADE_TICK_VALUE)*points)/(SymbolInfoDouble(Sym_Name,SYMBOL_TRADE_TICK_SIZE)));
|
| lot = 0.0;
|
| double UsdPerPip = 0.0;
|
|
|
| lot = AccountInfoDouble(ACCOUNT_BALANCE)*risk/100;
|
| UsdPerPip = lot/sloss;
|
| if(UsdPerPip <= 0.0)
|
| return(0);
|
| lot = NormalizeDouble(UsdPerPip/lotcost, 2);
|
| if(lot <= 0.0)
|
| return(0);
|
| lot = NormalizeDouble(lot/lot_step, 0) * lot_step;
|
| if(lot < lot_min)
|
| lot = lot_min;
|
| if(lot > lot_max)
|
| lot = lot_max;
|
| return(lot);
|
| }
|
| //+------------------------------------------------------------------+
|
| //| Lot Check |
|
| //+------------------------------------------------------------------+
|
| double LotCheck(double lots, string SymName) {
|
| //--- calculate maximum volume
|
| double volume=NormalizeDouble(lots,2);
|
| double stepvol=SymbolInfoDouble(SymName,SYMBOL_VOLUME_STEP);
|
| if(stepvol>0.0)
|
| volume=stepvol*MathFloor(volume/stepvol);
|
| //---
|
| double minvol=SymbolInfoDouble(SymName,SYMBOL_VOLUME_MIN);
|
| if(volume<minvol)
|
| volume=0.0;
|
| //---
|
| double maxvol=SymbolInfoDouble(SymName,SYMBOL_VOLUME_MAX);
|
| if(volume>maxvol)
|
| volume=maxvol;
|
| return(volume);
|
| }
|
| //+------------------------------------------------------------------+
|
| // Check Sl TP
|
| bool CheckStopLoss_Takeprofit(ENUM_ORDER_TYPE type,double SL,double TP) {
|
|
|
| double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
|
| double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
|
| //--- Let's get the SYMBOL_TRADE_STOPS_LEVEL level
|
| int stops_level=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
|
| if(stops_level!=0) {
|
| PrintFormat("SYMBOL_TRADE_STOPS_LEVEL=%d: StopLoss and TakeProfit must not be closer"+
|
| " as %d points from the exit price",stops_level,stops_level);
|
| }
|
| //---
|
| bool SL_check=false,TP_check=false;
|
| //--- Let's examine only two types of orders
|
| switch(type) {
|
| //--- The buying operation
|
| case ORDER_TYPE_BUY: {
|
| //--- Let's check StopLoss
|
| SL_check=(Bid-SL>stops_level*_Point);
|
| if(!SL_check)
|
| PrintFormat("For order %s StopLoss=%.5f must be less than %.5f"+
|
| " (Bid=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
| EnumToString(type),SL,Bid-stops_level*_Point,Bid,stops_level);
|
| //--- Let's check TakeProfit
|
| TP_check=(TP-Bid>stops_level*_Point);
|
| if(!TP_check)
|
| PrintFormat("For order %s TakeProfit=%.5f must be greater than %.5f"+
|
| " (Bid=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
| EnumToString(type),TP,Bid+stops_level*_Point,Bid,stops_level);
|
| //--- we return the result of the verification
|
| return(SL_check&&TP_check);
|
| }
|
| //--- The sale operation
|
| case ORDER_TYPE_SELL: {
|
| //--- Let's check StopLoss
|
| SL_check=(SL-Ask>stops_level*_Point);
|
| if(!SL_check)
|
| PrintFormat("For order %s StopLoss=%.5f must be greater than %.5f "+
|
| " (Ask=%.5f + SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
| EnumToString(type),SL,Ask+stops_level*_Point,Ask,stops_level);
|
| //--- Let's check TakeProfit
|
| TP_check=(Ask-TP>stops_level*_Point);
|
| if(!TP_check)
|
| PrintFormat("For order %s TakeProfit=%.5f must be less than %.5f "+
|
| " (Ask=%.5f - SYMBOL_TRADE_STOPS_LEVEL=%d points)",
|
| EnumToString(type),TP,Ask-stops_level*_Point,Ask,stops_level);
|
| //--- we return the result of the verification
|
| return(TP_check&&SL_check);
|
| }
|
| break;
|
| }
|
| //--- For the pending orders you need another function
|
| return false;
|
| }
|
| //+------------------------------------------------------------------+
|
| //volume counting function
|
| double getAllVolume() {
|
| int itotal=PositionsTotal();
|
| ulong uticket=-1;
|
| double dVolume=0;
|
|
|
| for(int i=itotal-1; i>=0; i--) {
|
| if(!(uticket=PositionGetTicket(i))) continue;
|
|
|
| if(PositionGetString(POSITION_SYMBOL)==m_symbol.Name())
|
| dVolume+=PositionGetDouble(POSITION_VOLUME);
|
| }
|
|
|
| itotal=OrdersTotal();
|
|
|
| for(int i=itotal-1; i>=0; i--) {
|
| if(!(uticket=OrderGetTicket(i))) continue;
|
|
|
| if(OrderGetString(ORDER_SYMBOL)==m_symbol.Name())
|
| dVolume+=OrderGetDouble(ORDER_VOLUME_CURRENT);
|
| }
|
|
|
| return dVolume;
|
| }
|
| //+------------------------------------------------------------------+
|