#include <stdlib.mqh>
#include <stderror.mqh>
//+------------------------------------------------------------------+
//| 10Pips.mq4 |
//+------------------------------------------------------------------+
//| Copyright � 2013, Russian trades |
//| http://rutrade.info |
//+------------------------------------------------------------------+
#property copyright "Copyright � 2013, Russian trades"
#property link "http://rutrade.info"
//------------------------------------------
extern double LotsFor10000 = 0.5; // ����� �� 10000 ��������
extern int StartHour = 1; // ����
extern int EndHour = 7; // ������
extern int Tries = 2; // ���-�� ������� �� ����� �� ��������
extern double Multiplier = 4; // ��������� ������
extern int TakeProfit = 10; //
extern int StopLoss = 30; //
extern int Magic = 20131017;
extern int Slippage = 3;
extern string comment = "10Pips v1.0";
//------------------------------------------
double slope, tma_high, tma_low,
mlots, sl, tp, BLots;
int retries = 5,
_OR_err = 0,
ticket,
trailing_level, // trailing stop
trailing_step, // trailing step
stop_level, // minimum level of the price to install a Stop Loss / Take Profit
order_type, // order type
order_ticket, // order ticket
orders_total;
double target, price, tstop;
double order_open_price; // order open price
double tp_sell, tp_buy, order_stop_loss;
bool buy_open = false; // buy flag
bool sell_open = false; // sell flag
//------------------------------------------
double bid, ask, point;
double h1, h2, h3, l1, l2, l3;
int digits;
int spread;
int acount;
string info;
string Currs[] = {"EURUSD", "GBPUSD"};
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
if(Digits == 3 || Digits == 5)
{
BLots = LotsFor10000;
Slippage *= 10;
}
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
if (TimeHour(TimeCurrent()) >= StartHour && TimeHour(TimeCurrent()) <= EndHour &&
CountBuy() + CountSell() == 0)
{
CheckLastOrder();
OpenSellOrder();
OpenBuyOrder();
}
ModifyOrders();
return(0);
}
//+------------------------------------------------------------------+
void CheckLastOrder()
{
datetime last_time;
datetime ltime = 0;
int aticket = 0;
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(OrderMagicNumber() == Magic)
{
last_time = OrderCloseTime();
if(last_time > ltime)
{
ltime = last_time;
aticket = OrderTicket();
}
}
}
}
if(aticket == 0)
{
Print("����� �� ������, ticket = 0");
Comment("����� �� ������, ticket = 0");
LotsFor10000 = BLots;
return;
}
Sleep(1000);
Print("Check next lot");
if (OrderSelect(aticket, SELECT_BY_TICKET, MODE_HISTORY))
{
Print("Last order selected, ticket: " + aticket);
Comment("Last order selected, ticket: " + aticket + ", Profit: " + OrderProfit());
if (OrderProfit() < 0)
{
Print("Profit < 0");
if (OrderLots() >= BLots*Tries)
LotsFor10000 = BLots;
else LotsFor10000 = NormalizeDouble(LotsFor10000 * Multiplier, 2);
} else LotsFor10000 = BLots;
}
}
//+------------------------------------------------------------------+
double GetLots()
{
double clots;
clots = AccountBalance() / 10000.0 * LotsFor10000;
clots = MathMax(clots, MarketInfo(Symbol(), MODE_MINLOT));
clots = MathMin(clots, MarketInfo(Symbol(), MODE_MAXLOT));
clots = NormalizeDouble(clots, 2);
return (clots);
}
//+------------------------------------------------------------------+
void ModifyOrders()
{
string smb;
int asl, atp;
for (int i=0; i<OrdersTotal(); i++)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderMagicNumber() == Magic && OrderSymbol() == Symbol())
{
smb = OrderSymbol();
bid = MarketInfo(smb, MODE_BID);
ask = MarketInfo(smb, MODE_ASK);
point = MarketInfo(smb, MODE_POINT);
digits = MarketInfo(smb, MODE_DIGITS);
spread = MarketInfo(smb, MODE_SPREAD);
asl = StopLoss;
atp = TakeProfit;
if (digits == 3 || digits == 5)
{
atp *= 10;
asl *= 10;
}
if (OrderType() == OP_SELL)
{
sl = NormalizeDouble(OrderOpenPrice() + asl*point, digits);
tp = NormalizeDouble(OrderOpenPrice() - atp*point, digits);
if(sl != OrderStopLoss() || tp != OrderTakeProfit())
OrderModifyReliable(OrderTicket(), OrderOpenPrice(), sl, tp, 0);
}
else if (OrderType() == OP_BUY)
{
sl = NormalizeDouble(OrderOpenPrice() - asl*point, digits);
tp = NormalizeDouble(OrderOpenPrice() + atp*point, digits);
if(sl != OrderStopLoss() || tp != OrderTakeProfit())
OrderModifyReliable(OrderTicket(), OrderOpenPrice(), sl, tp, 0);
}
}
}
}
}
//+------------------------------------------------------------------+
void OpenSellOrder()
{
mlots = GetLots();
bid = MarketInfo(Symbol(), MODE_BID);
ticket = OrderSendReliable(Symbol(), OP_SELL, mlots, bid, Slippage, 0, 0, comment, Magic, 0, Red);
}
//+------------------------------------------------------------------+
int OpenBuyOrder()
{
mlots = GetLots();
ask = MarketInfo(Symbol(), MODE_ASK);
ticket = OrderSendReliable(Symbol(), OP_BUY, mlots, ask, Slippage, 0, 0, comment, Magic, 0, Blue);
return(ticket);
}
//+------------------------------------------------------------------+
int CountBuy()
{
int count = 0;
for (int trade = OrdersTotal() - 1; trade >= 0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_BUY)
count++;
}
}
return (count);
}
//+------------------------------------------------------------------+
int CountSell()
{
int count = 0;
for (int trade = OrdersTotal() - 1; trade >= 0; trade--)
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
count++;
}
}
return (count);
}
//+------------------------------------------------------------------+
int OrderSendReliable(string asymbol, int cmd, double volume, double aprice,
int slippage, double stoploss, double takeprofit,
string acomment, int magic, datetime expiration = 0,
color arrow_color = CLR_NONE)
{
int err = GetLastError();
err = 0;
bool exit_loop = false;
bool limit_to_market = false;
err = GetLastError();
err = 0;
ticket = -1;
if ((cmd == OP_BUY) || (cmd == OP_SELL))
{
int cnt = 0;
while (!exit_loop)
{
if (IsTradeAllowed())
{
ticket = OrderSend(asymbol, cmd, volume, aprice, slippage,
stoploss, takeprofit, acomment, magic,
expiration, arrow_color);
err = GetLastError();
}
else
{
cnt++;
}
switch (err)
{
case ERR_NO_ERROR:
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
cnt++;
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue;
default:
exit_loop = true;
break;
} // end switch
if (cnt > retries)
exit_loop = true;
if (!exit_loop)
{
Sleep(1000);
RefreshRates();
}
if (exit_loop)
{
if (err != ERR_NO_ERROR)
{
Print("������ : " + err);
}
}
}
if (err == ERR_NO_ERROR)
{
OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
return(ticket);
}
Print("������ �������� ������ ����� " + cnt + " �������.");
Print("������ : " + err);
return(-1);
}
return(-1);
}
//+------------------------------------------------------------------+
bool OrderModifyReliable(int aticket, double aprice, double stoploss,
double takeprofit, datetime expiration,
color arrow_color = CLR_NONE)
{
if (IsStopped())
{
Print("������, ����������: IsStopped() == true");
return(false);
}
int cnt = 0;
while(!IsTradeAllowed() && cnt < retries)
{
Sleep(500);
cnt++;
}
if (!IsTradeAllowed())
{
Print("������: �������� ����������� - IsTradeAllowed()==false");
_OR_err = ERR_TRADE_CONTEXT_BUSY;
return(false);
}
// if (false)
{
OrderSelect(aticket, SELECT_BY_TICKET, MODE_TRADES);
string asymbol = OrderSymbol();
int adigits = MarketInfo(asymbol, MODE_DIGITS);
if (adigits > 0)
{
aprice = NormalizeDouble(aprice,adigits);
stoploss = NormalizeDouble(stoploss,adigits);
takeprofit = NormalizeDouble(takeprofit,adigits);
}
if (stoploss != 0) OrderReliable_EnsureValidStop(asymbol,aprice,stoploss);
}
int err = GetLastError(); // so we clear the global variable.
err = 0;
_OR_err = 0;
bool exit_loop = false;
cnt = 0;
bool result = false;
while (!exit_loop)
{
if (IsTradeAllowed())
{
result = OrderModify(aticket, aprice, stoploss,
takeprofit, expiration, arrow_color);
err = GetLastError();
_OR_err = err;
}
else
cnt++;
if (result == true)
exit_loop = true;
switch (err)
{
case ERR_NO_ERROR:
exit_loop = true;
break;
case ERR_NO_RESULT:
exit_loop = true;
break;
case ERR_SERVER_BUSY:
case ERR_NO_CONNECTION:
case ERR_INVALID_PRICE:
case ERR_OFF_QUOTES:
case ERR_BROKER_BUSY:
case ERR_TRADE_CONTEXT_BUSY:
case ERR_TRADE_TIMEOUT: // for modify this is a retryable error, I hope.
cnt++; // a retryable error
break;
case ERR_PRICE_CHANGED:
case ERR_REQUOTE:
RefreshRates();
continue; // we can apparently retry immediately according to MT docs.
default:
// an apparently serious, unretryable error.
exit_loop = true;
break;
} // end switch
if (cnt > retries)
exit_loop = true;
if (!exit_loop)
{
Print("������, �������: (" + cnt + "/" + retries +
"): " + OrderReliableErrTxt(err));
Sleep(500);
RefreshRates();
}
if (exit_loop)
{
if ((err != ERR_NO_ERROR) && (err != ERR_NO_RESULT))
Print("������: " + OrderReliableErrTxt(err));
}
}
// we have now exited from loop.
if ((result == true) || (err == ERR_NO_ERROR))
{
Print("�������� �����������");
OrderSelect(aticket, SELECT_BY_TICKET, MODE_TRADES);
OrderPrint();
return(true); // SUCCESS!
}
if (err == ERR_NO_RESULT)
{
return(true);
}
Print("������ ����������� ����� " + cnt + " �������");
Print("������ �����������: " + aticket + " " + asymbol +
"@" + aprice + " tp@" + takeprofit + " sl@" + stoploss);
Print("������ : " + OrderReliableErrTxt(err));
return(false);
}
//+------------------------------------------------------------------+
void OrderReliable_EnsureValidStop(string asymbol, double aprice, double& asl)
{
// Return if no S/L
if (asl == 0)
return;
double servers_min_stop = MarketInfo(asymbol, MODE_STOPLEVEL) * MarketInfo(asymbol, MODE_POINT);
if (MathAbs(aprice - asl) <= servers_min_stop)
{
// we have to adjust the stop.
if (aprice > asl)
asl = aprice - servers_min_stop; // we are long
else if (aprice < asl)
asl = aprice + servers_min_stop; // we are short
else
Print("EnsureValidStop: error, passed in aprice == sl, cannot adjust");
asl = NormalizeDouble(asl, MarketInfo(asymbol, MODE_DIGITS));
}
}
//+------------------------------------------------------------------+
string OrderReliableErrTxt(int err)
{
return ("" + err + ":" + ErrorDescription(err));
}
//+------------------------------------------------------------------+