bb_trader2/MyExpertFunctions.mqh

2022 lines
131 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 14:43:19 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| MyFirstIncludeFile.mqh |
//| dilettantcorner |
//| dilettantcorner@gmail.com |
//+------------------------------------------------------------------+
#property copyright "dilettantcorner"
#property link "dilettantcorner@gmail.com"
#ifndef MY_EXPERT_FUNCTIONS_MQH
#define MY_EXPERT_FUNCTIONS_MQH
namespace std {
//+------------------------------------------------------------------+
ulong Open_Buy_Pos(string symbol,double lot, int slipage, uint magic = NULL, string comment = NULL)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_DEAL;
reqwest.symbol = symbol;
reqwest.type = ORDER_TYPE_BUY;
reqwest.volume = NormalizeDouble(lot,2);
ENUM_ORDER_TYPE_FILLING fill_type;
GetFillMode(reqwest.symbol,fill_type);
::Print("Filling mode: ",fill_type);
reqwest.type_filling = fill_type;
if(SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_INSTANT ||
SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_REQUEST)
{
double current_ask = SymbolInfoDouble(reqwest.symbol,SYMBOL_ASK);
reqwest.price = current_ask;
reqwest.sl = 0;
reqwest.tp = 0;
reqwest.deviation = slipage;
}
if(comment != NULL && comment != "") reqwest.comment = comment;
if(magic > 0) reqwest.magic = magic;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print(">78F8O 09 =5 >B:@KB0. H81:0 !",result.retcode);
Sleep(500);
}
else
{
ulong deal_ticket = result.deal;
if(deal_ticket == 0) break;
if(deal_ticket > 0)
{
if(HistoryDealSelect(deal_ticket))
{
long pos_ticket = HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
return pos_ticket;
}
}
}
}
return 0;
}
//+------------------------------------------------------------------+
ulong Open_Sell_Pos(string symbol,double lot, int slipage, uint magic = NULL, string comment = NULL)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_DEAL;
reqwest.symbol = symbol;
reqwest.type = ORDER_TYPE_SELL;
reqwest.volume = NormalizeDouble(lot,2);
ENUM_ORDER_TYPE_FILLING fill_type;
GetFillMode(reqwest.symbol,fill_type);
::Print("Filling mode: ",fill_type);
reqwest.type_filling = fill_type;
if(SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_INSTANT ||
SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_EXEMODE) == SYMBOL_TRADE_EXECUTION_REQUEST)
{
double current_bid = SymbolInfoDouble(reqwest.symbol,SYMBOL_BID);
reqwest.price = current_bid;
reqwest.sl = 0;
reqwest.tp = 0;
reqwest.deviation = slipage;
}
if(comment != NULL && comment != "") reqwest.comment = comment;
if(magic > 0) reqwest.magic = magic;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print(">78F8O !5;; =5 >B:@KB0. H81:0 !",result.retcode);
Sleep(500);
}
else
{
ulong deal_ticket = result.deal;
if(deal_ticket == 0) break;
if(deal_ticket > 0)
{
if(HistoryDealSelect(deal_ticket))
{
long pos_ticket = HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
return pos_ticket;
}
}
}
}
return 0;
}
//+------------------------------------------------------------------+
ulong Set_Buy_Order(string symbol,
double lot,
double open_price,
int stop_loss,
int take_profit,
uint magic = NULL,
datetime expiration_time = 0,
string comment = NULL)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_PENDING;
reqwest.symbol = symbol;
reqwest.volume = NormalizeDouble(lot,2);
reqwest.type_filling = ORDER_FILLING_RETURN;
int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS);
reqwest.price = NormalizeDouble(open_price,digits);
double current_ask = SymbolInfoDouble(reqwest.symbol,SYMBOL_ASK);
if(reqwest.price > current_ask) reqwest.type = ORDER_TYPE_BUY_STOP;
else reqwest.type = ORDER_TYPE_BUY_LIMIT;
int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL);
double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT);
if(stop_loss > 0)
{
if(stop_loss < stop_level) stop_loss = stop_level;
reqwest.sl = NormalizeDouble(reqwest.price - stop_loss * point,digits);
}
else reqwest.sl = 0;
if(take_profit > 0)
{
if(take_profit < stop_level) take_profit = stop_level;
reqwest.tp = NormalizeDouble(reqwest.price + take_profit * point,digits);
}
else reqwest.tp = 0;
if(expiration_time == 0)
{
int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY;
else reqwest.type_time = ORDER_TIME_GTC;
}
if(comment != NULL && comment != "") reqwest.comment = comment;
if(magic > 0) reqwest.magic = magic;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("B;>65==K9 >@45@ 09 =5 CAB0=>2;5=. H81:0 !",result.retcode);
Sleep(500);
}
else
{
ulong order_ticket = result.order;
if(order_ticket > 0) return order_ticket;
}
}
return 0;
}
//+------------------------------------------------------------------+
ulong Set_Sell_Order(string symbol,
double lot,
double open_price,
int stop_loss,
int take_profit,
uint magic = NULL,
datetime expiration_time = 0,
string comment = NULL)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_PENDING;
reqwest.symbol = symbol;
reqwest.volume = NormalizeDouble(lot,2);
reqwest.type_filling = ORDER_FILLING_RETURN;
int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS);
reqwest.price = NormalizeDouble(open_price,digits);
double current_bid = SymbolInfoDouble(reqwest.symbol,SYMBOL_BID);
if(reqwest.price < current_bid) reqwest.type = ORDER_TYPE_SELL_STOP;
else reqwest.type = ORDER_TYPE_SELL_LIMIT;
int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL);
double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT);
if(stop_loss > 0)
{
if(stop_loss < stop_level) stop_loss = stop_level;
reqwest.sl = NormalizeDouble(reqwest.price + stop_loss * point,digits);
}
else reqwest.sl = 0;
if(take_profit > 0)
{
if(take_profit < stop_level) take_profit = stop_level;
reqwest.tp = NormalizeDouble(reqwest.price - take_profit * point,digits);
}
else reqwest.tp = 0;
if(expiration_time == 0)
{
int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY;
else reqwest.type_time = ORDER_TIME_GTC;
}
if(comment != NULL && comment != "") reqwest.comment = comment;
if(magic > 0) reqwest.magic = magic;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("B;>65==K9 >@45@ !5;; =5 CAB0=>2;5=. H81:0 !",result.retcode);
Sleep(500);
}
else
{
ulong order_ticket = result.order;
if(order_ticket > 0) return order_ticket;
}
}
return 0;
}
//+------------------------------------------------------------------+
ulong Set_Buy_Order(string symbol,
double lot,
double open_price,
double stop_loss,
double take_profit,
uint magic = NULL,
datetime expiration_time = 0,
string comment = NULL)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_PENDING;
reqwest.symbol = symbol;
reqwest.volume = NormalizeDouble(lot,2);
reqwest.type_filling = ORDER_FILLING_RETURN;
int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS);
reqwest.price = NormalizeDouble(open_price,digits);
double current_ask = SymbolInfoDouble(reqwest.symbol,SYMBOL_ASK);
if(reqwest.price > current_ask) reqwest.type = ORDER_TYPE_BUY_STOP;
else reqwest.type = ORDER_TYPE_BUY_LIMIT;
int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL);
double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT);
if(stop_loss > 0)
{
double stop_dist = DistPrices(reqwest.price,stop_loss,symbol);
if(stop_dist < stop_level) stop_loss = reqwest.price - stop_level * point;
reqwest.sl = NormalizeDouble(stop_loss,digits);
}
else reqwest.sl = 0;
if(take_profit > 0)
{
double stop_dist = DistPrices(reqwest.price,take_profit,symbol);
if(stop_dist < stop_level) take_profit = reqwest.price + stop_level * point;
reqwest.tp = NormalizeDouble(take_profit,digits);
}
else reqwest.tp = 0;
if(expiration_time == 0)
{
int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY;
else reqwest.type_time = ORDER_TIME_GTC;
}
if(comment != NULL && comment != "") reqwest.comment = comment;
if(magic > 0) reqwest.magic = magic;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("B;>65==K9 >@45@ 09 =5 CAB0=>2;5=. H81:0 !",result.retcode);
Sleep(500);
}
else
{
ulong order_ticket = result.order;
if(order_ticket > 0) return order_ticket;
}
}
return 0;
}
//+------------------------------------------------------------------+
ulong Set_Sell_Order(string symbol,
double lot,
double open_price,
double stop_loss,
double take_profit,
uint magic = NULL,
datetime expiration_time = 0,
string comment = NULL)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_PENDING;
reqwest.symbol = symbol;
reqwest.volume = NormalizeDouble(lot,2);
reqwest.type_filling = ORDER_FILLING_RETURN;
int digits = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_DIGITS);
reqwest.price = NormalizeDouble(open_price,digits);
double current_bid = SymbolInfoDouble(reqwest.symbol,SYMBOL_BID);
if(reqwest.price < current_bid) reqwest.type = ORDER_TYPE_SELL_STOP;
else reqwest.type = ORDER_TYPE_SELL_LIMIT;
int stop_level = (int)SymbolInfoInteger(reqwest.symbol,SYMBOL_TRADE_STOPS_LEVEL);
double point = SymbolInfoDouble(reqwest.symbol,SYMBOL_POINT);
if(stop_loss > 0)
{
double stop_dist = DistPrices(reqwest.price,stop_loss,symbol);
if(stop_dist < stop_level) stop_loss = reqwest.price + stop_level * point;
reqwest.sl = NormalizeDouble(stop_loss,digits);
}
else reqwest.sl = 0;
if(take_profit > 0)
{
double stop_dist = DistPrices(reqwest.price,take_profit,symbol);
if(take_profit < stop_level) take_profit = reqwest.price + stop_level * point;
reqwest.tp = NormalizeDouble(take_profit,digits);
}
else reqwest.tp = 0;
if(expiration_time == 0)
{
int symb_exp = (int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
if((SYMBOL_EXPIRATION_GTC & symb_exp) != SYMBOL_EXPIRATION_GTC) reqwest.type_time = ORDER_TIME_DAY;
else reqwest.type_time = ORDER_TIME_GTC;
}
if(comment != NULL && comment != "") reqwest.comment = comment;
if(magic > 0) reqwest.magic = magic;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("B;>65==K9 >@45@ !5;; =5 CAB0=>2;5=. H81:0 !",result.retcode);
Sleep(500);
}
else
{
ulong order_ticket = result.order;
if(order_ticket > 0) return order_ticket;
}
}
return 0;
}
//+------------------------------------------------------------------+
bool Position_SLTP(ulong position,double SL,double TP)
{
if(PositionSelectByTicket(position))
{
double pos_op = PositionGetDouble(POSITION_PRICE_OPEN);
string pos_symb = PositionGetString(POSITION_SYMBOL);
ulong pos_mag = PositionGetInteger(POSITION_MAGIC);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
int symb_digits = (int)SymbolInfoInteger(pos_symb,SYMBOL_DIGITS);
double symb_point = SymbolInfoDouble(pos_symb,SYMBOL_POINT);
int freez_level = (int)SymbolInfoInteger(pos_symb,SYMBOL_TRADE_FREEZE_LEVEL);
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
if(pos_type == POSITION_TYPE_BUY)
{
double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID);
if(SL < 0) reqwest.sl = 0;
else if(SL > 0)
{
reqwest.sl = NormalizeDouble(SL,symb_digits);
if(MathAbs(current_bid - reqwest.sl) / symb_point < freez_level)
reqwest.sl = NormalizeDouble(current_bid + freez_level * symb_point,symb_digits);
}
if(TP < 0) reqwest.tp = 0;
else if(TP > 0)
{
reqwest.tp = NormalizeDouble(TP,symb_digits);
if(MathAbs(current_bid - reqwest.tp) / symb_point < freez_level)
reqwest.tp = NormalizeDouble(current_bid + freez_level * symb_point,symb_digits);
}
}
else
{
if(SL < 0) reqwest.sl = 0;
else if(SL > 0)
{
reqwest.sl = NormalizeDouble(SL,symb_digits);
double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
if(MathAbs(current_ask - reqwest.sl) / symb_point < freez_level)
reqwest.sl = NormalizeDouble(current_ask + freez_level * symb_point,symb_digits);
}
if(TP < 0) reqwest.tp = 0;
else if(TP > 0)
{
reqwest.tp = NormalizeDouble(TP,symb_digits);
double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
if(MathAbs(current_ask - reqwest.tp) / symb_point < freez_level)
reqwest.tp = NormalizeDouble(current_ask - freez_level * symb_point,symb_digits);
}
}
reqwest.position = position;
reqwest.magic = pos_mag;
reqwest.symbol = pos_symb;
reqwest.action = TRADE_ACTION_SLTP;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print(">78F8O !",position," =5 1K;0 <>48D8F8@>20=0. H81:0!",result.retcode);
Sleep(500);
}
else return true;
}
}
else Print(">78F8O !",position," =5 =0945=0.");
return false;
}
//+------------------------------------------------------------------+
bool Position_SLTP(ulong position,int SL,int TP)
{
if(PositionSelectByTicket(position))
{
double pos_op = PositionGetDouble(POSITION_PRICE_OPEN);
string pos_symb = PositionGetString(POSITION_SYMBOL);
ulong pos_mag = PositionGetInteger(POSITION_MAGIC);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
int symb_digits = (int)SymbolInfoInteger(pos_symb,SYMBOL_DIGITS);
double symb_point = SymbolInfoDouble(pos_symb,SYMBOL_POINT);
int freez_level = (int)SymbolInfoInteger(pos_symb,SYMBOL_TRADE_FREEZE_LEVEL);
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
if(pos_type == POSITION_TYPE_BUY)
{
if(SL < 0) reqwest.sl = 0;
else if(SL > 0)
{
if(SL < freez_level) SL = freez_level;
reqwest.sl = NormalizeDouble(pos_op - SL * symb_point,symb_digits);
double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID);
if(MathAbs(current_bid - reqwest.sl) / symb_point < freez_level)
reqwest.sl = NormalizeDouble(current_bid - SL * symb_point,symb_digits);
}
if(TP < 0) reqwest.tp = 0;
else if(TP > 0)
{
if(TP < freez_level) TP = freez_level;
reqwest.tp = NormalizeDouble(pos_op + TP * symb_point,symb_digits);
double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID);
if(MathAbs(current_bid - reqwest.tp) / symb_point < freez_level)
reqwest.tp = NormalizeDouble(current_bid + TP * symb_point,symb_digits);
}
}
else
{
if(SL < 0) reqwest.sl = 0;
else if(SL > 0)
{
if(SL < freez_level) SL = freez_level;
reqwest.sl = NormalizeDouble(pos_op + SL * symb_point,symb_digits);
double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
if(MathAbs(current_ask - reqwest.sl) / symb_point < freez_level)
reqwest.sl = NormalizeDouble(current_ask + SL * symb_point,symb_digits);
}
if(TP < 0) reqwest.tp = 0;
else if(TP > 0)
{
if(TP < freez_level) TP = freez_level;
reqwest.tp = NormalizeDouble(pos_op - TP * symb_point,symb_digits);
double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
if(MathAbs(current_ask - reqwest.tp) / symb_point < freez_level)
reqwest.tp = NormalizeDouble(current_ask - TP * symb_point,symb_digits);
}
}
reqwest.position = position;
reqwest.magic = pos_mag;
reqwest.symbol = pos_symb;
reqwest.action = TRADE_ACTION_SLTP;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print(">78F8O !",position," =5 1K;0 <>48D8F8@>20=0. H81:0!",result.retcode);
Sleep(500);
}
else return true;
}
}
else Print(">78F8O !",position," =5 =0945=0.");
return false;
}
//+------------------------------------------------------------------+
int CountPositions(ulong magic , string symbol)
{
int count = 0;
for(int i = 0;i < PositionsTotal();i++)
{
ulong pos = PositionGetTicket(i);
if(PositionSelectByTicket(pos))
{
ulong pos_mag = PositionGetInteger(POSITION_MAGIC);
string pos_symb = PositionGetString(POSITION_SYMBOL);
if(pos_mag == magic && pos_symb == symbol) count++;
}
}
return count;
}
//+------------------------------------------------------------------+
int CountPositions(const MqlParam &Params[])
{
uint magic = NULL;
string symbol = "";
ENUM_POSITION_TYPE type = -1;
int param_size = ArraySize(Params);
for(int i = 0;i < param_size;i++)
{
if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value;
if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value;
if(Params[i].type == TYPE_INT) type = (ENUM_POSITION_TYPE)Params[i].integer_value;
}
int count = 0;
long total_pos = PositionsTotal();
for(int i = 0;i < total_pos;i++)
{
ulong position = PositionGetTicket(i);
if(PositionSelectByTicket(position))
{
uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC);
string pos_symbol = PositionGetString(POSITION_SYMBOL);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((symbol == "" || symbol == pos_symbol) && (magic == NULL || magic == pos_magic) && (type == -1 || type == pos_type)) count++;
}
}
return count;
}
//+------------------------------------------------------------------+
int GetPositionsTickets(const MqlParam &Params[] , ulong &Positions[])
{
::ArrayFree(Positions);
int size = CountPositions(Params);
ArrayResize(Positions,size);
uint magic = NULL;
string symbol = "";
ENUM_POSITION_TYPE type = -1;
int param_size = ArraySize(Params);
for(int i = 0;i < param_size;i++)
{
if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value;
if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value;
if(Params[i].type == TYPE_INT) type = (ENUM_POSITION_TYPE)Params[i].integer_value;
}
long total_pos = PositionsTotal();
int index = 0;
for(int i = 0;i < total_pos;i++)
{
ulong position = PositionGetTicket(i);
if(PositionSelectByTicket(position))
{
uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC);
string pos_symbol = PositionGetString(POSITION_SYMBOL);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((symbol == "" || symbol == pos_symbol) && (magic == NULL || magic == pos_magic) && (type == -1 || type == pos_type))
{
Positions[index] = position;
index++;
if(index >= size) break;
}
}
}
return size;
}
//+------------------------------------------------------------------+
int CountPositions(const MqlParam &Params[],const double level_1,const double level_2,const string ctrl_symbol)
{
double point = SymbolInfoDouble(ctrl_symbol,SYMBOL_POINT);
if(level_1 / point == level_2 / point)
{
Print("5 25@=> 7040=K C@>2=8");
return 0;
}
double upLevel = MathMax(level_1,level_2);
double dnLevel;
if(upLevel == level_1) dnLevel = level_2;
else dnLevel = level_1;
uint magic = NULL;
string symbol = "";
ENUM_POSITION_TYPE type = -1;
int param_size = ArraySize(Params);
for(int i = 0;i < param_size;i++)
{
if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value;
if(Params[i].type == TYPE_STRING)
{
if(ctrl_symbol != Params[i].string_value)
{
Print("H81:0 C:070=8O A8<2>;0");
return 0;
}
symbol = Params[i].string_value;
}
if(Params[i].type == TYPE_INT) type = (ENUM_POSITION_TYPE)Params[i].integer_value;
}
int count = 0;
long total_pos = PositionsTotal();
for(int i = 0;i < total_pos;i++)
{
ulong position = PositionGetTicket(i);
if(PositionSelectByTicket(position))
{
uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC);
string pos_symbol = PositionGetString(POSITION_SYMBOL);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
if((symbol == "" || symbol == pos_symbol) && (magic == NULL || magic == pos_magic) && (type == -1 || type == pos_type))
{
double op = PositionGetDouble(POSITION_PRICE_OPEN);
if(op / point > dnLevel / point && op / point < upLevel / point) count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
int CountOrders(const MqlParam &Params[],const double level_1,const double level_2,const string ctrl_symbol)
{
double point = SymbolInfoDouble(ctrl_symbol,SYMBOL_POINT);
if(level_1 / point == level_2 / point)
{
Print("5 25@=> 7040=K C@>2=8");
return 0;
}
double upLevel = MathMax(level_1,level_2);
double dnLevel;
if(upLevel == level_1) dnLevel = level_2;
else dnLevel = level_1;
uint magic = NULL;
string symbol = "";
ENUM_ORDER_TYPE type = -1;
int param_size = ArraySize(Params);
for(int i = 0;i < param_size;i++)
{
if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value;
if(Params[i].type == TYPE_STRING)
{
if(ctrl_symbol != Params[i].string_value)
{
Print("H81:0 C:070=8O A8<2>;0");
return 0;
}
symbol = Params[i].string_value;
}
if(Params[i].type == TYPE_INT) type = (ENUM_ORDER_TYPE)Params[i].integer_value;
}
int count = 0;
long total_ord = OrdersTotal();
if(total_ord == 0) return 0;
for(int i = 0;i < total_ord;i++)
{
ulong order = OrderGetTicket(i);
if(OrderSelect(order))
{
uint ord_magic = (uint)OrderGetInteger(ORDER_MAGIC);
string ord_symbol = OrderGetString(ORDER_SYMBOL);
ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
if((symbol == "" || symbol == ord_symbol) && (magic == NULL || magic == ord_magic) && (type == -1 || type == ord_type))
{
double op = OrderGetDouble(ORDER_PRICE_OPEN);
if(op / point > dnLevel / point && op / point < upLevel / point) count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
int DistPrices(double priceA , double priceB , string symbol = NULL)
{
return (int)(MathAbs(priceA - priceB) / SymbolInfoDouble(symbol,SYMBOL_POINT));
}
//+------------------------------------------------------------------+
double LotSize(string symbol, ENUM_ORDER_TYPE type, double entry, double exit, double Foundation, double risk)
{
double lotMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double lotMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
double lot = lotMin;
double currencyRisk = (Foundation / 100) * risk;
currencyRisk = floor(currencyRisk * 100) / 100;
Print("Risk in money = ",currencyRisk);
double profit = 0;
if(OrderCalcProfit(type,symbol,lot,entry,exit,profit))
{
if(MathAbs(profit) <= currencyRisk)
{
profit = MathAbs(profit);
lot = (currencyRisk / profit) * lotMin;
lot = floor(lot / lotStep) * lotStep;
if(lot > lotMax) lot = lotMax;
}
else
{
Print(" 8A:8 ?@52KH0NB <0:A8<0;L=> 4>ABC?=>5 7=0G5=85");
return lotMin;
}
}
for(double i = lot;i >= lotMin;i -= lotStep)
{
if(OrderCalcProfit(type,symbol,lot,entry,exit,profit))
{
if(MathAbs(profit) <= currencyRisk)
{
lot = i;
break;
}
}
}
return NormalizeDouble(lot,2);
}
//+------------------------------------------------------------------+
double QoutNormalize(double value, string symbol)
{
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double tick_size = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
int digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
int iValue = (int)(value / point);
int step = (int)(tick_size / point);
int max_step;
if(step < 10) max_step = 10;
else if(step >= 10 && step < 100) max_step = 100;
else if(step >= 100 && step < 1000) max_step = 1000;
else if(step >= 1000 && step < 10000) max_step = 10000;
else max_step = 100000;
int lost_value = iValue % max_step;
if(lost_value % step == 0)
{
return (NormalizeDouble(iValue * point,digits));
}
iValue /= max_step;
for(int i = step;i < max_step;i += step)
{
if(lost_value < i)
{
lost_value = i;
break;
}
else if(i + step >= max_step)
{
iValue++;
lost_value = 0;
break;
}
}
iValue = iValue * max_step + lost_value;
value = iValue * point;
return NormalizeDouble(value,digits);
}
//+------------------------------------------------------------------+
double LotNormalize(double volume, string symbol)
{
double lotMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
double lotMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
if(volume < lotMin) return NormalizeDouble(lotMin,2);
else if(volume > lotMax) return NormalizeDouble(lotMax,2);
else
{
int i_volume = (int)(volume / lotStep);
volume = i_volume * lotStep;
}
return NormalizeDouble(volume,2);
}
//+------------------------------------------------------------------+
int CountOrders(const MqlParam &Params[])
{
uint magic = NULL;
string symbol = "";
ENUM_ORDER_TYPE type = -1;
int param_size = ArraySize(Params);
for(int i = 0;i < param_size;i++)
{
if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value;
if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value;
if(Params[i].type == TYPE_INT) type = (ENUM_ORDER_TYPE)Params[i].integer_value;
}
int count = 0;
long total_ord = OrdersTotal();
if(total_ord == 0) return 0;
for(int i = 0;i < total_ord;i++)
{
ulong order = OrderGetTicket(i);
//Print("cur order = ",order);
if(OrderSelect(order))
{
uint ord_magic = (uint)OrderGetInteger(ORDER_MAGIC);
string ord_symbol = OrderGetString(ORDER_SYMBOL);
ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
if((symbol == "" || symbol == ord_symbol) && (magic == NULL || magic == ord_magic) && (type == -1 || type == ord_type)) count++;
}
}
return count;
}
//+------------------------------------------------------------------+
int GetPendingTickets(const MqlParam &Params[] , ulong &Orders[])
{
int size = CountOrders(Params);
ArrayResize(Orders,size);
uint magic = NULL;
string symbol = "";
ENUM_ORDER_TYPE type = -1;
int param_size = ArraySize(Params);
for(int i = 0;i < param_size;i++)
{
if(Params[i].type == TYPE_UINT) magic = (uint)Params[i].integer_value;
if(Params[i].type == TYPE_STRING) symbol = Params[i].string_value;
if(Params[i].type == TYPE_INT) type = (ENUM_ORDER_TYPE)Params[i].integer_value;
}
long total_ord = OrdersTotal();
int index = 0;
for(int i = 0;i < total_ord;i++)
{
ulong order = OrderGetTicket(i);
if(OrderSelect(order))
{
uint ord_magic = (uint)OrderGetInteger(ORDER_MAGIC);
string ord_symbol = OrderGetString(ORDER_SYMBOL);
ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
if((symbol == "" || symbol == ord_symbol) && (magic == NULL || magic == ord_magic) && (type == -1 || type == ord_type))
{
Orders[index] = order;
index++;
if(index >= size) break;
}
}
}
return size;
}
//+------------------------------------------------------------------+
int GetHandle(string symbol, ENUM_TIMEFRAMES tf, ENUM_INDICATOR ind, const MqlParam &Params[])
{
if(ind == IND_CUSTOM && Params[0].type != TYPE_STRING)
{
Print("BACBAB2C5B 8<O ?>;L7>20B5;LA:>3> 8=48:0B>@0.");
return INVALID_HANDLE;
}
return IndicatorCreate(symbol,tf,ind,ArraySize(Params),Params);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
bool Order_Modify(ulong order,double entry,int SL,int TP)
{
if(OrderSelect(order))
{
double ord_op = OrderGetDouble(ORDER_PRICE_OPEN);
string ord_symb = OrderGetString(ORDER_SYMBOL);
ulong ord_mag = OrderGetInteger(ORDER_MAGIC);
ENUM_ORDER_TYPE ord_type = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
int symb_digits = (int)SymbolInfoInteger(ord_symb,SYMBOL_DIGITS);
double symb_point = SymbolInfoDouble(ord_symb,SYMBOL_POINT);
int stop_level = (int)SymbolInfoInteger(ord_symb,SYMBOL_TRADE_STOPS_LEVEL);
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
if(ord_type == ORDER_TYPE_BUY_STOP || ord_type == ORDER_TYPE_BUY_LIMIT)
{
if(entry > 0) reqwest.price = NormalizeDouble(entry,symb_digits);
else reqwest.price = NormalizeDouble(ord_op,symb_digits);
double current_ask = SymbolInfoDouble(ord_symb,SYMBOL_ASK);
if(reqwest.price <= current_ask) reqwest.type = ORDER_TYPE_BUY_LIMIT;
else reqwest.type = ORDER_TYPE_BUY_STOP;
if(SL < 0) reqwest.sl = 0;
else if(SL > 0)
{
if(SL < stop_level) SL = stop_level;
reqwest.sl = NormalizeDouble(reqwest.price - SL * symb_point,symb_digits);
//double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID);
//if(MathAbs(current_bid - reqwest.sl) / symb_point < freez_level)
// reqwest.sl = NormalizeDouble(current_bid - SL * symb_point,symb_digits);
}
if(TP < 0) reqwest.tp = 0;
else if(TP > 0)
{
if(TP < stop_level) TP = stop_level;
reqwest.tp = NormalizeDouble(reqwest.price + TP * symb_point,symb_digits);
//double current_bid = SymbolInfoDouble(pos_symb,SYMBOL_BID);
//if(MathAbs(current_bid - reqwest.tp) / symb_point < freez_level)
// reqwest.tp = NormalizeDouble(current_bid + TP * symb_point,symb_digits);
}
}
else
{
if(entry > 0) reqwest.price = NormalizeDouble(entry,symb_digits);
else reqwest.price = NormalizeDouble(ord_op,symb_digits);
double current_bid = SymbolInfoDouble(ord_symb,SYMBOL_BID);
if(reqwest.price >= current_bid) reqwest.type = ORDER_TYPE_SELL_LIMIT;
else reqwest.type = ORDER_TYPE_SELL_STOP;
if(SL < 0) reqwest.sl = 0;
else if(SL > 0)
{
if(SL < stop_level) SL = stop_level;
reqwest.sl = NormalizeDouble(reqwest.price + SL * symb_point,symb_digits);
//double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
//if(MathAbs(current_ask - reqwest.sl) / symb_point < freez_level)
// reqwest.sl = NormalizeDouble(current_ask + SL * symb_point,symb_digits);
}
if(TP < 0) reqwest.tp = 0;
else if(TP > 0)
{
if(TP < stop_level) TP = stop_level;
reqwest.tp = NormalizeDouble(reqwest.price - TP * symb_point,symb_digits);
//double current_ask = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
//if(MathAbs(current_ask - reqwest.tp) / symb_point < freez_level)
// reqwest.tp = NormalizeDouble(current_ask - TP * symb_point,symb_digits);
}
}
reqwest.order = order;
reqwest.magic = ord_mag;
reqwest.symbol = ord_symb;
reqwest.action = TRADE_ACTION_MODIFY;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("@45@ !",order," =5 1K; <>48D8F8@>20=. H81:0!",result.retcode);
Sleep(500);
}
else return true;
}
}
else Print("@45@ !",order," =5 =0945=.");
return false;
}
//+------------------------------------------------------------------+
bool Delete_Order(ulong order)
{
if(OrderSelect(order))
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_REMOVE;
reqwest.order = order;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("@45@ !",order," =5 1K; C40;5=. H81:0!",result.retcode);
Sleep(500);
}
else return true;
}
}
else Print("@45@ !",order," =5 >=0@C65=.");
return false;
}
//+------------------------------------------------------------------+
enum LAST_POSITION_OPTION
{
LAST_POSITION_UP,
LAST_POSITION_DOWN,
LAST_POSITION_TIME
};
//+------------------------------------------------------------------+
ulong Ticket_Last_Buy(const ulong &Positions[] , LAST_POSITION_OPTION last_pos)
{
ulong ticket = 0;
double open = 0;
datetime time = 0;
int size = ArraySize(Positions);
for(int i = 0;i < size;i++)
{
ulong pos = Positions[i];
if(PositionSelectByTicket(pos))
{
if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue;
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME);
if(last_pos == LAST_POSITION_DOWN)
{
if(open == 0 || pos_open < open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_UP)
{
if(open == 0 || pos_open > open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_TIME)
{
if(time == 0 || pos_time > time)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
}
}
return ticket;
}
//+------------------------------------------------------------------+
ulong Ticket_Last_Sell(const ulong &Positions[] , LAST_POSITION_OPTION last_pos)
{
ulong ticket = 0;
double open = 0;
datetime time = 0;
int size = ArraySize(Positions);
for(int i = 0;i < size;i++)
{
ulong pos = Positions[i];
//Print("Position sell = ",pos);
if(PositionSelectByTicket(pos))
{
if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue;
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME);
if(last_pos == LAST_POSITION_DOWN)
{
if(open == 0 || pos_open < open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_UP)
{
if(open == 0 || pos_open > open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_TIME)
{
if(time == 0 || pos_time > time)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
}
}
return ticket;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
double GetComission(ulong position)
{
if(!HistorySelectByPosition(position)) return 0;
double comm = 0;
int tot_deals = HistoryDealsTotal();
for(int i = 0;i < tot_deals;i++)
{
ulong deal = HistoryDealGetTicket(i);
comm += HistoryDealGetDouble(deal,DEAL_COMMISSION);
}
return comm;
}
//+------------------------------------------------------------------+
double Profit(ulong position, double out_comission, bool subtotals = false)
{
double total_profit = 0;
double profit = 0, swap = 0, comission = 0;
double volume = 0;
if(PositionSelectByTicket(position))
{
profit = PositionGetDouble(POSITION_PROFIT);
swap = PositionGetDouble(POSITION_SWAP);
volume = PositionGetDouble(POSITION_VOLUME);
}
if(HistorySelectByPosition(position))
{
int total_deals = HistoryDealsTotal();
for(int i = 0;i < total_deals;i++)
{
ulong deal = HistoryDealGetTicket(i);
if(subtotals)
{
profit += HistoryDealGetDouble(deal,DEAL_PROFIT);
swap += HistoryDealGetDouble(deal,DEAL_SWAP);
}
comission += HistoryDealGetDouble(deal,DEAL_COMMISSION);
}
}
total_profit = (profit + swap + comission) - out_comission * volume;
return NormalizeDouble(total_profit,2);
}
//+---------------------------------------------------------------+
double Profit_History(datetime begin_time , datetime end_time , string symbol , uint magic)
{
ulong Positions[];
MqlParam params[2];
params[0].type = TYPE_STRING;
params[0].string_value = symbol;
params[1].type = TYPE_UINT;
params[1].integer_value = magic;
GetPositionsTickets(params, Positions);
double total_profit = 0;
double profit = 0, swap = 0, comission = 0;
if(HistorySelect(begin_time,end_time))
{
for(int i = 0;i < HistoryDealsTotal();i++)
{
ulong deal = HistoryDealGetTicket(i);
string deal_symbol = HistoryDealGetString(deal,DEAL_SYMBOL);
ulong deal_magic = HistoryDealGetInteger(deal,DEAL_MAGIC);
if(deal_symbol == symbol && deal_magic == magic)
{
for(int z = 0;z < ArraySize(Positions);z++)
{
ulong deal_pos = HistoryDealGetInteger(deal,DEAL_POSITION_ID);
if(deal_pos == Positions[z])
{
deal = 0;
break;
}
}
if(deal > 0) total_profit += HistoryDealGetDouble(deal,DEAL_PROFIT) + HistoryDealGetDouble(deal,DEAL_SWAP)
+ HistoryDealGetDouble(deal,DEAL_COMMISSION);
}
}
}
return NormalizeDouble(total_profit,2);
}
//+---------------------------------------------------------------+
bool Close_Position(ulong position, int slipage)
{
if(PositionSelectByTicket(position))
{
string pos_symb = PositionGetString(POSITION_SYMBOL);
ulong pos_mag = PositionGetInteger(POSITION_MAGIC);
double pos_volume = PositionGetDouble(POSITION_VOLUME);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
if(pos_type == POSITION_TYPE_BUY)
{
reqwest.price = SymbolInfoDouble(pos_symb,SYMBOL_BID);
reqwest.type = ORDER_TYPE_SELL;
}
else
{
reqwest.price = SymbolInfoDouble(pos_symb,SYMBOL_ASK);
reqwest.type = ORDER_TYPE_BUY;
}
reqwest.position = position;
reqwest.magic = pos_mag;
reqwest.symbol = pos_symb;
reqwest.volume = pos_volume;
reqwest.deviation = slipage;
reqwest.action = TRADE_ACTION_DEAL;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print(">78F8O !",position," =5 1K;0 70:@KB0. H81:0!",result.retcode);
Sleep(500);
}
else return true;
}
}
else Print(">78F8O !",position," =5 =0945=0.");
return false;
}
//+------------------------------------------------------------------+
bool SetTralLevel(ulong position , int tralLevel)
{
if(PositionSelectByTicket(position))
{
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
ENUM_POSITION_TYPE pos_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double pos_sl = PositionGetDouble(POSITION_SL);
string pos_symbol = PositionGetString(POSITION_SYMBOL);
int pos_magic = (int)PositionGetInteger(POSITION_MAGIC);
if(pos_type == POSITION_TYPE_BUY)
{
double close_price = SymbolInfoDouble(pos_symbol,SYMBOL_BID);
double point = SymbolInfoDouble(pos_symbol,SYMBOL_POINT);
if(close_price > pos_open)
{
double tral_level;
if(pos_sl < pos_open) tral_level = pos_open + tralLevel * point;
else tral_level = pos_sl + tralLevel * point;
int stop_level = (int)SymbolInfoInteger(pos_symbol,SYMBOL_TRADE_STOPS_LEVEL);
if(DistPrices(close_price,tral_level,pos_symbol) < stop_level) tral_level = close_price - stop_level * point;
if(tral_level > pos_sl)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.position = position;
reqwest.action = TRADE_ACTION_SLTP;
reqwest.sl = tral_level;
reqwest.symbol = pos_symbol;
reqwest.magic = pos_magic;
if(OrderSend(reqwest,result)) return true;
else Print("H81:0 B@0;8@>20=8O ",result.retcode);
}
else return true;
}
}
else
{
double close_price = SymbolInfoDouble(pos_symbol,SYMBOL_ASK);
double point = SymbolInfoDouble(pos_symbol,SYMBOL_POINT);
if(close_price < pos_open)
{
double tral_level;
if(pos_sl < pos_open) tral_level = pos_open - tralLevel * point;
else tral_level = pos_sl - tralLevel * point;
int stop_level = (int)SymbolInfoInteger(pos_symbol,SYMBOL_TRADE_STOPS_LEVEL);
if(DistPrices(close_price,tral_level,pos_symbol) < stop_level) tral_level = close_price + stop_level * point;
if(tral_level > pos_sl)
{
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.position = position;
reqwest.action = TRADE_ACTION_SLTP;
reqwest.sl = tral_level;
reqwest.symbol = pos_symbol;
reqwest.magic = pos_magic;
if(OrderSend(reqwest,result)) return true;
else Print("H81:0 B@0;8@>20=8O ",result.retcode);
}
else return true;
}
}
}
return false;
}
//+---------------------------------------------------------------+
bool Close_PartPosition(ulong position, int slipage, ulong opposing_pos)
{
if(!PositionSelectByTicket(position))
{
Print(__FUNCTION__," 5 =0945=0 ?>78F8O 4;O 70:@KB8O");
return false;
}
uint pos_magic = (uint)PositionGetInteger(POSITION_MAGIC);
if(!PositionSelectByTicket(opposing_pos))
{
Print(__FUNCTION__," 5 =0945=0 2AB@5G=0O ?>78F8O");
return false;
}
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
reqwest.action = TRADE_ACTION_CLOSE_BY;
reqwest.deviation = slipage;
reqwest.position = position;
reqwest.position_by = opposing_pos;
reqwest.magic = pos_magic;
if(OrderSend(reqwest,result)) return true;
return false;
}
//+------------------------------------------------------------------+
/*double GetAveragePrice(const ulong &positions[], string symbol, double out_comm)
{
double totVolume = 0, totOpVolume = 0, totSwapCom = 0;
int koef = 1;
for(int i = 0,size = ::ArraySize(positions);i < size;i++)
{
if(!::PositionSelectByTicket(positions[i])) continue;
if(::PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) koef = 1;
else if(::PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) koef = -1;
double volume = ::PositionGetDouble(POSITION_VOLUME);
double op = ::PositionGetDouble(POSITION_PRICE_OPEN);
totOpVolume += (volume * op * koef);
totVolume += (volume * koef);
//double commission = GetComission(positions[i]);
totSwapCom += ::PositionGetDouble(POSITION_SWAP) /*+ commission *//*- out_comm * volume;*/
/*}
if(totVolume == 0) return 0;
double AvPrice = ::MathAbs(totOpVolume / totVolume);
double point = ::SymbolInfoDouble(symbol,SYMBOL_POINT);
if(totVolume > 0) AvPrice -= (totSwapCom / ::MathAbs(totVolume) * point);
if(totVolume < 0) AvPrice += (totSwapCom / ::MathAbs(totVolume) * point);
return ::NormalizeDouble(AvPrice,(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS));
}*/
//+------------------------------------------------------------------+
double GetPointValue(string symbol)
{
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double tickValue = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
double tickSize = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
double pointValue = tickValue * (point / tickSize);
return pointValue;
}
//+------------------------------------------------------------------+
//flag = 0 - All volume; 1 - BUY only; 2 - SELL only
double GetTotalVolume(const ulong &positions[], int flag = 0)
{
double tot_volume = 0;
for(int i = 0,size = ArraySize(positions);i < size;i++)
{
if(!PositionSelectByTicket(positions[i])) continue;
if(flag == 0) tot_volume += PositionGetDouble(POSITION_VOLUME);
else
{
if(flag == 1)
{
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) tot_volume += PositionGetDouble(POSITION_VOLUME);
}
else if(flag == 2)
{
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) tot_volume += PositionGetDouble(POSITION_VOLUME);
}
}
}
return tot_volume;
}
//+------------------------------------------------------------------+
int GetIntFromDouble(double value, int digits)
{
int result = 0;
if(digits == 1) result = (int)(value * 10);
else if(digits == 2) result = (int)(value * 100);
else if(digits == 3) result = (int)(value * 1000);
else if(digits == 4) result = (int)(value * 10000);
else if(digits == 5) result = (int)(value * 100000);
return result;
}
//+------------------------------------------------------------------+
double GetDoubleFromInt(int value,int digits)
{
double result = 0.0;
if(digits == 1) result = value * 0.1;
else if(digits == 2) result = value * 0.01;
else if(digits == 3) result = value * 0.001;
else if(digits == 4) result = value * 0.0001;
else if(digits == 5) result = value * 0.00001;
return NormalizeDouble(result,digits);
}
//+------------------------------------------------------------------+
double CostPoint(string symbol, double volume, ENUM_POSITION_TYPE type)
{
double price = SymbolInfoDouble(symbol, SYMBOL_BID);
if(type == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK);
if (price == 0) {
PrintFormat("%s / ERROR: >102LB5 2 '1>@ @K=:0' %s", __FUNCTION__, symbol);
return 0;
}
// >?@545;O5< 2A?><>30B5;L=K5 40==K5
string xxx = StringSubstr(symbol, 0, 3);
string yyy = StringSubstr(symbol, 3, 3);
string tile = (StringLen(symbol) > 6) ? StringSubstr(symbol, 6) : "";
double contract = volume * SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
double costPoint = contract * SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
// >?@545;O5< F5=C >4=>3> ?C=:B0
if (yyy == "USD"); // >1@0B=0O :>B8@>2:0
// =8G53> =5 45;05<
else if (xxx == "USD") // ?@O<0O :>B8@>2:0
costPoint = costPoint / price;
else { // :@>AA-:C@A
string symbol1 = yyy + "USD" + tile;
price = SymbolInfoDouble(symbol1, SYMBOL_BID);
if(type == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK);
if (price > 0) costPoint = costPoint * price;
else {
string symbol2 = "USD" + yyy + tile;
price = SymbolInfoDouble(symbol2, SYMBOL_BID);
if(type == POSITION_TYPE_SELL) price = SymbolInfoDouble(symbol, SYMBOL_ASK);
if (price == 0) {
PrintFormat("%s: >102LB5 2 '1>@ @K=:0' %s 8;8 %s", __FUNCTION__, symbol1, symbol2);
return 0;
}
costPoint = costPoint / price;
}
}
return costPoint;
}
//+---------------------------------------------------------------+
bool Close_PartPosition(ulong position, double close_volume, int slipage)
{
ResetLastError();
if(!PositionSelectByTicket(position))
{
Print(__FUNCTION__," =5 A<>3;0 =09B8 70:@K205<CN ?>78F8N. H81:0 ",GetLastError());
return false;
}
string symbol = PositionGetString(POSITION_SYMBOL);
uint magic = (uint)PositionGetInteger(POSITION_MAGIC);
double lot = PositionGetDouble(POSITION_VOLUME);
if(lot > close_volume) lot = close_volume;
MqlTradeRequest reqwest;
MqlTradeResult result;
ZeroMemory(reqwest);
ZeroMemory(result);
if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
reqwest.type = ORDER_TYPE_SELL;
reqwest.price = SymbolInfoDouble(symbol,SYMBOL_BID);
}
else
{
reqwest.type = ORDER_TYPE_BUY;
reqwest.price = SymbolInfoDouble(symbol,SYMBOL_ASK);
}
reqwest.action = TRADE_ACTION_DEAL;
reqwest.position = position;
reqwest.symbol = symbol;
reqwest.volume = lot;
reqwest.magic = magic;
reqwest.deviation = slipage;
for(int i = 0;i < 10;i++)
{
if(!OrderSend(reqwest,result))
{
Print("'0AB8G=>5 70:@KB85 =5 C40;>AL. H81:0 A5@25@0 ",result.retcode);
Sleep(500);
}
else
{
return true;
}
}
return false;
}
//+---------------------------------------------------------------+
ulong Ticket_Last_Buy(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const ulong ex_pos)
{
ulong ticket = 0;
double open = 0;
datetime time = 0;
int size = ArraySize(Positions);
for(int i = 0;i < size;i++)
{
ulong pos = Positions[i];
if(PositionSelectByTicket(pos))
{
if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue;
if(PositionGetInteger(POSITION_TICKET) == ex_pos) continue;
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME);
if(last_pos == LAST_POSITION_DOWN)
{
if(open == 0 || pos_open < open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_UP)
{
if(open == 0 || pos_open > open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_TIME)
{
if(time == 0 || pos_time > time)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
}
}
return ticket;
}
//+------------------------------------------------------------------+
ulong Ticket_Last_Sell(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const ulong ex_pos)
{
ulong ticket = 0;
double open = 0;
datetime time = 0;
int size = ArraySize(Positions);
for(int i = 0;i < size;i++)
{
ulong pos = Positions[i];
if(PositionSelectByTicket(pos))
{
if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue;
if(PositionGetInteger(POSITION_TICKET) == ex_pos) continue;
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME);
if(last_pos == LAST_POSITION_DOWN)
{
if(open == 0 || pos_open < open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_UP)
{
if(open == 0 || pos_open > open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_TIME)
{
if(time == 0 || pos_time > time)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
}
}
return ticket;
}
//+------------------------------------------------------------------+
ulong Ticket_Last_Buy(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const double ex_volume)
{
ulong ticket = 0;
double open = 0;
datetime time = 0;
int size = ArraySize(Positions);
for(int i = 0;i < size;i++)
{
ulong pos = Positions[i];
if(PositionSelectByTicket(pos))
{
if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_BUY) continue;
if(PositionGetDouble(POSITION_VOLUME) <= ex_volume) continue;
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME);
if(last_pos == LAST_POSITION_DOWN)
{
if(open == 0 || pos_open < open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_UP)
{
if(open == 0 || pos_open > open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_TIME)
{
if(time == 0 || pos_time > time)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
}
}
return ticket;
}
//+------------------------------------------------------------------+
ulong Ticket_Last_Sell(const ulong &Positions[] , LAST_POSITION_OPTION last_pos, const double ex_volume)
{
ulong ticket = 0;
double open = 0;
datetime time = 0;
int size = ArraySize(Positions);
for(int i = 0;i < size;i++)
{
ulong pos = Positions[i];
if(PositionSelectByTicket(pos))
{
if(PositionGetInteger(POSITION_TYPE) != POSITION_TYPE_SELL) continue;
if(PositionGetDouble(POSITION_VOLUME) <= ex_volume) continue;
double pos_open = PositionGetDouble(POSITION_PRICE_OPEN);
datetime pos_time = (datetime)PositionGetInteger(POSITION_TIME);
if(last_pos == LAST_POSITION_DOWN)
{
if(open == 0 || pos_open < open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_UP)
{
if(open == 0 || pos_open > open)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
else if(last_pos == LAST_POSITION_TIME)
{
if(time == 0 || pos_time > time)
{
open = pos_open;
time = pos_time;
ticket = pos;
}
}
}
}
return ticket;
}
//+------------------------------------------------------------------+
/*double GetAveragePrice(const ulong &Positions[],string symbol,ENUM_POSITION_TYPE type,const double out_com)
{
for(int i = 0,size = ArraySize(Positions);i < size;i++)
{
if(!PositionSelectByTicket(Positions[i])) return 0;
if(PositionGetInteger(POSITION_TYPE) != type) return 0;
}
double AvPrice = 0;
return AvPrice;
}*/
//+------------------------------------------------------------------+
enum ENUM_AVERAGE_DIRECTION
{
AVERAGE_DIRECTION_ALL = 0,
AVERAGE_DIRECTION_BUY,
AVERAGE_DIRECTION_SELL
};
double GetAveragePrice(const ulong &Positions[],
const double out_com,
ENUM_AVERAGE_DIRECTION avDirection = AVERAGE_DIRECTION_ALL)
{
string symbol = "";
for(int i = 0,size = ArraySize(Positions);i < size;i++)
{
if(!PositionSelectByTicket(Positions[i])) return 0;
if(symbol == "") symbol = PositionGetString(POSITION_SYMBOL);
else if(symbol == PositionGetString(POSITION_SYMBOL)) continue;
else if (symbol != "" && symbol != PositionGetString(POSITION_SYMBOL)) return 0;
}
double buyVolume = 0, sellVolume = 0, buyProfit = 0, sellProfit = 0;
for(int i = 0,size = ArraySize(Positions);i < size;i++)
{
PositionSelectByTicket(Positions[i]);
double lot = PositionGetDouble(POSITION_VOLUME);
double profit = PositionGetDouble(POSITION_PROFIT);
double swap = PositionGetDouble(POSITION_SWAP);
double comission = GetComission(Positions[i]) + ((out_com * -1) * lot);
double posProfit = profit + swap + comission;
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
buyVolume += lot;
buyProfit += posProfit;
}
else
{
sellVolume += lot;
sellProfit += posProfit;
}
}
if(avDirection == AVERAGE_DIRECTION_ALL && buyVolume == sellVolume) return 0;
else if(avDirection == AVERAGE_DIRECTION_BUY && buyVolume == 0) return 0;
else if(avDirection == AVERAGE_DIRECTION_SELL && sellVolume == 0) return 0;
double avPrice = 0;
double tickValue = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
int digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
double point = SymbolInfoDouble(symbol,SYMBOL_POINT);
double bid = SymbolInfoDouble(symbol,SYMBOL_BID);
double ask = SymbolInfoDouble(symbol,SYMBOL_ASK);
double buyZeroLevel = bid - (buyProfit / (tickValue * buyVolume) * point);
double sellZeroLevel = ask + (sellProfit / (tickValue * sellVolume) * point);
buyZeroLevel = NormalizeDouble(buyZeroLevel,digits);
sellZeroLevel = NormalizeDouble(sellZeroLevel,digits);
if(buyVolume > sellVolume) avPrice = bid - ((buyProfit + sellProfit) / (tickValue * (buyVolume - sellVolume)) * point);
else avPrice = ask + ((buyProfit + sellProfit) / (tickValue * (sellVolume - buyVolume)) * point);
avPrice = NormalizeDouble(avPrice,digits);
if(avDirection == AVERAGE_DIRECTION_BUY) return buyZeroLevel;
else if(avDirection == AVERAGE_DIRECTION_SELL) return sellZeroLevel;
else return avPrice;
}
//+------------------------------------------------------------------+
template<typename T>
string GetTypeName(const T &t){
return (typename(T));
}
//+------------------------------------------------------------------+
template<typename T>
bool fileWriteBinStuct(const string &file, const T &fiboStruct){
int handle =::FileOpen(file,FILE_WRITE|FILE_BIN);
::ResetLastError();
if(handle == INVALID_HANDLE){
::Print("Unable acces to file ",file," Error ",::GetLastError());
return false;
}
uint count = ::FileWriteStruct(handle,fiboStruct);
if(count == 0){
::Print("Unable write data to file ",file," Error ",::GetLastError());
return false;
}
::FileClose(handle);
return true;
}
//+------------------------------------------------------------------+
template<typename T>
bool fileReadBinStuct(const string &file, T &Struct){
int handle =::FileOpen(file,FILE_READ|FILE_BIN);
::ResetLastError();
if(handle == INVALID_HANDLE){
::Print("Unable acces to file ",file," Error ",::GetLastError());
return false;
}
uint count = ::FileReadStruct(handle,Struct);
if(count == 0){
::Print("Unable read data from file ",file," Error ",::GetLastError());
return false;
}
::FileClose(handle);
return true;
}
//+------------------------------------------------------------------+
void GetFillMode(const string symbol,ENUM_ORDER_TYPE_FILLING &fill_type){
uint filling = (uint)::SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);
if((filling&SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK)
fill_type = ORDER_FILLING_FOK;
else if((filling&SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC)
fill_type = ORDER_FILLING_IOC;
else
fill_type = ORDER_FILLING_RETURN;
}
//------------------------------------------------------------------|
// END OF NAMESPACE std |
//------------------------------------------------------------------|
}
#endif