//+------------------------------------------------------------------+
//| FGProBot 0.9 by pip.digger 2013.01.30 |
//| |
//| |
//| inspired by Pro_Bot by HotFx 2012.08.06, http://hotfx.0pk.ru |
//| http://hot-fx.blogspot.com |
//| and ForexGrowthBot, http://www.ForexGrowthBot.com |
//+------------------------------------------------------------------+
#property copyright "FGProBot 0.9 by pip.digger 2013.01.30"
#property link "wwi.org"
// externals
extern double LotSize = 0.1;
extern double Risk = 1.0;
extern int FridayStopHour = 16;
bool HardTPSL = TRUE;
extern int FastVolatilityBase = 5;
extern int SlowVolatilityBase = 58;
extern int SlowVolatilityOffset = 3;
extern double VolatilityFactor = 2.2;
extern double ProfitTarget = 0.43;
extern double StopLoss = 0.16;
extern int ProfitLossVolatilityBase = 46;
extern string BotComment = "FGProBot 0.9 by pip.digger";
extern int Magic = 20130130;
extern int Slippage = 3;
// globals
double MinLot, MaxLot, LotDigits, Range;
datetime bt = 0;
string symb, txt = "\n FGProBot 0.9 by pip.digger \n Lot: ";
int init()
{
symb = Symbol();
if(Digits%2==1) Slippage *= 10;
LotDigits = MathLog(MarketInfo(symb, MODE_LOTSTEP)) / MathLog(0.1);
MinLot = MarketInfo(symb, MODE_MINLOT);
MaxLot = MarketInfo(symb, MODE_MAXLOT);
}
int start()
{
double VolFac, rg;
int i;
static int ticket;
// only on new bar openening...
if(bt != Time[0]) {
bt = Time[0];
VolFac = VF(FastVolatilityBase, SlowVolatilityBase);
Range = High[iHighest(symb, 0, MODE_HIGH, ProfitLossVolatilityBase, 1)] - Low[iLowest(symb, 0, MODE_LOW, ProfitLossVolatilityBase, 1)];
// check for any trades to close by new bar opening (example here, trades w/o TP or SL assigned)
// can also be used to implement other (dynamic) closing strategies
for(i = OrdersTotal() - 1; i >= 0; i--){
if(OrderSelect(i, SELECT_BY_POS))
if(OrderSymbol() == symb && OrderMagicNumber() == Magic)
if(OrderTakeProfit() == 0.0) // check if TP has been reached
switch(OrderType()) {
case OP_BUY:
if(Bid >= OrderOpenPrice() + RangeFromComment() * ProfitTarget)
OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Blue);
break;
case OP_SELL:
if(Ask <= OrderOpenPrice() - RangeFromComment() * ProfitTarget)
OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red);
break;
}
if (OrderStopLoss() == 0.0) // check if SL has been reached
switch(OrderType()) {
case OP_BUY:
if(Bid <= OrderOpenPrice() - RangeFromComment() * StopLoss)
OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Blue);
break;
case OP_SELL:
if(Ask >= OrderOpenPrice() + RangeFromComment() * StopLoss)
OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red);
break;
}
}
Comment(txt, Lot());
}
// place new trade if prerequisites are met
if(IsTradeTime() && MathAbs(VolFac) > VolatilityFactor)
if(VolFac > 0.0) {
ticket = OrderSend(symb, OP_BUY, Lot(), ND(Ask), Slippage, 0.0, 0.0, StringConcatenate(DoubleToStr(Range/Point, 0), " - ", BotComment), Magic, 0, Blue);
if(ticket != -1)
VolFac = 0.0;
} else if(VolFac < 0.0) {
ticket = OrderSend(symb, OP_SELL, Lot(), ND(Bid), Slippage, 0.0, 0.0, StringConcatenate(DoubleToStr(Range/Point, 0), " - ", BotComment), Magic, 0, Red);
if(ticket != -1)
VolFac = 0.0;
}
// set hard TP & SL for last opened trade
if(HardTPSL && OrderSelect(ticket, SELECT_BY_TICKET))
if(OrderSymbol() == symb && OrderMagicNumber() == Magic)
switch(OrderType()) {
case OP_BUY:
if(OrderModify(ticket, OrderOpenPrice(), ND(Ask - Range * StopLoss), ND(Ask + Range * ProfitTarget), 0, Blue))
ticket = -1;
break;
case OP_SELL:
if(OrderModify(ticket, OrderOpenPrice(), ND(Bid + Range * StopLoss), ND(Bid - Range * ProfitTarget), 0, Red))
ticket = -1;
break;
default:
ticket = -1;
}
return(0);
}
// return lotsize for next trade (currently here, per 1000 free margin)
double Lot()
{
double Lots;
if(Risk > 0.0)
Lots = AccountFreeMargin() * (Risk/100.0) / ((Range * StopLoss / Point) * MarketInfo(symb, MODE_TICKVALUE));
else
Lots = LotSize;
return(NormalizeDouble(MathMin(MathMax(MinLot, Lots), MaxLot), LotDigits));
}
// normalize double to accuracy of Digits of current symbol price
double ND(double val)
{
return (NormalizeDouble(val, Digits));
}
// calculate volatility (acceleration) factor
double VF(int Fa, int Sa)
{
double sumF = 0.0, sumS = 0.0;
for (int i = 1; i <= Fa; i++)
sumF += Close[i] - Open[i];
for (i = 1; i <= Sa; i++)
sumS += MathAbs(Close[i + SlowVolatilityOffset] - Open[i + SlowVolatilityOffset]);
return((sumF / Fa) / (sumS / Sa));
}
// trading time filter
bool IsTradeTime()
{
if (DayOfWeek() >= 5 && FridayStopHour >= 0 && Hour() >= FridayStopHour)
return(false);
else
return(true);
}
// extract range from trade comment
double RangeFromComment()
{
return(StrToDouble(StringSubstr(OrderComment(), 0, StringFind(OrderComment(), " - "))) * Point);
}