Der FRAMA FX Scalper handelt im Forex maximal 4 Trades pro Stunde
Der FRAMA Scalper wurde entwickelt, um in den Trendphasen innerhalb einer Stunde maximal 4 Trades auszuführen. Geschlossen werden die Positionen, wenn der Stop oder die Gewinnmitnahme-Ziele erreicht wurden. Es wurden zuvor die Pips für die SL und TP fixiert.
Signale werden mit der Fraktalen Adaptive Moving Average Methode ermittelt. Um in Drehpunkten Fehlsignale zu minimieren, wurde als zweite Bestätigung der Adaptive Moving Average basierend mit der Average True Range hinzugefühgt.
Video auf Youtube
Download diesen Bot – Expert Advisor
MetaTrader5 Code – Forex FRAMA FX Scalper
//+------------------------------------------------------------------+
//| Strategy: FRAMA SCALPER PRO.mq5 |
//| Created with EABuilder.com |
//| https://www.eabuilder.com |
//+------------------------------------------------------------------+
#property copyright "Created with EABuilder.com"
#property link "https://www.eabuilder.com"
#property version "1.00"
#property description ""
#property tester_indicator "ATR_MAs"
int LotDigits; //initialized in OnInit
input int MagicNumber = 373032;
input int NextOpenTradeAfterMinutes = 15; //next open trade after time
input int MaxTradeDurationBars = 10; //maximum trade duration
input double TradeSize = 0.1;
input int MaxSlippage = 3; //slippage, adjusted in OnInit
int MaxSlippage_;
int MaxOpenTrades = 1000;
int MaxLongTrades = 1000;
int MaxShortTrades = 1000;
int MaxPendingOrders = 1000;
int MaxLongPendingOrders = 1000;
int MaxShortPendingOrders = 1000;
input bool Hedging = true;
int OrderRetry = 5; //# of retries if sending order returns error
int OrderWait = 5; //# of seconds to wait if sending order returns error
double myPoint; //initialized in OnInit
int FrAMA_handle;
double FrAMA[];
int ATR_MAs_handle;
double ATR_MAs[];
void CloseByDuration(int sec) //close trades opened longer than sec seconds
{
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return;
bool success = false;
int err = 0;
int total = PositionsTotal();
ulong orderList[][2];
int orderCount = 0;
for(int i = 0; i < total; i++)
{
if(PositionGetTicket(i) <= 0) continue;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber || PositionGetString(POSITION_SYMBOL) != Symbol() || PositionGetInteger(POSITION_TIME) + sec > TimeCurrent()) continue;
orderCount++;
ArrayResize(orderList, orderCount);
orderList[orderCount - 1][0] = PositionGetInteger(POSITION_TIME);
orderList[orderCount - 1][1] = PositionGetInteger(POSITION_TICKET);
}
if(orderCount > 0)
ArraySort(orderList);
for(int i = 0; i < orderCount; i++)
{
if(!PositionSelectByTicket(orderList[i][1])) continue;
int type = (int)PositionGetInteger(POSITION_TYPE);
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
double price = (type == ORDER_TYPE_SELL) ? last_tick.ask : last_tick.bid;
MqlTradeRequest request;
ZeroMemory(request);
request.action = TRADE_ACTION_DEAL;
request.position = PositionGetInteger(POSITION_TICKET);
//set allowed filling type
int filling = (int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
if(request.action == TRADE_ACTION_DEAL && (filling & 1) != 1)
request.type_filling = ORDER_FILLING_IOC;
request.magic = MagicNumber;
request.symbol = Symbol();
request.volume = NormalizeDouble(PositionGetDouble(POSITION_VOLUME), LotDigits);
if (NormalizeDouble(request.volume, LotDigits) == 0) return;
request.price = NormalizeDouble(price, Digits());
request.sl = 0;
request.tp = 0;
request.deviation = MaxSlippage_;
request.type = (ENUM_ORDER_TYPE)(1-type); //opposite type
MqlTradeResult result;
ZeroMemory(result);
if(!OrderSend(request, result) || !OrderSuccess(result.retcode))
{
myAlert("error", "OrderClose failed; error: "+result.comment);
}
else myAlert("order", "Orders closed by duration: "+Symbol()+" Magic #"+IntegerToString(MagicNumber));
}
}
void myAlert(string type, string message)
{
if(type == "print")
Print(message);
else if(type == "error")
{
Print(type+" | FRAMA SCALPER PRO @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
}
else if(type == "order")
{
}
else if(type == "modify")
{
}
}
int TradesCount(ENUM_ORDER_TYPE type) //returns # of open trades for order type, current symbol and magic number
{
if(type <= 1)
{
int result = 0;
int total = PositionsTotal();
for(int i = 0; i < total; i++)
{
if(PositionGetTicket(i) <= 0) continue;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber || PositionGetString(POSITION_SYMBOL) != Symbol() || PositionGetInteger(POSITION_TYPE) != type) continue;
result++;
}
return(result);
}
else
{
int result = 0;
int total = OrdersTotal();
for(int i = 0; i < total; i++)
{
if(OrderGetTicket(i) <= 0) continue;
if(OrderGetInteger(ORDER_MAGIC) != MagicNumber || OrderGetString(ORDER_SYMBOL) != Symbol() || OrderGetInteger(ORDER_TYPE) != type) continue;
result++;
}
return(result);
}
}
ulong LastHistoryTradeTicket(int deal_io)
{
HistorySelect(0, TimeCurrent());
int total = HistoryDealsTotal();
ulong ticket = 0;
for(int i = total-1; i >= 0; i--)
{
if((ticket = HistoryDealGetTicket(i)) <= 0) continue;
if(HistoryDealGetString(ticket, DEAL_SYMBOL) == Symbol()
&& HistoryDealGetInteger(ticket, DEAL_MAGIC) == MagicNumber
&& HistoryDealGetInteger(ticket, DEAL_TYPE) <= 1 && HistoryDealGetInteger(ticket, DEAL_ENTRY) == deal_io)
return(ticket);
}
return(0);
}
datetime LastCloseTime()
{
ulong ticket = 0;
if((ticket = LastHistoryTradeTicket(DEAL_ENTRY_OUT)) > 0)
return((datetime)HistoryDealGetInteger(ticket, DEAL_TIME));
return(0);
}
ulong myOrderSend(ENUM_ORDER_TYPE type, double price, double volume, string ordername) //send order, return ticket ("price" is irrelevant for market orders)
{
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(0);
int retries = 0;
int long_trades = TradesCount(ORDER_TYPE_BUY);
int short_trades = TradesCount(ORDER_TYPE_SELL);
int long_pending = TradesCount(ORDER_TYPE_BUY_LIMIT) + TradesCount(ORDER_TYPE_BUY_STOP) + TradesCount(ORDER_TYPE_BUY_STOP_LIMIT);
int short_pending = TradesCount(ORDER_TYPE_SELL_LIMIT) + TradesCount(ORDER_TYPE_SELL_STOP) + TradesCount(ORDER_TYPE_SELL_STOP_LIMIT);
string ordername_ = ordername;
if(ordername != "")
ordername_ = "("+ordername+")";
//test Hedging
if(!Hedging && ((type % 2 == 0 && short_trades + short_pending > 0) || (type % 2 == 1 && long_trades + long_pending > 0)))
{
myAlert("print", "Order"+ordername_+" not sent, hedging not allowed");
return(0);
}
//test maximum trades
if((type % 2 == 0 && long_trades >= MaxLongTrades)
|| (type % 2 == 1 && short_trades >= MaxShortTrades)
|| (long_trades + short_trades >= MaxOpenTrades)
|| (type > 1 && type % 2 == 0 && long_pending >= MaxLongPendingOrders)
|| (type > 1 && type % 2 == 1 && short_pending >= MaxShortPendingOrders)
|| (type > 1 && long_pending + short_pending >= MaxPendingOrders)
)
{
myAlert("print", "Order"+ordername_+" not sent, maximum reached");
return(0);
}
//prepare to send order
MqlTradeRequest request;
ZeroMemory(request);
request.action = (type <= 1) ? TRADE_ACTION_DEAL : TRADE_ACTION_PENDING;
//set allowed filling type
int filling = (int)SymbolInfoInteger(Symbol(),SYMBOL_FILLING_MODE);
if(request.action == TRADE_ACTION_DEAL && (filling & 1) != 1)
request.type_filling = ORDER_FILLING_IOC;
request.magic = MagicNumber;
request.symbol = Symbol();
request.volume = NormalizeDouble(volume, LotDigits);
request.sl = 0;
request.tp = 0;
request.deviation = MaxSlippage_;
request.type = type;
request.comment = ordername;
int expiration=(int)SymbolInfoInteger(Symbol(), SYMBOL_EXPIRATION_MODE);
if((expiration & SYMBOL_EXPIRATION_GTC) != SYMBOL_EXPIRATION_GTC)
{
request.type_time = ORDER_TIME_DAY;
request.type_filling = ORDER_FILLING_RETURN;
}
MqlTradeResult result;
ZeroMemory(result);
while(!OrderSuccess(result.retcode) && retries < OrderRetry+1)
{
//refresh price before sending order
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
if(type == ORDER_TYPE_BUY)
price = last_tick.ask;
else if(type == ORDER_TYPE_SELL)
price = last_tick.bid;
else if(price < 0) //invalid price for pending order
{
myAlert("order", "Order"+ordername_+" not sent, invalid price for pending order");
return(0);
}
request.price = NormalizeDouble(price, Digits());
if(!OrderSend(request, result) || !OrderSuccess(result.retcode))
{
myAlert("print", "OrderSend"+ordername_+" error: "+result.comment);
Sleep(OrderWait*1000);
}
retries++;
}
if(!OrderSuccess(result.retcode))
{
myAlert("error", "OrderSend"+ordername_+" failed "+IntegerToString(OrderRetry+1)+" times; error: "+result.comment);
return(0);
}
string typestr[8] = {"Buy", "Sell", "Buy Limit", "Sell Limit", "Buy Stop", "Sell Stop", "Buy Stop Limit", "Sell Stop Limit"};
myAlert("order", "Order sent"+ordername_+": "+typestr[type]+" "+Symbol()+" Magic #"+IntegerToString(MagicNumber));
return(result.order);
}
int myOrderModify(ENUM_ORDER_TYPE type, ulong ticket, double SL, double TP) //modify SL and TP (absolute price), zero targets do not modify
{
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(-1);
bool netting = AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING;
int retries = 0;
int err = 0;
SL = NormalizeDouble(SL, Digits());
TP = NormalizeDouble(TP, Digits());
if(SL < 0) SL = 0;
if(TP < 0) TP = 0;
//prepare to select order
Sleep(10);
if((type <= 1 && ((netting && !PositionSelect(Symbol())) || (!netting && !PositionSelectByTicket(ticket)))) || (type > 1 && !OrderSelect(ticket)))
{
err = GetLastError();
myAlert("error", "PositionSelect / OrderSelect failed; error #"+IntegerToString(err));
return(-1);
}
//ignore open positions other than "type"
if (type <= 1 && PositionGetInteger(POSITION_TYPE) != type) return(0);
//prepare to modify order
double currentSL = (type <= 1) ? PositionGetDouble(POSITION_SL) : OrderGetDouble(ORDER_SL);
double currentTP = (type <= 1) ? PositionGetDouble(POSITION_TP) : OrderGetDouble(ORDER_TP);
if(NormalizeDouble(SL, Digits()) == 0) SL = currentSL; //not to modify
if(NormalizeDouble(TP, Digits()) == 0) TP = currentTP; //not to modify
if(NormalizeDouble(SL - currentSL, Digits()) == 0
&& NormalizeDouble(TP - currentTP, Digits()) == 0)
return(0); //nothing to do
MqlTradeRequest request;
ZeroMemory(request);
request.action = (type <= 1) ? TRADE_ACTION_SLTP : TRADE_ACTION_MODIFY;
if (type > 1)
request.order = ticket;
else
request.position = PositionGetInteger(POSITION_TICKET);
request.symbol = Symbol();
request.price = (type <= 1) ? PositionGetDouble(POSITION_PRICE_OPEN) : OrderGetDouble(ORDER_PRICE_OPEN);
request.sl = NormalizeDouble(SL, Digits());
request.tp = NormalizeDouble(TP, Digits());
request.deviation = MaxSlippage_;
MqlTradeResult result;
ZeroMemory(result);
while(!OrderSuccess(result.retcode) && retries < OrderRetry+1)
{
if(!OrderSend(request, result) || !OrderSuccess(result.retcode))
{
err = GetLastError();
myAlert("print", "OrderModify error #"+IntegerToString(err));
Sleep(OrderWait*1000);
}
retries++;
}
if(!OrderSuccess(result.retcode))
{
myAlert("error", "OrderModify failed "+IntegerToString(OrderRetry+1)+" times; error #"+IntegerToString(err));
return(-1);
}
string alertstr = "Order modify: ticket="+IntegerToString(ticket);
if(NormalizeDouble(SL, Digits()) != 0) alertstr = alertstr+" SL="+DoubleToString(SL);
if(NormalizeDouble(TP, Digits()) != 0) alertstr = alertstr+" TP="+DoubleToString(TP);
myAlert("modify", alertstr);
return(0);
}
int myOrderModifyRel(ENUM_ORDER_TYPE type, ulong ticket, double SL, double TP) //works for positions and orders, modify SL and TP (relative to open price), zero targets do not modify, ticket is irrelevant for open positions
{
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) || !MQLInfoInteger(MQL_TRADE_ALLOWED)) return(-1);
bool netting = AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING;
int retries = 0;
int err = 0;
SL = NormalizeDouble(SL, Digits());
TP = NormalizeDouble(TP, Digits());
if(SL < 0) SL = 0;
if(TP < 0) TP = 0;
//prepare to select order
Sleep(10);
if((type <= 1 && ((netting && !PositionSelect(Symbol())) || (!netting && !PositionSelectByTicket(ticket)))) || (type > 1 && !OrderSelect(ticket)))
{
err = GetLastError();
myAlert("error", "PositionSelect / OrderSelect failed; error #"+IntegerToString(err));
return(-1);
}
//ignore open positions other than "type"
if (type <= 1 && PositionGetInteger(POSITION_TYPE) != type) return(0);
//prepare to modify order, convert relative to absolute
double openprice = (type <= 1) ? PositionGetDouble(POSITION_PRICE_OPEN) : OrderGetDouble(ORDER_PRICE_OPEN);
if(((type <= 1) ? PositionGetInteger(POSITION_TYPE) : OrderGetInteger(ORDER_TYPE)) % 2 == 0) //buy
{
if(NormalizeDouble(SL, Digits()) != 0)
SL = openprice - SL;
if(NormalizeDouble(TP, Digits()) != 0)
TP = openprice + TP;
}
else //sell
{
if(NormalizeDouble(SL, Digits()) != 0)
SL = openprice + SL;
if(NormalizeDouble(TP, Digits()) != 0)
TP = openprice - TP;
}
double currentSL = (type <= 1) ? PositionGetDouble(POSITION_SL) : OrderGetDouble(ORDER_SL);
double currentTP = (type <= 1) ? PositionGetDouble(POSITION_TP) : OrderGetDouble(ORDER_TP);
if(NormalizeDouble(SL, Digits()) == 0) SL = currentSL; //not to modify
if(NormalizeDouble(TP, Digits()) == 0) TP = currentTP; //not to modify
if(NormalizeDouble(SL - currentSL, Digits()) == 0
&& NormalizeDouble(TP - currentTP, Digits()) == 0)
return(0); //nothing to do
MqlTradeRequest request;
ZeroMemory(request);
request.action = (type <= 1) ? TRADE_ACTION_SLTP : TRADE_ACTION_MODIFY;
if (type > 1)
request.order = ticket;
else
request.position = PositionGetInteger(POSITION_TICKET);
request.symbol = Symbol();
request.price = (type <= 1) ? PositionGetDouble(POSITION_PRICE_OPEN) : OrderGetDouble(ORDER_PRICE_OPEN);
request.sl = NormalizeDouble(SL, Digits());
request.tp = NormalizeDouble(TP, Digits());
request.deviation = MaxSlippage_;
MqlTradeResult result;
ZeroMemory(result);
while(!OrderSuccess(result.retcode) && retries < OrderRetry+1)
{
if(!OrderSend(request, result) || !OrderSuccess(result.retcode))
{
err = GetLastError();
myAlert("print", "OrderModify error #"+IntegerToString(err));
Sleep(OrderWait*1000);
}
retries++;
}
if(!OrderSuccess(result.retcode))
{
myAlert("error", "OrderModify failed "+IntegerToString(OrderRetry+1)+" times; error #"+IntegerToString(err));
return(-1);
}
string alertstr = "Order modify: ticket="+IntegerToString(ticket);
if(NormalizeDouble(SL, Digits()) != 0) alertstr = alertstr+" SL="+DoubleToString(SL);
if(NormalizeDouble(TP, Digits()) != 0) alertstr = alertstr+" TP="+DoubleToString(TP);
myAlert("modify", alertstr);
return(0);
}
void TrailingStopTrail(ENUM_ORDER_TYPE type, double TS, double step, bool aboveBE, double aboveBEval) //set Stop Loss to "TS" if price is going your way with "step"
{
TS = NormalizeDouble(TS, Digits());
step = NormalizeDouble(step, Digits());
int total = PositionsTotal();
for(int i = total-1; i >= 0; i--)
{
if(PositionGetTicket(i) <= 0) continue;
if(PositionGetInteger(POSITION_MAGIC) != MagicNumber || PositionGetString(POSITION_SYMBOL) != Symbol() || PositionGetInteger(POSITION_TYPE) != type) continue;
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
double SL = PositionGetDouble(POSITION_SL);
double openprice = PositionGetDouble(POSITION_PRICE_OPEN);
ulong ticket = PositionGetInteger(POSITION_TICKET);
if(type == ORDER_TYPE_BUY && (!aboveBE || last_tick.bid > openprice + TS + aboveBEval) && (NormalizeDouble(SL, Digits()) <= 0 || last_tick.bid > SL + TS + step))
myOrderModify(ORDER_TYPE_BUY, ticket, last_tick.bid - TS, 0);
else if(type == ORDER_TYPE_SELL && (!aboveBE || last_tick.ask < openprice - TS - aboveBEval) && (NormalizeDouble(SL, Digits()) <= 0 || last_tick.ask < SL - TS - step))
myOrderModify(ORDER_TYPE_SELL, ticket, last_tick.ask + TS, 0);
}
}
bool OrderSuccess(uint retcode)
{
return(retcode == TRADE_RETCODE_PLACED || retcode == TRADE_RETCODE_DONE
|| retcode == TRADE_RETCODE_DONE_PARTIAL || retcode == TRADE_RETCODE_NO_CHANGES);
}
double getBid()
{
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
return(last_tick.bid);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
MaxSlippage_ = MaxSlippage;
//initialize myPoint
myPoint = Point();
if(Digits() == 5 || Digits() == 3)
{
myPoint *= 10;
MaxSlippage_ *= 10;
}
//initialize LotDigits
double LotStep = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_STEP);
if(NormalizeDouble(LotStep, 3) == round(LotStep))
LotDigits = 0;
else if(NormalizeDouble(10*LotStep, 3) == round(10*LotStep))
LotDigits = 1;
else if(NormalizeDouble(100*LotStep, 3) == round(100*LotStep))
LotDigits = 2;
else LotDigits = 3;
FrAMA_handle = iFrAMA(NULL, PERIOD_H1, 14, 0, PRICE_CLOSE);
if(FrAMA_handle < 0)
{
Print("The creation of iFrAMA has failed: FrAMA_handle=", INVALID_HANDLE);
Print("Runtime error = ", GetLastError());
return(INIT_FAILED);
}
ATR_MAs_handle = iCustom(NULL, PERIOD_H1, "ATR_MAs", 8, 1, 14, 100, 1.0);
if(ATR_MAs_handle < 0)
{
Print("The creation of ATR_MAs has failed: ATR_MAs_handle=", INVALID_HANDLE);
Print("Runtime error = ", GetLastError());
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
ulong ticket = 0;
double price;
double SL;
double TP;
CloseByDuration(MaxTradeDurationBars * PeriodSeconds());
if(CopyBuffer(FrAMA_handle, 0, 0, 200, FrAMA) <= 0) return;
ArraySetAsSeries(FrAMA, true);
if(CopyBuffer(ATR_MAs_handle, 0, 0, 200, ATR_MAs) <= 0) return;
ArraySetAsSeries(ATR_MAs, true);
TrailingStopTrail(ORDER_TYPE_BUY, 2 * myPoint, 1 * myPoint, true, 3 * myPoint); //Trailing Stop = trail
TrailingStopTrail(ORDER_TYPE_SELL, 2 * myPoint, 1 * myPoint, true, 3 * myPoint); //Trailing Stop = trail
//Open Buy Order
if(getBid() > FrAMA[0] //Price > Fractal Adaptive Moving Average
&& getBid() > ATR_MAs[0] //Price > ATR_MAs
)
{
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
price = last_tick.ask;
SL = 3 * myPoint; //Stop Loss = value in points (relative to price)
TP = 7.5 * myPoint; //Take Profit = value in points (relative to price)
if(TradesCount(ORDER_TYPE_BUY) + TradesCount(ORDER_TYPE_SELL) > 0 || TimeCurrent() - LastCloseTime() < NextOpenTradeAfterMinutes * 60) return; //next open trade after time after previous trade's close
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
{
ticket = myOrderSend(ORDER_TYPE_BUY, price, TradeSize, "");
if(ticket == 0) return;
}
else //not autotrading => only send alert
myAlert("order", "");
myOrderModifyRel(ORDER_TYPE_BUY, ticket, 0, TP);
myOrderModifyRel(ORDER_TYPE_BUY, ticket, SL, 0);
}
//Open Sell Order
if(getBid() < FrAMA[0] //Price < Fractal Adaptive Moving Average
&& getBid() < ATR_MAs[0] //Price < ATR_MAs
)
{
MqlTick last_tick;
SymbolInfoTick(Symbol(), last_tick);
price = last_tick.bid;
SL = 3 * myPoint; //Stop Loss = value in points (relative to price)
TP = 7.5 * myPoint; //Take Profit = value in points (relative to price)
if(TradesCount(ORDER_TYPE_BUY) + TradesCount(ORDER_TYPE_SELL) > 0 || TimeCurrent() - LastCloseTime() < NextOpenTradeAfterMinutes * 60) return; //next open trade after time after previous trade's close
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && MQLInfoInteger(MQL_TRADE_ALLOWED))
{
ticket = myOrderSend(ORDER_TYPE_SELL, price, TradeSize, "");
if(ticket == 0) return;
}
else //not autotrading => only send alert
myAlert("order", "");
myOrderModifyRel(ORDER_TYPE_SELL, ticket, SL, 0);
myOrderModifyRel(ORDER_TYPE_SELL, ticket, 0, TP);
}
}
//+------------------------------------------------------------------+
Code des ATR Moving Averages
//+------------------------------------------------------------------+
//| ATR_MAs.mq5|
//| Copyright 2022, MetaQuotes Ltd. |
//| https://www.mql5.com |
//| Author: Yashar Seyyedin |
//| Web Address: https://www.mql5.com/en/users/yashar.seyyedin |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.10"
#property indicator_chart_window
#property indicator_buffers 10
#property indicator_plots 1
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#define BARS MathMax(rates_total-_length-_atr_length-_stdev_length-prev_calculated,1)
enum MA_TYPE {ATRWSMA, ATRWEMA, ATRWRMA, ATRWWMA};
enum MA_TYPE2 {SMA, EMA, RMA, WMA};
//--- input parameters
input int _length=8;
input MA_TYPE _type=ATRWEMA;
input int _atr_length = 14;
input int _stdev_length = 100;
input double _stdev_mult = 1.0;
//--- indicator buffers
double MABuffer[];
double EMA1Buffer[];
double EMA2Buffer[];
double RMA1Buffer[];
double RMA2Buffer[];
double RMA3Buffer[];
double atrwoBuffer[];
double trwoBuffer[];
double ta_trBuffer[];
double atrwotmpBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
SetIndexBuffer(1,EMA1Buffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,EMA2Buffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,RMA1Buffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,RMA2Buffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,RMA3Buffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(6,atrwoBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(7,trwoBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(8,ta_trBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(9,atrwotmpBuffer,INDICATOR_CALCULATIONS);
ArraySetAsSeries(MABuffer,true);
ArraySetAsSeries(EMA1Buffer,true);
ArraySetAsSeries(EMA2Buffer,true);
ArraySetAsSeries(RMA1Buffer,true);
ArraySetAsSeries(RMA2Buffer,true);
ArraySetAsSeries(RMA3Buffer,true);
ArraySetAsSeries(atrwoBuffer,true);
ArraySetAsSeries(trwoBuffer,true);
ArraySetAsSeries(ta_trBuffer,true);
ArraySetAsSeries(atrwotmpBuffer,true);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
for(int i=BARS; i>=0; i--)
MABuffer[i]=anyma(open, close, high, low, close, _length, _type, _atr_length, _stdev_length, _stdev_mult, i);
return(rates_total);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double anyma(const double &open[],
const double &close[],
const double &high[],
const double &low[],
const double &src[],
int length,
MA_TYPE type,
int atr_length = 14,
int stdev_length = 100,
double stdev_mult = 1.0,
int index = 0)
{
switch(type)
{
case ATRWSMA:
return atrwma(open, close, high, low, src, length, SMA, atr_length, stdev_length, stdev_mult, index);
case ATRWEMA:
return atrwma(open, close, high, low, src, length, EMA, atr_length, stdev_length, stdev_mult, index);
case ATRWRMA:
return atrwma(open, close, high, low, src, length, RMA, atr_length, stdev_length, stdev_mult, index);
case ATRWWMA:
return atrwma(open, close, high, low, src, length, WMA, atr_length, stdev_length, stdev_mult, index);
default:
return EMPTY_VALUE;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double atrwma(
const double &open[],
const double &close[],
const double &high[],
const double &low[],
const double &src[],
int length,
MA_TYPE2 type,
int atr_length,
int stdev_length,
double stdev_mult,
int index)
{
atrwo(open, close, high, low, length, stdev_length, stdev_mult, index);
atrwotmpBuffer[index]=src[index]*atrwoBuffer[index];
switch(type)
{
case SMA:
return pine_sma(atrwotmpBuffer, length, index)/pine_sma(atrwoBuffer, length, index);
case EMA:
return pine_ema(atrwotmpBuffer, EMA1Buffer, length, index)/pine_ema(atrwoBuffer, EMA2Buffer, length, index);
case RMA:
return pine_rma(atrwotmpBuffer, RMA1Buffer, length, index)/pine_rma(atrwoBuffer, RMA2Buffer, length, index);
case WMA:
return pine_wma(atrwotmpBuffer, length, index)/pine_wma(atrwoBuffer,length, index);
}
return EMPTY_VALUE;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void atrwo(const double &open[],
const double &close[],
const double &high[],
const double &low[],
int length = 14,
int stdev_length = 100,
double stdev_mult = 1,
int index = 0)
{
atrwoBuffer[index] = 0.0;
trwoBuffer[index] = 0.0;
ta_trBuffer[index]=MathMax(high[index] - low[index], MathAbs(high[index] - close[index+1]));
ta_trBuffer[index]=MathMax(ta_trBuffer[index], MathAbs(low[index] - close[index+1]));
double max_tr = atrwoBuffer[index+1] + stdev_mult * pine_stdev(ta_trBuffer, stdev_length, index);
trwoBuffer[index] = ta_trBuffer[index] > max_tr ? trwoBuffer[index+1] : ta_trBuffer[index];
atrwoBuffer[index] = pine_rma(trwoBuffer, RMA3Buffer, length, index);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double pine_stdev(double &src[], int length, int index)
{
double avg = pine_sma(src, length, index);
double sumOfSquareDeviations = 0.0;
for(int i = index; i<index+length; i++)
{
double sum = src[i]-avg;
sumOfSquareDeviations = sumOfSquareDeviations + sum * sum;
}
return MathSqrt(sumOfSquareDeviations / length);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double pine_sma(const double &src[], int length, int index)
{
double sum = 0.0;
for(int i = index; i<index+length; i++)
sum = sum + src[i] / length;
return sum;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double pine_ema(const double &src[], double &out[], int length, int index)
{
double alpha=2.0/(1+length);
out[index] = out[index+1]*(1-alpha)+src[index]*alpha;
return out[index];
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double pine_rma(const double &src[], double &out[], int length, int index)
{
double alpha=1.0/(length);
out[index] = out[index+1]*(1-alpha)+src[index]*alpha;
return out[index];
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double pine_wma(const double &src[], int length, int index)
{
double norm = 0.0;
double sum = 0.0;
for(int i = index; i<index+length; i++)
{
double weight = (length - i+index) * length;
norm = norm + weight;
sum = sum + src[i] * weight;
}
return sum/norm;
}
//+------------------------------------------------------------------+
