Субботник по наполнению FAQ (часто встречающиеся вопросы). Поможем товарищам! - страница 13

 
В чем отличие Instant Executuion и Market Execution?

(Integer): При Instant Executuion ордер можно открыть с заранее установленным стоплосс и тейпрофит, задать допустимое отклонение (Slippage) в пунктах, при котором допускается открытие ордера при отклонении цены на момент его исполнения брокером от цены запроса трейдера. При Market Execution невозможно открыть ордер с заранее установленным стоплосс и/или тейкпрофит, отсутствует параметр допустимого проскальзывания (Slippage). Ордер открывается по любой цене имеющейся на момент исполнения ордера брокером. Стоплосс и/или тейкпрофит можно установить ордеру сразу после его открытия. Большинство дилинговых центров работает в режиме Instant Executuion. В режиме Market Execution работает не так много дилинговых центров.
 
Всё больше и больше ДЦ переходят на Market Execution. Скоро информация, данная Integer станет неактуальной.
 
joo:
Всё больше и больше ДЦ переходят на Market Execution. Скоро информация, данная Integer станет неактуальной.

это ж просто информация про два режима.

а в FAQ последний абзац именно так и написал - тенденция! https://www.mql5.com/ru/forum/131853/page3#464977

-------

кстати, как там словарь терминов, пациент скорее жив?

Файлы:
mql4_10.zip  419 kb
 
sergeev:

1. а в FAQ последний абзац именно так и написал - тенденция! https://www.mql5.com/ru/forum/131853/page3#464977

-------

2. кстати, как там словарь терминов, пациент скорее жив?

1. Не видел последний абзац в FAQ по ссылке, а среагировал только на пост granit77.

2. Я ознакомился с разделом, по которому сам предложил свою помощь. Но он настолько полон, насколько можно пожелать. Добавлять практически нечего. Мне следовало бы уже сообщить об этом раньше - сожалею, что не сделал этого.

Все таки, в разделе можно добавить жаргонные сокращения терминов, которые в ходу у программистов и трейдеров. Я недавно устроился на новую работу и свободного времени стало очень мало, едва хватает, что бы хоть как то продолжать собственный проект. Поэтому буду потихоньку записывать "на листочек", когда накопится побольше - добавим в раздел. ОК?

 
joo:

ок
 

Вопрос: Получение массива тикетов «своих» ордеров

Ответ: С точки зрения оптимизации работы кода, удобно применять такой подход: первым делом проводим "ревизию" "своих" (это ордера с заданным MagicNumber()) ордеров, создаём массив тикетов с полной информацией по каждому тикету, а затем все остальные проверки (на закрытие и модификацию позиций) проводим с эти самым массивом тикетов.
Пример № 1. Сбор информации по тикетам на одной валютной паре.
// Сначала объявляем массив в глобальных переменных
double gda_Tickets[30][10]; // массив для хранения информации о "своих" ордерах:
       // gda_Tickets[][0] - Ticket
       // gda_Tickets[][1] - Type
       // gda_Tickets[][2] - Lots
       // gda_Tickets[][3] - Open Price
       // gda_Tickets[][4] - OrderProfit
       // gda_Tickets[][5] - Stop Loss
       // gda_Tickets[][6] - Take Profit
       // gda_Tickets[][7] - Open Time
       // gda_Tickets[][8] - MagicNumber
       // gda_Tickets[][9] - Expiration Time
// Не забываем о счётчике ордеров (он нам ещё понадобится)
int   gi_cnt_Tickets;
// сама функция
void fMyTickets (double& ar_Tickets[][10], int fi_Magic = -1)
{
    int li_cnt = 0; // счетчик заполнения
    int li_total = OrdersTotal();
//----
    for (int li_int = li_total - 1; li_int >= 0; li_int--)
    {
        if (OrderSelect (li_int, SELECT_BY_POS))
        {
            //---- проверка на Symbol
            if (OrderSymbol() != Symbol()) 
            {continue;}
            //---- проверка MagicNumber
            if (OrderMagicNumber() != fi_Magic
            && fi_Magic >= 0) // предусматриваем возможность контролтровать любой Magic
            {continue;}
            //---- заполняем массив
            ar_Tickets[li_cnt][0] = OrderTicket();
            ar_Tickets[li_cnt][1] = OrderType();
            ar_Tickets[li_cnt][2] = OrderLots();
            ar_Tickets[li_cnt][3] = OrderOpenPrice();
            ar_Tickets[li_cnt][4] = OrderProfit() + OrderSwap() + OrderCommission();
            ar_Tickets[li_cnt][5] = OrderStopLoss();
            ar_Tickets[li_cnt][6] = OrderTakeProfit();
            ar_Tickets[li_cnt][7] = OrderOpenTime();
            ar_Tickets[li_cnt][8] = OrderMagicNumber();
            ar_Tickets[li_cnt][9] = OrderExpiration();
            //---- увеличим счётчик заполненных тикетов
            li_cnt++;
        }
    }   
    gi_cnt_Tickets = li_cnt;
//----
    return;   
}

На любителя, можно объявить данную функцию типа int и чтобы она возвращала количество "своих ордеров".

gi_cnt_Tickets = fMyTickets (gda_Tickets, Magic);

Если наш советник мультивалютный.
Пример № 2. Сбор информации по тикетам на нескольких валютных парах.

Чтобы в данном случае производить проверку на "свой" символ, нам потребуется ещё одна небольшая функция:

//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+
//|  UNI:      Получаем номер элемента в массиве string                               |
//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+
int fGetNumElementInArray_STR (string sArray[], string Element)
{
//----
    for (int l_int = 0; l_int < ArraySize (sArray); l_int++)
    {
        if (sArray[l_int] == Element)
        {return (l_int);}
    }
//---- 
    return (-1);
} 

а наша функция будет иметь такой вид:

// В глобальных переменных объявляем ещё одина массив, теперь с символами с которыми работает наш мультивалютный советник
string gsa_Symbols[];
// Для использования его в советнике, нужно предварительно задать его размер и заполнить символами
// (как это сделать - отдельная тема)
// сама функция
int fMyTickets (string ar_Symbol[],        // заполненный массив рабочих символов
                 double& ar_Tickets[][11], // массив тикетов (для заполнения)
                 int fi_Magic = -1)        // MagicNumber
{
    int NUM_Symbol, li_cnt = 0; // счетчик заполнения
    int li_total = OrdersTotal();
    string ls_Sym;
//----
    for (int li_int = li_total - 1; li_int >= 0; li_int--)
    {
        if (OrderSelect (li_int, SELECT_BY_POS))
        {
            ls_Sym = OrderSymbol();
            //---- Определяем номер символа в массиве (фильтр по Symbol)
            NUM_Symbol = fGetNumElementInArray_STR (ar_Symbols, ls_Sym);
            //---- Если ордер не "свой" - пропускаем
            if (NUM_Symbol < 0)
            {continue;}
            //---- проверка MagicNumber
            if (OrderMagicNumber() != fi_Magic)
            {continue;}
            //---- заполняем массив
            ar_Tickets[li_cnt][0] = OrderTicket();
            ar_Tickets[li_cnt][1] = OrderType();
            ar_Tickets[li_cnt][2] = OrderLots();
            ar_Tickets[li_cnt][3] = OrderOpenPrice();
            ar_Tickets[li_cnt][4] = OrderProfit() + OrderSwap() + OrderCommission();
            ar_Tickets[li_cnt][5] = OrderStopLoss();
            ar_Tickets[li_cnt][6] = OrderTakeProfit();
            ar_Tickets[li_cnt][7] = OrderOpenTime();
            ar_Tickets[li_cnt][8] = OrderMagicNumber();
            ar_Tickets[li_cnt][9] = OrderExpiration();
            //---- для дальнейших вычислений не лишним будет запомнить номер индекса символа в массиве символов
            //---- но для этого не забудьте увеличить размер массива тикетов при его объявлении gda_Tickets[30][11]
            ar_Tickets[li_cnt][10] = NUM_Symbol;
            //---- увеличим счётчик заполненных тикетов
            li_cnt++;
        }
    }   
//----
    return (li_cnt);   
}
 

Вопрос: Получение массива тикетов «своих» ордеров

Ответ: (Продолжение)

Не удивительно, если Вы захотите в своём советнике иметь дополнительную статистику по его работе, например: максимальную просадку, общий профит и.т.д. Для того, чтобы лишний раз "не тревожить" сервер запросами, удобно добавить в нашу функцию функциональности (сорри за каламбур). Тогда функция может выглядеть так:

Вариант № 1 для моновалютного советника:

// Объявляем массив в глобальных переменных
double gda_Tickets[30][10]; // массив для хранения информации о "своих" ордерах:
       // gda_Tickets[][0] - Ticket
       // gda_Tickets[][1] - Type
       // gda_Tickets[][2] - Lots
       // gda_Tickets[][3] - Open Price
       // gda_Tickets[][4] - Order Profit
       // gda_Tickets[][5] - Stop Loss
       // gda_Tickets[][6] - Take Profit
       // gda_Tickets[][7] - Open Time
       // gda_Tickets[][8] - MagicNumber
       // gda_Tickets[][9] - Expiration Time
// Добавляем массив для сбора ститистики
double gda_AddInfo[5]; // массив для хранения дополнительной информации по работе советника
       // gda_AddInfo[0] - количество соих ордеров (всех)
       // gda_AddInfo[1] - количество своих рыночных ордеров
       // gda_AddInfo[2] - общий размер открытых рыночных лотов
       // gda_AddInfo[3] - общий профит по открытым позициям
       // gda_AddInfo[4] - максимальная просадка по открытым позициям
void fMyTickets (double& ar_Tickets[][10], // массив тикетов (для заполнения)
                 double& ar_Info[],        // массив для заполнения дополнительной информацией
                 int fi_Magic = -1)        // MagicNumber
{
    int li_cnt = 0; // счетчик заполнения
    int li_total = OrdersTotal();
    double tmp_Loss;
//----
    tmp_Loss = ar_Info[4];
    //---- Обнуляем заполняемый массив перед использованием
    ArrayInitialize (ar_Info, 0.0);
    for (int li_int = li_total - 1; li_int >= 0; li_int--)
    {
        if (OrderSelect (li_int, SELECT_BY_POS))
        {
            //---- проверка на Symbol
            if (OrderSymbol() != Symbol()) 
            {continue;}
            //---- проверка MagicNumber
            if (OrderMagicNumber() != fi_Magic
            && fi_Magic >= 0) // предусматриваем возможность контролтровать любой Magic
            {continue;}
            //---- заполняем массив
            ar_Tickets[li_cnt][0] = OrderTicket();
            ar_Tickets[li_cnt][1] = OrderType();
            ar_Tickets[li_cnt][2] = OrderLots();
            ar_Tickets[li_cnt][3] = OrderOpenPrice();
            ar_Tickets[li_cnt][4] = OrderProfit() + OrderSwap() + OrderCommission();
            ar_Tickets[li_cnt][5] = OrderStopLoss();
            ar_Tickets[li_cnt][6] = OrderTakeProfit();
            ar_Tickets[li_cnt][7] = OrderOpenTime();
            ar_Tickets[li_cnt][8] = OrderMagicNumber();
            ar_Tickets[li_cnt][9] = OrderExpiration();
            //---- увеличим счётчик заполненных тикетов
            li_cnt++;
            //---- заполняем массив дополнительной информацией
            ar_Info[0]++;
            if (OrderType() < 2)
            {
                ar_Info[1]++;
                ar_Info[2] += OrderLots();
                ar_Info[3] += OrderProfit() + OrderSwap() + OrderCommission();
            }
        }
    }   
    //---- Учитываем максимальную просадку
    ar_Info[4] = MathMin (ar_Info[3], tmp_Loss);
//----
    return;   
}

Вариант № 2 для мультивалютного:

// В глобальных переменных объявляем массив, с символами, с которыми работает наш мультивалютный советник
string gsa_Symbols[];
// Массив с дополниетельной информацией должен быть 2-ух мерным
// 1-ый индекс - это номер символа в массиве символов gsa_Symbols[]
// Не забудьте перед его использованием задать ему размер в первом измерении равный количеству используемых символов
// ArrayResize (gda_AddInfo, ArraySize (gsa_Symbols));
double gda_AddInfo[][5]; // массив для хранения дополнительной информации по работе советника
       // gda_AddInfo[][0] - количество соих ордеров (всех)
       // gda_AddInfo[][1] - количество своих рыночных ордеров
       // gda_AddInfo[][2] - общий размер открытых рыночных лотов
       // gda_AddInfo[][3] - общий профит по открытым позициям
       // gda_AddInfo[][4] - максимальная просадка по открытым позициям
// Для использования его в советнике, нужно предварительно задать его размер и заполнить символами
// (как это сделать - отдельная тема)

void fMyTickets (string ar_Symbol[],      // заполненный массив рабочих символов
                double& ar_Tickets[][11], // массив тикетов (для заполнения)
                double& ar_Info[][5],     // массив для заполнения дополнительной информацией
                int fi_Magic)             // MagicNumber
{
    int NUM_Symbol, li_cnt = 0, li_Range = ArraySize (ar_Symbol); // счетчик заполнения
    int li_total = OrdersTotal();
    string ls_Sym;
    double tmp_Loss[];
//----
    //---- Инициализируем временный массив для хранения сведений о максимальной просадке
    ArrayResize (tmp_Loss, li_Range);
    //---- Сохраняем в него эти сведения
    for (int li_int = 0; li_int < li_Range; li_int++)
    {tmp_Loss[li_int] = ar_Info[li_int][4];}
    //---- Обнуляем используемый массив
    ArrayInitialize (ar_Info, 0.0);
    for (int li_int = li_total - 1; li_int >= 0; li_int--)
    {
        if (OrderSelect (li_int, SELECT_BY_POS))
        {
            ls_Sym = OrderSymbol();
            //---- Определяем номер символа в массиве (фильтр по Symbol)
            NUM_Symbol = fGetNumElementInArray_STR (ar_Symbols, ls_Sym);
            //---- Если ордер не "свой" - пропускаем
            if (NUM_Symbol < 0)
            {continue;}
            //---- проверка MagicNumber
            if (OrderMagicNumber() != fi_Magic
            && fi_Magic >= 0) // предусматриваем возможность контролтровать любой Magic
            {continue;}
            //---- заполняем массив
            ar_Tickets[li_cnt][0] = OrderTicket();
            ar_Tickets[li_cnt][1] = OrderType();
            ar_Tickets[li_cnt][2] = OrderLots();
            ar_Tickets[li_cnt][3] = OrderOpenPrice();
            ar_Tickets[li_cnt][4] = OrderProfit() + OrderSwap() + OrderCommission();
            ar_Tickets[li_cnt][5] = OrderStopLoss();
            ar_Tickets[li_cnt][6] = OrderTakeProfit();
            ar_Tickets[li_cnt][7] = OrderOpenTime();
            ar_Tickets[li_cnt][8] = OrderMagicNumber();
            ar_Tickets[li_cnt][9] = OrderExpiration();
            ar_Tickets[li_cnt][10] = NUM_Symbol;
            //---- увеличим счётчик заполненных тикетов
            li_cnt++;
            //---- заполняем массив дополнительной информацией
            ar_Info[NUM_Symbol][0]++;
            if (OrderType() < 2)
            {
                ar_Info[NUM_Symbol][1]++;
                ar_Info[NUM_Symbol][2] += OrderLots();
                ar_Info[NUM_Symbol][3] += OrderProfit() + OrderSwap() + OrderCommission();
                ar_Info[NUM_Symbol][4] = MathMin (tmp_Loss[NUM_Symbol], ar_Info[NUM_Symbol][3]);
            }
        }
    }   
//----
    return;   
}

В приведённых примерах по сбору информации о тикетах, этой информации хватает в подавляющем большинстве случаев. Но никто Вам не запрещает в более сложных системах в массиве тикетов хранить, например, если в советнике предусмотрены виртуальные стопы, о них информацию:

double gda_Tickets[30][12]; // массив для хранения информации о "своих" ордерах:
       // gda_Tickets[][0] - Ticket
       // gda_Tickets[][1] - Type
       // gda_Tickets[][2] - Lots
       // gda_Tickets[][3] - Open Price
       // gda_Tickets[][4] - Order Profit
       // gda_Tickets[][5] - Stop Loss
       // gda_Tickets[][6] - Take Profit
       // gda_Tickets[][7] - Open Time
       // gda_Tickets[][8] - MagicNumber
       // gda_Tickets[][9] - Expiration Time
       // gda_Tickets[][10] - Virtual SL
       // gda_Tickets[][11] - Virtual TP

В общем здесь Вы ограничены только полётом фантазии\фанатизма и уровнем знания MQL4.

 

TarasBY

Для того, чтобы лишний раз "не тревожить" сервер запросами...

При сборе ордеров сервер не тревожится. Идеология сбора информации по ордерам в массив -- УГ. Это ни в коем случае в ЧаВо нельзя.
 
TheXpert:
При сборе ордеров сервер не тревожится. Идеология сбора информации по ордерам в массив -- УГ. Это ни в коем случае в ЧаВо нельзя.

предложите другой вариант. для потребности работы со "своими" ордерами
 
Не предложу. Чаще всего массив тикетов вообще не нужен. А правильней всего, имхо, всегда просить максимально свежую информацию у терминала.
Причина обращения: