Hedging PRO_Beta
Похожие материалы по тегам
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «hedging pro_beta.mq4» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
Hedging PRO_Beta — это торговый советник для MetaTrader, предназначенный для управления открытыми позициями и автоматического открытия ордеров в направлениях BUY и SELL. При отсутствии открытой позиции в нужном направлении советник выставляет рыночные ордера с заданным TakeProfit. В коде реализованы несколько подсистем управления ордерами с разными магическими числами, а также функция модификации TakeProfit на основе средневзвешенной цены открытых позиций.
Советник отображает на графике информацию о количестве открытых ордеров, суммарных лотах, текущей прибыли и просадке. В OnTick обрабатываются рыночные события: проверка условий открытия новых позиций, управление стоп-лоссами и тейк-профитами. Также реализована проверка максимального плавающего убытка с возможностью остановки торговли.
Встроенная библиотека ADBF предоставляет обёртки для торговых API: отправка ордеров, закрытие и модификация позиций, получение данных об аккаунте и ценовых данных. Включена обработка таймера и графических событий. Советник проверяет имя программы и при расхождении прекращает работу.
Настройки программы
| Настройка | Описание |
|---|---|
| Lots | Lots — Объём лота для открытия новых ордеров. |
| PipStep | PipStep — Шаг в пунктах, используемый для условий открытия дополнительных ордеров. |
| MaxLots | MaxLots — Максимально допустимый объём лота для открытых позиций. |
| TakeProfit | TakeProfit — Расстояние в пунктах до TakeProfit для открытых ордеров. |
| UseTrailingStop | UseTrailingStop — Переключатель включения/выключения трейлинг-стопа. |
| TrailStart | TrailStart — Порог в пунктах для активации трейлинг-стопа. |
| TrailStop | TrailStop — Расстояние в пунктах от цены до трейлинг-стопа после активации. |
| slip | slip — Допустимое отклонение цены (проскальзывание) при открытии и модификации ордеров. |
Поиск по коду файла
#property version "2.1"
#property strict
#property icon "\\Images\\icon.ico"
#define LICENSE_PANEL
const string VERSION="2.1";
const int ADMIN_ID=36;
const int PRODUCT_ID=79;//Hedging PRO_Beta_Beta
#include <EA_Protect/Protect.mqh>
SHOW_LICENSE_PARAMS
PROTECT_CREATE
#define MODE_SPREAD 13
#define MODE_MINLOT 23
#define MODE_TICKVALUE 16
#define SELECT_BY_POS 0
#define MODE_TRADES 0
#define OP_BUY 0
#define OP_SELL 1
#define OP_BUYLIMIT 2
#define OP_BUYSTOP 4
#define OP_SELLLIMIT 3
#define OP_SELLSTOP 5
input double Lots = 0.01;
double LotExponent = 1.2; // Layer Multiplier
int lotdecimal = 2;
input double PipStep = 600.0; // PipStep
input double MaxLots = 1.0;
bool MM = false;
input double TakeProfit = 300.0;
bool UseEquityStop = false;
double TotalEquityRisk = 20.0;
input bool UseTrailingStop = false;
input double TrailStart = 13.0;
input double TrailStop = 3.0;
input double slip = 5.0;
/*"SETTINGS For Order 1"*/
string x="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
string ATURANFIBO = "SETTINGS ORDER BUY"; // Setting Order Buy
int MaxTrades_Hilo = 50; // Maxtrade Order Buy
bool gi_184 = false;
double gd_188 = 48.0;
double g_pips_196 = 40.0;
double g_slippage_204;
int MagicNumber_Hilo = 852791; // Magic Order Buy
double g_price_216;
double gd_224;
double gd_unused_232;
double gd_unused_240;
double gd_248;
double gd_256;
double g_price_264;
double g_bid_272;
double g_ask_280;
double gd_288;
double gd_296;
double gd_304;
bool gi_312;
string gs_316 = "[Hedging PRO_Beta]";
int gi_324 = 0;
int gi_328;
int gi_332 = 0;
double gd_336;
int g_pos_344 = 0;
int gi_348;
double gd_352 = 0.0;
bool gi_360 = false;
bool gi_364 = false;
bool gi_368 = false;
int gi_372;
bool gi_376 = false;
double gd_380;
double gd_388;
double PercentToRisk = 0.02;
double TahananModal = 10000.0;
/*"SETTINGS For Order 2"*/
string xx="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
string ATURANAFSCALPER = "SETTINGS ORDER SELL"; // Setting Order Sell
int MaxTrades_15 = 50; // Maxtrade Order Sell
int g_timeframe_408 = PERIOD_H1;
double g_pips_412 = 40.0;
bool gi_420 = false;
double gd_424 = 48.0;
double g_slippage_432;
int g_magic_176_15 = 852792; // Magic Order Sell
double g_price_444;
double gd_452;
double gd_unused_460;
double gd_unused_468;
double g_price_476;
double g_bid_484;
double g_ask_492;
double gd_500;
double gd_508;
double gd_516;
bool gi_524;
string gs_528 = "[Hedging PRO_Beta]";
int gi_536 = 0;
int gi_540;
int gi_544 = 0;
double gd_548;
int g_pos_556 = 0;
int gi_560;
double gd_564 = 0.0;
bool gi_572 = false;
bool gi_576 = false;
bool gi_580 = false;
int gi_584;
bool gi_588 = false;
double gd_592;
double gd_600;
int g_datetime_608 = 1;
/*"SETTINGS For Order 3 UPDATING"*/
string xxx="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
string ATURANTRENDKILLER = "SETTINGS ORDER SELL"; // Setting Order Sell
int MaxTrades_16 = 11; // Maxtrade Order Sell
int g_timeframe_624 = PERIOD_M1;
double g_pips_628 = 40.0;
bool gi_636 = false;
double gd_640 = 48.0;
double g_slippage_648;
int g_magic_176_16 = 852793; // Magic Order Sell
bool UseNewsFilter = false;
double g_price_660;
double gd_668;
double gd_unused_676;
double gd_unused_684;
double g_price_692;
double g_bid_700;
double g_ask_708;
double gd_716;
double gd_724;
double gd_732;
bool gi_740;
string gs_744 = "[Hedging PRO_Beta-EA-Sell]";
int gi_752 = 0;
int gi_756;
int gi_760 = 0;
double gd_764;
int g_pos_772 = 0;
int gi_776;
double gd_780 = 0.0;
bool gi_788 = false;
bool gi_792 = false;
bool gi_796 = false;
int gi_800;
bool gi_804 = false;
bool cg =false;
double gd_808;
double gd_816;
int g_datetime_824 = 1;
int g_timeframe_828 = PERIOD_M1;
int g_timeframe_832 = PERIOD_M5;
int g_timeframe_836 = PERIOD_M15;
int g_timeframe_840 = PERIOD_M30;
int g_timeframe_844 = PERIOD_H1;
int g_timeframe_848 = PERIOD_H4;
int g_timeframe_852 = PERIOD_D1;
bool g_corner_856 = true;
int gi_860 = 0;
int gi_864 = 10;
int g_window_868 = 0;
bool gi_872 = true;
bool gi_unused_876 = true;
bool gi_880 = false;
int g_color_884 = Gray;
int g_color_888 = Gray;
int g_color_892 = Gray;
int g_color_896 = DarkOrange;
int gi_unused_900 = 36095;
int g_color_904 = Lime;
int g_color_908 = OrangeRed;
int gi_912 = 65280;
int gi_916 = 17919;
int g_color_920 = Lime;
int g_color_924 = Red;
int g_color_928 = Orange;
int g_period_932 = 8;
int g_period_936 = 17;
int g_period_940 = 9;
int g_applied_price_944 = PRICE_CLOSE;
int g_color_948 = Lime;
int g_color_952 = Tomato;
int g_color_956 = Green;
int g_color_960 = Red;
string gs_dummy_1088;
string g_text_1096;
string g_text_1104;
string g_dbl2str_1112 = "";
string g_dbl2str_1120 = "";
int g_color_1128 = ForestGreen;
int li_0;
int li_4;
int li_8;
int li_12;
int li_16;
int li_20;
int li_24;
color color_28;
color color_32;
color color_36;
color color_40;
color color_44;
color color_48;
color color_52;
string ls_unused_56;
color color_64;
color color_68;
color color_72;
color color_76;
color color_80;
color color_84;
color color_88;
color color_92;
string ls_unused_96;
color color_104;
int li_unused_108;
double ihigh_112;
double ilow_120;
double iclose_128;
double iclose_136;
double ld_144;
double ld_152;
double ld_160;
int li_168;
int count_172;
double ld_176;
double ld_184;
int li_192;
int count_196;
string ManagementProfitTarget ="***** Management Floating Loss *****"; // Management Floating Loss
bool UseFloatingLoss_Target = false; // Use stop a maximum floating loss
int FloatingLoss_Target = -500; // Maximum Floating Loss (example input: -500)
int OnInit()
{
// код доступен только после оплаты
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0);
EventKillTimer();
PROTECT_DEINIT
}
void OnTimer()
{
PROTECT_TIMER
}
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam) {PROTECT_EVENT}
void OnTick()
{
// код доступен только после оплаты
}
void Loadtext(){
datetime currentTime = TimeCurrent();
MqlDateTime mqlDateTime;
TimeToStruct(currentTime, mqlDateTime);
int day = mqlDateTime.day;
int month = mqlDateTime.mon;
int year = mqlDateTime.year;
int lbldayWidth = ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
int lbldayHeight = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
ObjectSetInteger(0, "lblDay", OBJPROP_XDISTANCE, lbldayWidth - 250); // X position
ObjectSetInteger(0, "lblDay", OBJPROP_YDISTANCE, lbldayHeight/10); // Y position
ObjectSetString(0,"lblDay",OBJPROP_FONT,"Arial Bold");
ObjectSetInteger(0, "lblDay", OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, "lblDay", OBJPROP_FONTSIZE, 12);
int totalBuyOrders = 0;
double totalLotsBuy = 0.0;
int totalSellOrders = 0;
double totalLotsSell = 0.0;
string currentSymbol = Symbol(); // Get the name of the current currency pair
for(int i = 0; i < ADBF::OrdersTotal(); i++)
{
if(ADBF::OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && ADBF::OrderType() == OP_BUY && ADBF::OrderSymbol() == currentSymbol)
{
totalBuyOrders++;
totalLotsBuy += ADBF::OrderLots();
}
}
for(int i = 0; i < ADBF::OrdersTotal(); i++)
{
if(ADBF::OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && ADBF::OrderType() == OP_SELL && ADBF::OrderSymbol() == currentSymbol)
{
totalSellOrders++;
totalLotsSell += ADBF::OrderLots();
}
}
double highestBalance = ADBF::AccountEquity(); // This value needs to be updated frequently during trading
double currentBalance = ADBF::AccountBalance();
double drawdown = 0;
if(highestBalance > 0)
{
drawdown = 100.0 * (highestBalance - currentBalance) / highestBalance;
}
ObjectSetInteger(0, "lblBuy", OBJPROP_XDISTANCE, lbldayWidth - 250); // X position
ObjectSetInteger(0, "lblBuy", OBJPROP_YDISTANCE, lbldayHeight/8); // Y position
ObjectSetString(0,"lblBuy",OBJPROP_FONT,"Courier New");
ObjectSetInteger(0, "lblBuy", OBJPROP_COLOR, clrLimeGreen);
ObjectSetInteger(0, "lblBuy", OBJPROP_FONTSIZE, 10);
ObjectSetInteger(0, "lblSell", OBJPROP_XDISTANCE, lbldayWidth - 250); // X position
ObjectSetInteger(0, "lblSell", OBJPROP_YDISTANCE, lbldayHeight/7); // Y position
ObjectSetString(0,"lblSell",OBJPROP_FONT,"Courier New");
ObjectSetInteger(0, "lblSell", OBJPROP_COLOR, clrLimeGreen);
ObjectSetInteger(0, "lblSell", OBJPROP_FONTSIZE, 10);
ObjectCreate(0, "lblProfit", OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, "lblProfit", OBJPROP_XDISTANCE, lbldayWidth - 1300); // X position
ObjectSetInteger(0, "lblProfit", OBJPROP_YDISTANCE, lbldayHeight/14); // Y position
ObjectSetString(0, "lblProfit", OBJPROP_TEXT, "Profit: "+ NormalizeDouble(AccountInfoDouble(ACCOUNT_PROFIT),2)+" | DD: "+ NormalizeDouble(drawdown,2) + "%");
ObjectSetString(0,"lblProfit",OBJPROP_FONT,"Arial Black");
ObjectSetInteger(0, "lblProfit", OBJPROP_COLOR, clrGreen);
ObjectSetInteger(0, "lblProfit", OBJPROP_FONTSIZE, 10);
}
void info() {
double Risk = FloatingLoss_Target;
Comment("\n"
);
}
int FXD_SELECTED_TYPE = 0;// Indicates what is selected by OrderSelect, 1 for trade, 2 for pending order, 3 for history trade
ulong FXD_SELECTED_TICKET = 0;// The ticket number selected by OrderSelect
int FXD_INDICATOR_COUNTED_MEMORY = 0;// Used as a memory for IndicatorCounted() function. It needs to be outside of the function, because when OnCalculate needs to be reset, this memory must be reset as well.
int Bars = Bars(_Symbol, PERIOD_CURRENT);
int Digits = _Digits;
double Point = _Point;
double Ask, Bid, Close[], High[], Low[], Open[];
long Volume[];
datetime Time[];
class ADBF
{
private:
/**
* _LastError is used to set custom errors that could be returned by the custom GetLastError method
* The initial value should be -1 and everything >= 0 should be valid error code
* When setting an error code in it, it should be the MQL5 value,
* because then in GetLastError it will be converted to MQL4 value
*/
static int _LastError;
public:
ADBF() {
};
static double AccountBalance() {
return ::AccountInfoDouble(ACCOUNT_BALANCE);
}
static double AccountEquity() {
return ::AccountInfoDouble(ACCOUNT_EQUITY);
}
static double AccountCompany() {
return ::AccountInfoString(ACCOUNT_COMPANY);
}
static double AccountName() {
return ::AccountInfoString(ACCOUNT_NAME);
}
static double AccountNumber() {
return ::AccountInfoInteger(ACCOUNT_LOGIN);
}
static double AccountCurrency() {
return ::AccountInfoString(ACCOUNT_CURRENCY);
}
static int OrdersTotal() {
return ::PositionsTotal() + ::OrdersTotal();
}
/**
* In MQL4's documentation errors are also shown as numeric values and sometimes people use these numbers, because they are shorter to write.
* This means that GetLastError shoud return such MQL4 numeric values instead of the MQL5 values.
* Supports custom error codes that can be set with ADBF -> _LastError
*/
static int GetLastError() {
int errorCode = 0;
if (ADBF::_LastError >= 0) {
errorCode = ADBF::_LastError;
ADBF::_LastError = -1;
}
else {
errorCode = ::GetLastError();
}
switch (errorCode) {
case ERR_SUCCESS : return 0; /* ERR_NO_ERROR */
case TRADE_RETCODE_INVALID : return 3; /* ERR_INVALID_TRADE_PARAMETERS */
case ERR_TRADE_SEND_FAILED : return 4; /* ERR_SERVER_BUSY */
case TRADE_RETCODE_CONNECTION : return 6; /* ERR_NO_CONNECTION */
case TRADE_RETCODE_REJECT : return 7; /* ERR_NOT_ENOUGH_RIGHTS */
case TRADE_RETCODE_ERROR : return 9; /* ERR_MALFUNCTIONAL_TRADE */
case TRADE_RETCODE_TIMEOUT : return 128; /* ERR_TRADE_TIMEOUT */
case TRADE_RETCODE_INVALID_PRICE : return 129; /* ERR_INVALID_PRICE */
case TRADE_RETCODE_INVALID_STOPS : return 130; /* ERR_INVALID_STOPS */
case TRADE_RETCODE_INVALID_VOLUME : return 131; /* ERR_INVALID_TRADE_VOLUME */
case TRADE_RETCODE_MARKET_CLOSED : return 132; /* ERR_MARKET_CLOSED */
case TRADE_RETCODE_TRADE_DISABLED : return 133; /* ERR_TRADE_DISABLED */
case TRADE_RETCODE_NO_MONEY : return 134; /* ERR_NOT_ENOUGH_MONEY */
case TRADE_RETCODE_PRICE_CHANGED : return 135; /* ERR_PRICE_CHANGED */
case TRADE_RETCODE_PRICE_OFF : return 136; /* ERR_OFF_QUOTES */
case TRADE_RETCODE_REQUOTE : return 138; /* ERR_REQUOTE */
case TRADE_RETCODE_LOCKED : return 139; /* ERR_ORDER_LOCKED */
case TRADE_RETCODE_TOO_MANY_REQUESTS : return 141; /* ERR_TOO_MANY_REQUESTS */
case TRADE_RETCODE_INVALID_EXPIRATION : return 147; /* ERR_TRADE_EXPIRATION_DENIED */
case TRADE_RETCODE_LIMIT_ORDERS : return 148; /* ERR_TRADE_TOO_MANY_ORDERS */
case 10046 : return 149; /* ERR_TRADE_HEDGE_PROHIBITED */
case TRADE_RETCODE_FIFO_CLOSE : return 150; /* ERR_TRADE_PROHIBITED_BY_FIFO */
case ERR_INVALID_POINTER_TYPE : return 4001; /* ERR_WRONG_FUNCTION_POINTER */
case ERR_SMALL_ARRAY : return 4002; /* ERR_ARRAY_INDEX_OUT_OF_RANGE */
case ERR_MATH_OVERFLOW : return 4004; /* ERR_RECURSIVE_STACK_OVERFLOW */
case ERR_STRING_OUT_OF_MEMORY : return 4006; /* ERR_NO_MEMORY_FOR_PARAM_STRING */
case ERR_NOTINITIALIZED_STRING : return 4008; /* ERR_NOT_INITIALIZED_STRING */
case ERR_STRING_TOO_BIGNUMBER : return 4011; /* ERR_TOO_LONG_STRING */
case ERR_ZEROSIZE_ARRAY : return 4016; /* ERR_NOT_INITIALIZED_ARRAY */
case ERR_INTERNAL_ERROR : return 4024; /* ERR_INTERNAL_ERROR */
case ERR_NOT_ENOUGH_MEMORY : return 4025; /* ERR_OUT_OF_MEMORY */
case ERR_INVALID_POINTER : return 4026; /* ERR_INVALID_POINTER */
case ERR_TOO_MANY_FORMATTERS : return 4027; /* ERR_FORMAT_TOO_MANY_FORMATTERS */
case ERR_TOO_MANY_PARAMETERS : return 4028; /* ERR_FORMAT_TOO_MANY_PARAMETERS */
case ERR_INVALID_ARRAY : return 4029; /* ERR_ARRAY_INVALID */
case ERR_CHART_NO_REPLY : return 4030; /* ERR_CHART_NOREPLY */
case ERR_WRONG_INTERNAL_PARAMETER : return 4052; /* ERR_STRING_FUNCTION_INTERNAL */
case ERR_SERIES_ARRAY : return 4054; /* ERR_INCORRECT_SERIESARRAY_USING */
case ERR_INCOMPATIBLE_ARRAYS : return 4056; /* ERR_INCOMPATIBLE_ARRAYS */
case ERR_GLOBALVARIABLE_EXISTS :
case ERR_GLOBALVARIABLE_NOT_MODIFIED :
case ERR_GLOBALVARIABLE_CANNOTREAD :
case ERR_GLOBALVARIABLE_CANNOTWRITE : return 4057; /* ERR_GLOBAL_VARIABLES_PROCESSING */
case ERR_GLOBALVARIABLE_NOT_FOUND : return 4058; /* ERR_GLOBAL_VARIABLE_NOT_FOUND */
case ERR_FUNCTION_NOT_ALLOWED : return 4060; /* ERR_FUNCTION_NOT_CONFIRMED */
case ERR_MAIL_SEND_FAILED : return 4061; /* ERR_SEND_MAIL_ERROR */
case ERR_RESOURCE_NOT_FOUND : return 4068; /* ERR_RESOURCE_NOT_FOUND */
case ERR_RESOURCE_NAME_DUPLICATED : return 4070; /* ERR_RESOURCE_DUPLICATED */
case ERR_INDICATOR_CANNOT_CREATE : return 4071; /* ERR_INDICATOR_CANNOT_INIT */
case ERR_INDICATOR_CANNOT_ADD :
case ERR_CHART_INDICATOR_CANNOT_ADD : return 4072; /* ERR_INDICATOR_CANNOT_LOAD */
case ERR_HISTORY_NOT_FOUND : return 4073; /* ERR_NO_HISTORY_DATA */
case ERR_HISTORY_LOAD_ERRORS : return 4074; /* ERR_NO_MEMORY_FOR_HISTORY */
case ERR_BUFFERS_NO_MEMORY : return 4075; /* ERR_NO_MEMORY_FOR_INDICATOR */
case ERR_FILE_ENDOFFILE : return 4099; /* ERR_END_OF_FILE */
case ERR_TRADE_POSITION_NOT_FOUND :
case ERR_TRADE_ORDER_NOT_FOUND :
case ERR_TRADE_DEAL_NOT_FOUND : return 4105; /* ERR_NO_ORDER_SELECTED */
case ERR_MARKET_UNKNOWN_SYMBOL :
case ERR_INDICATOR_UNKNOWN_SYMBOL : return 4106; /* ERR_UNKNOWN_SYMBOL */
case ERR_TRADE_DISABLED :
case TRADE_RETCODE_CLIENT_DISABLES_AT : return 4109; /* ERR_TRADE_NOT_ALLOWED */
case TRADE_RETCODE_SHORT_ONLY : return 4110; /* ERR_LONGS_NOT_ALLOWED */
case TRADE_RETCODE_LONG_ONLY : return 4111; /* ERR_SHORTS_NOT_ALLOWED */
case TRADE_RETCODE_SERVER_DISABLES_AT : return 4112; /* ERR_TRADE_EXPERT_DISABLED_BY_SERVER */
case ERR_OBJECT_WRONG_PROPERTY : return 4201; /* ERR_UNKNOWN_OBJECT_PROPERTY */
case ERR_OBJECT_NOT_FOUND : return 4202; /* ERR_OBJECT_DOES_NOT_EXIST */
case ERR_OBJECT_ERROR : return 4207; /* ERR_SOME_OBJECT_ERROR */
case ERR_CHART_WRONG_PROPERTY : return 4210; /* ERR_CHART_PROP_INVALID */
case ERR_CHART_NOT_FOUND : return 4211; /* ERR_CHART_NOT_FOUND */
case ERR_CHART_WINDOW_NOT_FOUND : return 4212; /* ERR_CHARTWINDOW_NOT_FOUND */
case ERR_CHART_INDICATOR_NOT_FOUND : return 4213; /* ERR_CHARTINDICATOR_NOT_FOUND */
case ERR_MARKET_NOT_SELECTED : return 4220; /* ERR_SYMBOL_SELECT */
case ERR_NOTIFICATION_SEND_FAILED : return 4250; /* ERR_NOTIFICATION_ERROR */
case ERR_NOTIFICATION_WRONG_PARAMETER : return 4251; /* ERR_NOTIFICATION_PARAMETER */
case ERR_NOTIFICATION_WRONG_SETTINGS : return 4252; /* ERR_NOTIFICATION_SETTINGS */
case ERR_NOTIFICATION_TOO_FREQUENT : return 4253; /* ERR_NOTIFICATION_TOO_FREQUENT */
case ERR_FTP_NOSERVER : return 4260; /* ERR_FTP_NOSERVER */
case ERR_FTP_NOLOGIN : return 4261; /* ERR_FTP_NOLOGIN */
case ERR_FTP_CONNECT_FAILED : return 4262; /* ERR_FTP_CONNECT_FAILED */
case 4524 : return 4263; /* ERR_FTP_CLOSED */
case ERR_FTP_CHANGEDIR : return 4264; /* ERR_FTP_CHANGEDIR */
case ERR_FTP_FILE_ERROR : return 4265; /* ERR_FTP_FILE_ERROR */
case ERR_FTP_SEND_FAILED : return 4266; /* ERR_FTP_ERROR */
case ERR_TOO_MANY_FILES : return 5001; /* ERR_FILE_TOO_MANY_OPENED */
case ERR_WRONG_FILENAME : return 5002; /* ERR_FILE_WRONG_FILENAME */
case ERR_TOO_LONG_FILENAME : return 5003; /* ERR_FILE_TOO_LONG_FILENAME */
case ERR_CANNOT_OPEN_FILE : return 5004; /* ERR_FILE_CANNOT_OPEN */
case ERR_FILE_CACHEBUFFER_ERROR : return 5005; /* ERR_FILE_BUFFER_ALLOCATION_ERROR */
case ERR_CANNOT_DELETE_FILE : return 5006; /* ERR_FILE_CANNOT_DELETE */
case ERR_INVALID_FILEHANDLE : return 5007; /* ERR_FILE_INVALID_HANDLE */
case ERR_WRONG_FILEHANDLE : return 5008; /* ERR_FILE_WRONG_HANDLE */
case ERR_FILE_NOTTOWRITE : return 5009; /* ERR_FILE_NOT_TOWRITE */
case ERR_FILE_NOTTOREAD : return 5010; /* ERR_FILE_NOT_TOREAD */
case ERR_FILE_NOTBIN : return 5011; /* ERR_FILE_NOT_BIN */
case ERR_FILE_NOTTXT : return 5012; /* ERR_FILE_NOT_TXT */
case ERR_FILE_NOTTXTORCSV : return 5013; /* ERR_FILE_NOT_TXTORCSV */
case ERR_FILE_NOTCSV : return 5014; /* ERR_FILE_NOT_CSV */
case ERR_FILE_READERROR : return 5015; /* ERR_FILE_READ_ERROR */
case ERR_FILE_WRITEERROR : return 5016; /* ERR_FILE_WRITE_ERROR */
case ERR_FILE_BINSTRINGSIZE : return 5017; /* ERR_FILE_BIN_STRINGSIZE */
case ERR_INCOMPATIBLE_FILE : return 5018; /* ERR_FILE_INCOMPATIBLE */
case ERR_FILE_IS_DIRECTORY : return 5019; /* ERR_FILE_IS_DIRECTORY */
case ERR_FILE_NOT_EXIST : return 5020; /* ERR_FILE_NOT_EXIST */
case ERR_FILE_CANNOT_REWRITE : return 5021; /* ERR_FILE_CANNOT_REWRITE */
case ERR_WRONG_DIRECTORYNAME : return 5022; /* ERR_FILE_WRONG_DIRECTORYNAME */
case ERR_DIRECTORY_NOT_EXIST : return 5023; /* ERR_FILE_DIRECTORY_NOT_EXIST */
case ERR_FILE_ISNOT_DIRECTORY : return 5024; /* ERR_FILE_NOT_DIRECTORY */
case ERR_CANNOT_DELETE_DIRECTORY : return 5025; /* ERR_FILE_CANNOT_DELETE_DIRECTORY */
case ERR_CANNOT_CLEAN_DIRECTORY : return 5026; /* ERR_FILE_CANNOT_CLEAN_DIRECTORY */
case ERR_ARRAY_RESIZE_ERROR : return 5027; /* ERR_FILE_ARRAYRESIZE_ERROR */
case ERR_STRING_RESIZE_ERROR : return 5028; /* ERR_FILE_STRINGRESIZE_ERROR */
case ERR_STRUCT_WITHOBJECTS_ORCLASS : return 5029; /* ERR_FILE_STRUCT_WITH_OBJECTS */
case ERR_WEBREQUEST_INVALID_ADDRESS : return 5200; /* ERR_WEBREQUEST_INVALID_ADDRESS */
case ERR_WEBREQUEST_CONNECT_FAILED : return 5201; /* ERR_WEBREQUEST_CONNECT_FAILED */
case ERR_WEBREQUEST_TIMEOUT : return 5202; /* ERR_WEBREQUEST_TIMEOUT */
case ERR_WEBREQUEST_REQUEST_FAILED : return 5203; /* ERR_WEBREQUEST_REQUEST_FAILED */
case ERR_USER_ERROR_FIRST : return 65536; /* ERR_USER_ERROR_FIRST */
default : return 2; /* ERR_COMMON_ERROR */
}
}
static double MarketInfo(string symbol, int type) {
if (symbol == NULL) symbol = ::Symbol();
switch(type) {
case 1 /* MODE_LOW */ : return ::SymbolInfoDouble(symbol, SYMBOL_LASTLOW);
case 2 /* MODE_HIGH */ : return ::SymbolInfoDouble(symbol, SYMBOL_LASTHIGH);
case 5 /* MODE_TIME */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_TIME);
case 9 /* MODE_BID */ : return ::SymbolInfoDouble(symbol, SYMBOL_BID);
case 10 /* MODE_ASK */ : return ::SymbolInfoDouble(symbol, SYMBOL_ASK);
case 11 /* MODE_POINT */ : return ::SymbolInfoDouble(symbol, SYMBOL_POINT);
case 12 /* MODE_DIGITS */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_DIGITS);
case 13 /* MODE_SPREAD */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_SPREAD);
case 14 /* MODE_STOPLEVEL */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
case 15 /* MODE_LOTSIZE */ : return ::SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE);
case 16 /* MODE_TICKVALUE */ : return ::SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
case 17 /* MODE_TICKSIZE */ : return ::SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
case 18 /* MODE_SWAPLONG */ : return ::SymbolInfoDouble(symbol, SYMBOL_SWAP_LONG);
case 19 /* MODE_SWAPSHORT */ : return ::SymbolInfoDouble(symbol, SYMBOL_SWAP_SHORT);
case 20 /* MODE_STARTING */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_START_TIME);
case 21 /* MODE_EXPIRATION */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_EXPIRATION_TIME);
case 22 /* MODE_TRADEALLOWED */ : return (::SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE) != SYMBOL_TRADE_MODE_DISABLED);
case 23 /* MODE_MINLOT */ : return ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
case 24 /* MODE_LOTSTEP */ : return ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
case 25 /* MODE_MAXLOT */ : return ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
case 26 /* MODE_SWAPTYPE */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_SWAP_MODE);
case 27 /* MODE_PROFITCALCMODE */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_TRADE_CALC_MODE);
case 28 /* MODE_MARGINCALCMODE */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_TRADE_CALC_MODE);
case 29 /* MODE_MARGININIT */ : return (double)::SymbolInfoDouble(symbol, SYMBOL_MARGIN_INITIAL);
case 30 /* MODE_MARGINMAINTENANCE */ : return (double)::SymbolInfoDouble(symbol, SYMBOL_MARGIN_MAINTENANCE);
case 31 /* MODE_MARGINHEDGED */ : return (double)::SymbolInfoDouble(symbol, SYMBOL_MARGIN_HEDGED);
case 32 /* MODE_MARGINREQUIRED */ : {
double margin = 0.0;
if (::OrderCalcMargin(ORDER_TYPE_BUY, symbol, 1, ::SymbolInfoDouble(symbol, SYMBOL_ASK), margin))
return margin;
else
return 0.0;
}
case 33 /* MODE_FREEZELEVEL */ : return (double)::SymbolInfoInteger(symbol, SYMBOL_TRADE_FREEZE_LEVEL);
case 34 /* MODE_CLOSEBY_ALLOWED */ : return 0.0;
}
return 0.0;
}
static bool OrderClose(long ticket, double lots, double price, int slippage, color arrow_color = clrNONE) {
int positionsTotal = ::PositionsTotal();
bool found = false;
long positionID = ticket;
for (int index = positionsTotal-1; index >= 0; index--) {
ticket = (long)::PositionGetTicket(index);
if (::PositionGetInteger(POSITION_IDENTIFIER) == positionID) {
found = true;
break;
}
}
/*
if (!found) {
if (::HistoryDealSelect(ticket)) {
long posID = ::HistoryDealGetInteger(ticket, DEAL_POSITION_ID);
for (int index = positionsTotal-1; index >= 0; index--) {
ticket = (long)::PositionGetTicket(index);
if (::PositionGetInteger(POSITION_IDENTIFIER) == posID) {
found = true;
break;
}
}
}
}
*/
if (!found) return false;
double lots0 = ::NormalizeDouble(PositionGetDouble(POSITION_VOLUME), 5);
string symbol = ::PositionGetString(POSITION_SYMBOL);
double lotstep = ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
while (true) {
lots = ::MathFloor(lots/lotstep)*lotstep;
MqlTradeRequest request;
MqlTradeResult result;
::ZeroMemory(request);
::ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.price = price;
request.type = (::PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY ;
request.position = ::PositionGetInteger(POSITION_TICKET);
request.symbol = symbol;
request.volume = lots;
request.magic = ::PositionGetInteger(POSITION_MAGIC);
request.deviation = (ulong)slippage;
request.comment = "from #" + ::IntegerToString(ticket);
if (ADBF_TRADES::IsFillingTypeAllowed(symbol, SYMBOL_FILLING_FOK))
request.type_filling = ORDER_FILLING_FOK;
else if (ADBF_TRADES::IsFillingTypeAllowed(symbol, SYMBOL_FILLING_IOC))
request.type_filling = ORDER_FILLING_IOC;
else if (ADBF_TRADES::IsFillingTypeAllowed(symbol, ORDER_FILLING_RETURN)) // just in case
request.type_filling = ORDER_FILLING_RETURN;
int success = ::OrderSend(request, result);
if (!success || (result.retcode!=TRADE_RETCODE_DONE && result.retcode!=TRADE_RETCODE_PLACED && result.retcode!=TRADE_RETCODE_DONE_PARTIAL)) {
string errmsgpfx = "Closing trade error";
int erraction = ADBF_TRADES::CheckForTradingError(result.retcode, errmsgpfx);
switch (erraction) {
case 0: break; // no error
case 1: continue; // overcomable error
case 2: break; // fatal error
}
return false;
}
if (result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED || result.retcode == TRADE_RETCODE_DONE_PARTIAL) {
if (lots0 == ::NormalizeDouble(result.volume, 5)) {
while (true) {
if (!::PositionSelectByTicket(ticket)) {
break;
}
::Sleep(10);
}
}
else if (lots0 > ::NormalizeDouble(result.volume, 5)) {
while (true) {
if (::PositionSelectByTicket(ticket) && (lots0 != ::NormalizeDouble(PositionGetDouble(POSITION_VOLUME), 5))) {
break;
}
::Sleep(10);
}
}
}
break;
}
::ResetLastError();
return true;
}
static double OrderLots() {
if (ADBF_TRADES::LoadedType() == 1) return ::PositionGetDouble(POSITION_VOLUME);
if (ADBF_TRADES::LoadedType() == 2) return ::OrderGetDouble(ORDER_VOLUME_CURRENT);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = total -1; index >= 0; index--) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_OUT) {
return ::HistoryDealGetDouble(ticket, DEAL_VOLUME);
}
}
}
if (ADBF_TRADES::LoadedType() == 4) return ::HistoryOrderGetDouble(ADBF::OrderTicket(), ORDER_VOLUME_CURRENT);
return 0.0;
}
static long OrderMagicNumber() {
if (ADBF_TRADES::LoadedType() == 1) return (long)::PositionGetInteger(POSITION_MAGIC);
if (ADBF_TRADES::LoadedType() == 2) return (long)::OrderGetInteger(ORDER_MAGIC);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = total -1; index >= 0; index--) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_OUT) {
return (long)::HistoryDealGetInteger(ticket, DEAL_MAGIC);
}
}
}
if (ADBF_TRADES::LoadedType() == 4) return (long)::HistoryOrderGetInteger(ADBF::OrderTicket(), ORDER_MAGIC);
return 0;
}
static bool OrderModify(long ticket, double price, double sl, double tp, datetime expiration, color arrow_color = clrNONE) {
bool isTrade = true;
string symbol = "";
long magic = 0;
if (::PositionSelectByTicket(ticket)) {
symbol = ::PositionGetString(POSITION_SYMBOL);
}
else if (::OrderSelect(ticket)) {
isTrade = false;
symbol = ::OrderGetString(ORDER_SYMBOL);
}
else {
return false;
}
::ResetLastError();
int digits = (int)::SymbolInfoInteger(symbol, SYMBOL_DIGITS);
sl = ::NormalizeDouble(sl, digits);
tp = ::NormalizeDouble(tp, digits);
price = ::NormalizeDouble(price, digits);
while (true) {
MqlTradeRequest request;
MqlTradeResult result;
::ZeroMemory(request);
::ZeroMemory(result);
if (isTrade) {
if (
sl == ::NormalizeDouble(PositionGetDouble(POSITION_SL), digits)
&& tp == ::NormalizeDouble(PositionGetDouble(POSITION_TP), digits)
) {
return true;
}
request.action = TRADE_ACTION_SLTP;
request.symbol = symbol;
request.position = ::PositionGetInteger(POSITION_TICKET);
request.magic = ::PositionGetInteger(POSITION_MAGIC);
request.comment = ::PositionGetString(POSITION_COMMENT);
}
else {
if (
price == ::NormalizeDouble(OrderGetDouble(ORDER_PRICE_OPEN), digits)
&& sl == ::NormalizeDouble(OrderGetDouble(ORDER_SL), digits)
&& tp == ::NormalizeDouble(OrderGetDouble(ORDER_TP), digits)
&& expiration == ::OrderGetInteger(ORDER_TIME_EXPIRATION)
) {
return true;
}
request.action = TRADE_ACTION_MODIFY;
request.order = ::OrderGetInteger(ORDER_TICKET);
request.price = price;
request.volume = ::OrderGetDouble(ORDER_VOLUME_CURRENT);
request.magic = ::OrderGetInteger(ORDER_MAGIC);
request.type_time = ORDER_TIME_SPECIFIED;
request.expiration = expiration;
request.comment = ::OrderGetString(ORDER_COMMENT);
uint filling=(uint)::SymbolInfoInteger(request.symbol,SYMBOL_FILLING_MODE);
if (filling==SYMBOL_FILLING_FOK) {
request.type_filling=ORDER_FILLING_FOK;
}
else if (filling==SYMBOL_FILLING_IOC) {
request.type_filling=ORDER_FILLING_IOC;
}
}
request.sl = sl;
request.tp = tp;
int success = ::OrderSend(request, result);
if (!success || (result.retcode!=TRADE_RETCODE_DONE && result.retcode!=TRADE_RETCODE_PLACED && result.retcode!=TRADE_RETCODE_DONE_PARTIAL)) {
string errmsgpfx = "Modify error";
int erraction = ADBF_TRADES::CheckForTradingError(result.retcode, errmsgpfx);
switch (erraction) {
case 0: break; // no error
case 1: continue; // overcomable error
case 2: break; // fatal error
}
return false;
}
if (result.retcode==TRADE_RETCODE_DONE || result.retcode==TRADE_RETCODE_PLACED || result.retcode==TRADE_RETCODE_DONE_PARTIAL) {
int w;
for (w = 0; w < 5000; w++) {
double actualSl = ::NormalizeDouble(OrderStopLoss(), digits);
double actualTp = ::NormalizeDouble(OrderTakeProfit(), digits);
if (
((ADBF_TRADES::LoadedType() == 1 && ::PositionSelectByTicket(ticket)) || ::OrderSelect(ticket))
&& (sl == actualSl && tp == actualTp)
) {
break;
}
::Sleep(1);
}
if (w == 5000) {
::Print("Check error: Modify order stops");
return false;
}
}
break;
}
::ResetLastError();
return true;
}
static double OrderOpenPrice() {
if (ADBF_TRADES::LoadedType() == 1) return ::PositionGetDouble(POSITION_PRICE_OPEN);
if (ADBF_TRADES::LoadedType() == 2) return ::OrderGetDouble(ORDER_PRICE_OPEN);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = 0; index < total; index++) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_IN) {
return ::HistoryDealGetDouble(ticket, DEAL_PRICE);
}
}
}
if (ADBF_TRADES::LoadedType() == 4) return ::HistoryOrderGetDouble(ADBF::OrderTicket(), ORDER_PRICE_OPEN);
return 0.0;
}
static double OrderProfit() {
if (ADBF_TRADES::LoadedType() == 1) return ::PositionGetDouble(POSITION_PROFIT);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = total -1; index >= 0; index--) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_OUT) {
return ::HistoryDealGetDouble(ticket, DEAL_PROFIT);
}
}
}
return 0.0;
}
static bool OrderSelect(long index, int select, int pool = 0) {
if (pool < 0 || pool > 1) pool = 0;
if (select != 0) select = 1;
bool selected = false;
int loadedTypeTrade = 1;
int loadedTypeOrder = 2;
ADBF::OrderTicket(0);
ADBF_TRADES::LoadedType(0);
if (select == 0) {
int totalTrades = 0;
int totalOrders = 0;
if (pool == 1) {
::HistorySelect(0, ::TimeCurrent() + 1);
totalTrades = ::HistoryDealsTotal();
totalOrders = ::HistoryOrdersTotal();
loadedTypeTrade = 3;
loadedTypeOrder = 4;
}
else {
totalTrades = ::PositionsTotal();
totalOrders = ::OrdersTotal();
loadedTypeTrade = 1;
loadedTypeOrder = 2;
}
if (totalTrades == 0 && totalOrders == 0) {
ADBF::_LastError_(ERR_INVALID_PARAMETER);
}
else {
int total = ::MathMax(totalTrades, totalOrders);
int tradeIndex = 0;
int orderIndex = 0;
int iterationIndex = 0;
while (true) {
ulong tradeTicket = 0;
ulong orderTicket = 0;
if (tradeIndex < totalTrades) {
if (pool == 1) {
tradeTicket = ::HistoryDealGetTicket(tradeIndex);
if (
(tradeTicket == 0) // something is wrong
|| (::HistoryDealGetInteger(tradeTicket, DEAL_ENTRY) != DEAL_ENTRY_OUT) // not that kind of a deal
) {
tradeIndex++;
continue;
}
if (tradeTicket > 0) {
tradeTicket = ::HistoryDealGetInteger(tradeTicket, DEAL_POSITION_ID);
}
}
else {
tradeTicket = ::PositionGetTicket(tradeIndex);
}
}
if (orderIndex < totalOrders) {
if (pool == 1) {
orderTicket = ::HistoryOrderGetTicket(orderIndex);
ENUM_ORDER_STATE state = (ENUM_ORDER_STATE)::HistoryOrderGetInteger(orderTicket, ORDER_STATE);
if (
(orderTicket == 0) // something is wrong
|| (state != ORDER_STATE_CANCELED && state != ORDER_STATE_EXPIRED) // not that kind of state
) {
orderIndex++;
continue;
}
}
else {
orderTicket = ::OrderGetTicket(orderIndex);
}
}
iterationIndex++;
if (tradeTicket == 0 && orderTicket == 0) {
break;
}
else if (tradeTicket > 0 && orderTicket == 0) {
tradeIndex++;
if (iterationIndex > index) {
ADBF::OrderTicket(tradeTicket);
ADBF_TRADES::LoadedType(loadedTypeTrade);
selected = true;
break;
}
}
else if (tradeTicket == 0 && orderTicket > 0) {
orderIndex++;
if (iterationIndex > index) {
ADBF::OrderTicket(orderTicket);
ADBF_TRADES::LoadedType(loadedTypeOrder);
selected = true;
break;
}
}
else if (tradeTicket <= orderTicket) {
tradeIndex++;
if (iterationIndex > index) {
ADBF::OrderTicket(tradeTicket);
ADBF_TRADES::LoadedType(loadedTypeTrade);
selected = true;
break;
}
}
else if (tradeTicket > orderTicket) {
orderIndex++;
if (iterationIndex > index) {
ADBF::OrderTicket(orderTicket);
ADBF_TRADES::LoadedType(loadedTypeOrder);
selected = true;
break;
}
}
}
}
}
else {
long ticket = index;
if (::PositionSelectByTicket(ticket)) {
ADBF::OrderTicket(::PositionGetInteger(POSITION_IDENTIFIER));
ADBF_TRADES::LoadedType(1);
selected = true;
}
else if (::OrderSelect(ticket)) {
ADBF::OrderTicket(ticket);
ADBF_TRADES::LoadedType(2);
selected = true;
}
else {
::HistorySelect(0, ::TimeCurrent() + 1);
long posID = ::HistoryDealGetInteger(ticket, DEAL_POSITION_ID);
if (posID) {
ADBF::OrderTicket(posID);
ADBF_TRADES::LoadedType(3);
selected = true;
}
if (selected == false) {
long orderTicket = ::HistoryOrderGetInteger(ticket, ORDER_TICKET);
if (orderTicket) {
ADBF::OrderTicket(ticket);
ADBF_TRADES::LoadedType(4);
selected = true;
}
}
}
}
if (selected) ::ResetLastError();
return selected;
}
static int OrderSend(
string symbol, // symbol
int cmd, // operation
double volume, // volume
double price, // price
int slippage, // slippage
double sl, // stop loss
double tp, // take profit
string comment=NULL, // comment
long magic=0, // magic number
datetime expiration=0, // pending order expiration
color arrow_color=clrNONE // color
) {
int type = cmd;
ulong ticket = -1;
bool successed = false;
bool isPendingOrder = (cmd > 1);
ENUM_ORDER_TYPE_TIME type_time = ORDER_TIME_GTC;
symbol = (symbol == NULL || symbol == "") ? ::Symbol() : symbol;
if (isPendingOrder) {
if (expiration <= 0) {
expiration = 0;
if (ADBF_TRADES::IsExpirationTypeAllowed(symbol, SYMBOL_EXPIRATION_GTC))
type_time = ORDER_TIME_GTC;
else
type_time = ORDER_TIME_DAY;
}
else {
type_time = ORDER_TIME_SPECIFIED;
}
}
else {
expiration = 0;
}
bool closing = false;
double lots0 = 0;
long type0 = type;
if (
(::AccountInfoInteger(ACCOUNT_MARGIN_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_NETTING)
&& (type == POSITION_TYPE_BUY || type == POSITION_TYPE_SELL)
) {
if (::PositionSelect(symbol)) {
if ((int)::PositionGetInteger(POSITION_TYPE) != type) {
closing = true;
}
lots0 = ::NormalizeDouble(PositionGetDouble(POSITION_VOLUME), 5);
type0 = ::PositionGetInteger(POSITION_TYPE);
}
}
while (true) {
int digits = (int)::SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double ask = ::SymbolInfoDouble(symbol, SYMBOL_ASK);
double bid = ::SymbolInfoDouble(symbol, SYMBOL_BID);
double lotstep = ::SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
sl = ::NormalizeDouble(sl, digits);
tp = ::NormalizeDouble(tp, digits);
price = ::NormalizeDouble(price, digits);
volume = ::MathFloor(volume/lotstep) * lotstep; // MQL4's OrderSend rounds to floor
if (isPendingOrder) {
if (
(type == ORDER_TYPE_BUY_LIMIT && price >= ask)
|| (type == ORDER_TYPE_SELL_LIMIT && price <= bid)
|| (type == ORDER_TYPE_BUY_STOP && price <= ask)
|| (type == ORDER_TYPE_SELL_STOP && price >= bid)
) {
ADBF::_LastError_(TRADE_RETCODE_INVALID_STOPS);
return -1;
}
}
if (
((type == POSITION_TYPE_BUY || type == ORDER_TYPE_BUY_LIMIT || type == ORDER_TYPE_BUY_STOP) && ((sl > 0 && sl >= price) || (tp > 0 && tp <= price)))
|| ((type == POSITION_TYPE_SELL || type == ORDER_TYPE_SELL_LIMIT || type == ORDER_TYPE_SELL_STOP) && ((sl > 0 && sl <= price) || (tp > 0 && tp >= price)))
) {
ADBF::_LastError_(TRADE_RETCODE_INVALID_STOPS);
return -1;
}
MqlTradeRequest request;
MqlTradeResult result;
MqlTradeCheckResult check_result;
::ZeroMemory(request);
::ZeroMemory(result);
::ZeroMemory(check_result);
request.action = (type < 2) ? TRADE_ACTION_DEAL : TRADE_ACTION_PENDING;
request.symbol = symbol;
request.volume = volume;
request.type = (ENUM_ORDER_TYPE)type;
request.price = price;
request.deviation = slippage;
request.sl = sl;
request.tp = tp;
request.comment = comment;
request.magic = magic;
request.type_time = type_time;
request.expiration = expiration;
if (isPendingOrder) {
if (ADBF_TRADES::IsFillingTypeAllowed(symbol, ORDER_FILLING_RETURN))
request.type_filling = ORDER_FILLING_RETURN;
else if (ADBF_TRADES::IsFillingTypeAllowed(symbol, ORDER_FILLING_FOK))
request.type_filling = ORDER_FILLING_FOK;
else if (ADBF_TRADES::IsFillingTypeAllowed(symbol, ORDER_FILLING_IOC))
request.type_filling = ORDER_FILLING_IOC;
}
else {
if (ADBF_TRADES::IsFillingTypeAllowed(symbol, SYMBOL_FILLING_FOK))
request.type_filling = ORDER_FILLING_FOK;
else if (ADBF_TRADES::IsFillingTypeAllowed(symbol, SYMBOL_FILLING_IOC))
request.type_filling = ORDER_FILLING_IOC;
else if (ADBF_TRADES::IsFillingTypeAllowed(symbol, ORDER_FILLING_RETURN)) // just in case
request.type_filling = ORDER_FILLING_RETURN;
}
bool success = ::OrderSend(request, result);
if (successed == true) {
::Print("The program will be removed because of suspicious attempt to create new positions");
::ExpertRemove();
::Sleep(10000);
break;
}
if (success) {
successed = true;
}
if (
success == false
|| (
result.retcode != TRADE_RETCODE_DONE
&& result.retcode != TRADE_RETCODE_PLACED
&& result.retcode != TRADE_RETCODE_DONE_PARTIAL
)
) {
string errmsgpfx = (type > ORDER_TYPE_SELL) ? "New pending order error" : "New position error";
int erraction = ADBF_TRADES::CheckForTradingError(result.retcode, errmsgpfx);
switch (erraction) {
case 0: break; // no error
case 1: continue; // overcomable error
case 2: break; // fatal error
}
ADBF::_LastError_(result.retcode);
return -1;
}
if (
result.retcode==TRADE_RETCODE_DONE
|| result.retcode==TRADE_RETCODE_PLACED
|| result.retcode==TRADE_RETCODE_DONE_PARTIAL
) {
ticket = result.order;
if (type <= ORDER_TYPE_SELL) {
if (::AccountInfoInteger(ACCOUNT_MARGIN_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_NETTING) {
if (closing == false) {
while (true) {
if (::PositionSelect(symbol) && (lots0 != ::NormalizeDouble(PositionGetDouble(POSITION_VOLUME), 5))) {
break;
}
Sleep(10);
}
}
else {
if (lots0 == ::NormalizeDouble(result.volume, 5)) {
while (true) {
if (!::PositionSelect(symbol)) {break;}
::Sleep(10);
}
}
else if (lots0 > ::NormalizeDouble(result.volume, 5)) {
while (true) {
if (::PositionSelect(symbol) && (lots0 != ::NormalizeDouble(PositionGetDouble(POSITION_VOLUME), 5))) {
break;
}
::Sleep(10);
}
}
else if (lots0 < ::NormalizeDouble(result.volume, 5)) {
while (true) {
if (::PositionSelect(symbol) && (type0 != ::PositionGetInteger(POSITION_TYPE))) {
break;
}
::Sleep(10);
}
}
}
}
else if (::AccountInfoInteger(ACCOUNT_MARGIN_MODE) == ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) {
if (closing == false) {
while (true) {
if (::PositionSelectByTicket(ticket)) {
break;
}
::Sleep(10);
}
}
}
}
else {
while (true) {
if (ADBF_TRADES::LoadPendingOrder(result.order)) {
break;
}
::Sleep(10);
}
}
}
break;
}
if (ticket > 0) {
int loadedType = (isPendingOrder) ? 2 : 1; // 1 for trade, 2 for pending order
ADBF::OrderTicket(ticket);
ADBF_TRADES::LoadedType(loadedType);
::ResetLastError();
}
return (int)ticket;
}
static double OrderStopLoss() {
if (ADBF_TRADES::LoadedType() == 1) return ::PositionGetDouble(POSITION_SL);
if (ADBF_TRADES::LoadedType() == 2) return ::OrderGetDouble(ORDER_SL);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = total -1; index >= 0; index--) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_IN) {
ulong orderTicket = ::HistoryDealGetInteger(ticket, DEAL_ORDER);
return ::HistoryOrderGetDouble(orderTicket, ORDER_SL);
}
}
}
if (ADBF_TRADES::LoadedType() == 4) return ::HistoryOrderGetDouble(ADBF::OrderTicket(), ORDER_SL);
return 0.0;
}
static string OrderSymbol() {
if (ADBF_TRADES::LoadedType() == 1) return ::PositionGetString(POSITION_SYMBOL);
if (ADBF_TRADES::LoadedType() == 2) return ::OrderGetString(ORDER_SYMBOL);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = 0; index < total; index++) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_IN) {
return ::HistoryDealGetString(ticket, DEAL_SYMBOL);
}
}
}
if (ADBF_TRADES::LoadedType() == 4) return ::HistoryOrderGetString(ADBF::OrderTicket(), ORDER_SYMBOL);
return _Symbol;
}
static double OrderTakeProfit() {
if (ADBF_TRADES::LoadedType() == 1) return ::PositionGetDouble(POSITION_TP);
if (ADBF_TRADES::LoadedType() == 2) return ::OrderGetDouble(ORDER_TP);
if (ADBF_TRADES::LoadedType() == 3) {
::HistorySelectByPosition(ADBF::OrderTicket());
int total = ::HistoryDealsTotal();
for (int index = total -1; index >= 0; index--) {
ulong ticket = ::HistoryDealGetTicket(index);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)::HistoryDealGetInteger(ticket, DEAL_ENTRY);
if (entry == DEAL_ENTRY_IN) {
ulong orderTicket = ::HistoryDealGetInteger(ticket, DEAL_ORDER);
return ::HistoryOrderGetDouble(orderTicket, ORDER_TP);
}
}
}
if (ADBF_TRADES::LoadedType() == 4) return ::HistoryOrderGetDouble(ADBF::OrderTicket(), ORDER_TP);
return 0.0;
}
static int OrderTicket(long ticket = 0) {
static int memory = 0;
if (ticket > 0) {
memory = (int)ticket;
}
return memory;
}
static int OrderType() {
if (ADBF_TRADES::LoadedType() == 1) return (int)::PositionGetInteger(POSITION_TYPE);
if (ADBF_TRADES::LoadedType() == 2) return (int)::OrderGetInteger(ORDER_TYPE);
if (ADBF_TRADES::LoadedType() == 3) return (int)::HistoryDealGetInteger(ADBF::OrderTicket(), DEAL_TYPE);
if (ADBF_TRADES::LoadedType() == 4) return (int)::HistoryOrderGetInteger(ADBF::OrderTicket(), ORDER_TYPE);
return 0; // MQL4 returns 0 if there is nothing loaded
}
static int OrdersTotals() {
return ::PositionsTotal() + ::OrdersTotal();
}
/**
* Refresh the data in the predefined variables and series arrays
* In MQL5 this function should run on every tick or calculate
*
* Note that when Symbol or Timeframe is changed,
* the global arrays (Ask, Bid...) are reset to size 0,
* and also the static variables are reset to initial values.
*/
static bool RefreshRates() {
static bool initialized = false;
static double prevAsk = 0.0;
static double prevBid = 0.0;
static int prevBars = 0;
static MqlRates ratesArray[1];
bool isDataUpdated = false;
if (initialized == false) {
::ArraySetAsSeries(::Close, true);
::ArraySetAsSeries(::High, true);
::ArraySetAsSeries(::Low, true);
::ArraySetAsSeries(::Open, true);
::ArraySetAsSeries(::Volume, true);
initialized = true;
}
::Bars = ::Bars(::_Symbol, PERIOD_CURRENT);
::Ask = ::SymbolInfoDouble(::_Symbol, SYMBOL_ASK);
::Bid = ::SymbolInfoDouble(::_Symbol, SYMBOL_BID);
if ((::Bars > 0) && (::Bars > prevBars)) {
::ArrayResize(::Time, ::Bars);
::ArrayResize(::Open, ::Bars);
::ArrayResize(::High, ::Bars);
::ArrayResize(::Low, ::Bars);
::ArrayResize(::Close, ::Bars);
::ArrayResize(::Volume, ::Bars);
for (int i = prevBars; i < ::Bars; i++) {
int success = ::CopyRates(::_Symbol, PERIOD_CURRENT, i, 1, ratesArray);
if (success == 1) {
::Time[i] = ratesArray[0].time;
::Open[i] = ratesArray[0].open;
::High[i] = ratesArray[0].high;
::Low[i] = ratesArray[0].low;
::Close[i] = ratesArray[0].close;
::Volume[i] = ratesArray[0].tick_volume;
}
}
}
else {
int success = ::CopyRates(::_Symbol, PERIOD_CURRENT, 0, 1, ratesArray);
if (success == 1) {
::Time[0] = ratesArray[0].time;
::Open[0] = ratesArray[0].open;
::High[0] = ratesArray[0].high;
::Low[0] = ratesArray[0].low;
::Close[0] = ratesArray[0].close;
::Volume[0] = ratesArray[0].tick_volume;
}
}
if (::Bars != prevBars || ::Ask != prevAsk || ::Bid != prevBid) {
Показано первые 50% кода (символов: 81720)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.