Как програмно перезагрузить чарт? - страница 6

 
AlexSTAL:

Вы обратитесь к платным программистам с конкретными кодами и конкретным заданием и будет Вам счастье...

Или в этой ветке попробуйте выложить всё и возможно найдётся альтруист...


Путь к УСПЕХУ каждый должен пройти сам! Ни кто за меня мой путь не пройдёт!

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

 

Наверное, чтобы "тем, кто будет идти за нами", кто столкнётся с теми же "граблями", и подводя ответ вопросу, будет не лишним, если я озвучу полученное решение.

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

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

    hWnd = GlobalVariableGet (PreFix + "_hWnd");
    // Если у нас такое окно существовало
    if (hWnd > 0)
    {
        if (CloseWindow (hWnd) > 0)
        {Print ("Закрыли окно ", hWnd, "!!!");}
    }

соответственно в init() этой самой функции нужно провести обратное действие:

    hWnd = GlobalVariableGet (PreFix + "_hWnd");
    if (hWnd > 0)
    {
        if (GetAncestor (hWnd, GA_ROOT) == hWnd)
        {
            if (OpenDeletedChart (0))
            {if (PrintCom) {Print ("EquityBasket: Восстанавливаем chart с индикаторами !!!");}}
        }
        else
        {
            if (fRefreshChart (hWnd))
            {if (PrintCom) {Print ("EquityBasket: Перезагружаем chart с индикаторами !!!");}}
            else
            {if (PrintCom) {Print ("EquityBasket: Перезагрузка chart`a с индикаторами не произведена!!!");}}
        }
    }
    else
    {
        {if (PrintCom) {Print ("EquityBasket: Нет дескриптора окна !!!");}}
        //---- Включаем переключатель Restart`a для других индикаторов
        gi_Restart = GlobalVariableGet (PreFix + "_ReStart");
        GlobalVariableSet (PreFix + "_ReStart", IIFi ((gi_Restart == 0), 1, 0));
        if (PrintCom) {Print ("EquityBasket: Переключаем флаг перезагрузки !!! ReStart = ", GlobalVariableGet (PreFix + "_ReStart"));}
    }

а в каждом индюке прописываем условие на перезагрузку в start():

    //---- Следим за принудительной перезагрузкой
    fl_ReStart = GlobalVariableGet (PreFix + "_ReStart");
    if (cur_fl_ReStart != fl_ReStart && !first_run)
    {
        init();
        fPrintComment (StringConcatenate (gs_NameGV, ": Совершаем регулируемую перезагрузку !!! first run = ", CheckBOOL (first_run), "."), PrintCom);
    }
    //---- Флаги перезагрузки нужно переключить (в конце функции)
    if (first_run && cur_fl_ReStart != fl_ReStart)
    {cur_fl_ReStart = IIFi ((cur_fl_ReStart == 0), 1, 0);}

Ну, и напоследок, библиотека презагрузочных функций:

#define GA_ROOT 2
#define PAUZE 100
#include        <WinUser32.mqh>
//+------------------------------------------------------------------+
// Открывает окно удаленного графика с номером NumChart (нумерация с нуля)
//+------------------------------------------------------------------+
bool OpenDeletedChart (int NumChart)
{
    int hwnd = fWindowHandle();
    int err[] = {0};
//----
    hwnd = GetAncestor (hwnd, GA_ROOT);
    NumChart += 35000;  
    if (PostMessageA (hwnd, WM_COMMAND, NumChart, err) > 0)
    {return (true);}
//----
    return (false);
}
//+------------------------------------------------------------------+
// Закрывает\открывает окно удаленного графика с дескриптором hwnd   |
//+------------------------------------------------------------------+
bool fRefreshChart (int hwnd)
{
    if (CloseWindow (hwnd) > 0)
    {
        Print ("Закрыли окно ", hwnd, "!!!");
        Sleep (PAUZE);
        if (OpenDeletedChart (0))
        {return (true);}
    }
    else
    {Print ("Не закрыли окно ", hwnd, "!!!");}
//----
    return (false);
}
//+------------------------------------------------------------------+
//|    ПОЛУЧАЕМ ДЕСКРИПТОР ОКНА                                      |
//+------------------------------------------------------------------+
int fWindowHandle()
{
    int cnt = 0, Handle = -1;
    
    while (Handle <= 0 && !IsStopped())             // Выходим из цикла, только если получили дескриптор окна.
    {
        Handle = WindowHandle (Symbol(), Period()); // Получаем системный дескриптор нового окна.
        Sleep (500);                                // Делаем задержку между итерациями.
        cnt++;
        if (cnt > 20)
        {break;}
    }
   return (Handle);
}

Ну, и, конечно, один из индикаторов, тот, который рисует бары эквити, должен передать информацию о дескрипторе своего окна в start():

    if (first_run)
    {
        if (cur_fl_ReStart != fl_ReStart)
        {cur_fl_ReStart = IIFi ((cur_fl_ReStart == 0), 1, 0);}
        hWnd = fWindowHandle();
        GlobalVariableSet (PreFix + "_hWnd", hWnd);
    }
 

RekkeR:

А само решение известно?

Для примера реализации есть готовый прошлогодний эксперт для mt5. Расставляет на всех чартах кнопку "Reset" и переинициализирует чарт при нажатии.

Можешь взять в прицепе.

Для четвёрки у меня нет, но по аналогии можешь сам сделать.

Файлы:
 

Спасибо Владимир.