Regras de estrutura. Aprender a estruturar programas, explorar possibilidades, erros, soluções, etc. - página 6

 
FAQ:

ZS. É um pouco pequeno, então porque não fazemos um mais global?

Tem uma proposta concreta?
 
MetaDriver :

Bem, tady prick (em termos gerais), como você preenche essas lacunas entre os quatro primeiros. Está tudo em DLLs? :)

Sem DLL, MCL puro + winepi para manipulação de eventos .

Em relação a isso, precisamos encontrar tempo para descrever tudo lindamente e fazer um ótimo artigo. Eu posso lançar um exemplo ou uma implementação de pseudoclasses visuais para MT4, mas temo que seja difícil digerir sem uma descrição detalhada. A essência da criação de um DOM (Data Object Module) para MT por analogia com JS - eles são realmente semelhantes de qualquer maneira. Para sementes - a principal função do coração, por assim dizer:

 //+------------------------------------------------------------------+
//| Brief Description included Functions                             |
/*+----exported function---------------------------------------------+
bool   ObjSet(ObjNm,ObjTyp,isets[],tsets[],{ObjParent})Устанавливает на график объект класса Interface.
void   ObjDelete(string nm,bool delChild=true) Удаляет объект с графика, вместе , или без первого потомка
void   ObjsDelete(string nm) Удаляет объект, вместе со всеми его потомками
double ObjGet(string nm, int prop_id) Ищет объект и возвращает значение его свойства
bool   ObjSearch(string ObjNm):int[];string; Возвращает признак наличия объекта класса Interface
int    This(int prop_id) Ищет значение свойства объекта в списке свойств : obj_props[10]
//+----internal function---------------------------------------------+
string ObjGetName(string,int[],{string})  Собирает полное имя объекта класса Interface
void   ObjSetLabel()Обертка для стандартной функции
*/ //+----------------------------------------------------------------+
//|                                      OBJECTS_INTERFACE_CLASS.mq4 |
//|           Copyright © 2012, XrustSolution. mail:xrustx@gmail.com |
//|          https://www.youtube.com/user/opmlv http://forexrust.info |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, XrustSolution."
#property link        "mail: xrustx@gmail.com https://www.youtube.com/user/opmlv http://forexrust.info"
//+------------------------------------------------------------------+
//|   Extern variables                                               |
//+------------------------------------------------------------------+
extern    string    ObjectsInterfaceSettings = "-------- ObjectsInterfaceSettings ----------" ;
extern    int       X_Distance                                = 2       ;
extern    int       Y_Distance                                = 2       ;
extern    int       ChartCorner                               = 0       ;

//+------------------------------------------------------------------+
//|   Defines                                                        |
//+------------------------------------------------------------------+
#define GlobalPrefix     "wnd:"    // Префикс имени класса
#define GlobalParent     "chart"    // Имя глобального родителя
#define hName           "Header" // Имя главного родителя (заголовка)
#define wName           "Window" // Имя главного окна
#define cName           ""        // Стандартное имя текущего объекта
#define tName           "Txt"    // Стандартное имя для текстовой строки
#define Objects 500                // Максимальное количество командных объектов
//+------------------------------------------------------------------+
//|   Global variables                                               |
//+------------------------------------------------------------------+
string ObjParent = "" ;           // Глобальное имя родителя Object Parent Name
string ObjName   = "" ;           // Глобальное имя объекта  Object Own Name
int     obj_props[ 10 ];             // Набор свойств объекта : {xdLeft,ydUp,xdRight,ydDown,zIndex,Class,Corner,Color,Window};
//+------------------------------------------------------------------+
string   ObjsParent[Objects];     // Список имен родителей командных объектов
string   ObjsNames[Objects];       // Список имен командных объектов
int      CommObjs[Objects][ 6 ];     // Список параматров командных объектов = {класс,угол,х0,у0,х1,у1}
string   ObjsDom[Objects][ 2 ];     // Список всех объектов и их дочерних элементов (объектов) ObjsDom[Parent][Childrens]
string   ObjsDel[ 5000 ];           // Список старых объектов для удаления при перемещении окон  
string   ObjsName[ 5000 ];       // Список полных имен объектов
//+------------------------------------------------------------------+
//|   Defines                                                        |
//+-----ObjectsTypes-------------------------------------------------+
#define         OBJ_CANVAS       30        // Холст\Окно\Прямоугольник (Основной элемент)
//+---Предопределенные типы окон-------------------------------------+
#define         OBJ_WINDOW     31 // Пустое окно
#define         OBJ_TXTWND     32 // Текстовое окно с форматированием текста
#define         OBJ_HTMWND     33 // Текстовое окно с форматированием, активными ссылками
#define         OBJ_CHARTW     34 // Псевдографическое окно с возможностями граф построений
//#define       OBJ_LEDWND     34 // 

//+---Кнопки командные-----------------------------------------------+ 
#define   OBJ_BUTTON      40 // Кнопка (пустая) общего назначения
//----Кнопки предопределенные(Команда)
#define   OBJ_BUTBUY     41 // OP_BUY
#define   OBJ_BUTSEL     42 // OP_SELL
#define   OBJ_BUTCLO     43 // ORDER_CLOSE
#define   OBJ_BUTREV     44 // ORDER_REVERSE
#define   OBJ_BUTBST     45 // OP_BUYSTOP
#define   OBJ_BUTBLM     46 // OP_BUYLIMIT
#define   OBJ_BUTSST     47 // OP_SELLSTOP
#define   OBJ_BUTSLM     48 // OP_SELLLIMIT
#define   OBJ_BUTDEL     49 // ORDER_DELETE
//+---Ярлыки командные (кнопки 1х1 с значком)------------------------+
#define   OBJ_LABCNT     50 // Командный ярлык (Контрол) Без обкладки в виде канваса 1х1 наследие двигательного аппарата команд
#define   OBJ_LABCOM     51 // Командный ярлык кнопка 1х1 с канвасом (пустой) 
//----Ярлыки предопределенные(Команда)
         /*----Группа ярлыков кнопок находящихся в заголовке (верхнем меню)---*/
#define   OBJ_LABCLO     52 // Ярлык/Кн.закрыть
#define   OBJ_LABHID     53 // Ярлык/Кн.Свернуть
#define   OBJ_LABSHW     54 // Ярлык/Кн.развернуть
#define   OBJ_LABSET     55 // Ярлык/Кн.Настройки
         /*----Двухцветные ярлычки (триггеры(серый\зеленый))----*/
#define   OBJ_LABALR     56 // Ярлык/Кн.Алерт
#define   OBJ_LABSND     57 // Ярлык/Кн.Звук
#define   OBJ_LABEML     58 // Ярлык/Кн.Мыло
#define   OBJ_LABSEL     59 // Ярлык/Кн.Select\Unselect
         /*----Группа ярлыков стрелок и др предустановленных спец символов---*/
#define   OBJ_LABLFT     60 // Ярлык/Стрелка Влево
#define   OBJ_LABRGT     61 // Ярлык/Стрелка Вправо
#define   OBJ_LABUP       62 // Ярлык/Стрелка Вверх
#define   OBJ_LABDWN     63 // Ярлык/Стрелка Вниз
     
#define   OBJ_LAB_TXT     69 // Текстовая строка / значек в ярлыке
//+----Хидеры(заголовки)-Основной родительский объект, наследует все остальные+
#define   OBJ_HD         70 // Пустой хидер (прямоугольник 1 размера блока)
#define   OBJ_HDC         71 // + Кнока закрытия
#define   OBJ_HDH         72 // + Кнопка свернуть\развернуть
#define   OBJ_HDCH       73 // + закрыть + развернуть
#define   OBJ_HDCHT       74 // + закрыть + развернуть + настройки
#define   OBJ_HDСHTS     75 // + закрыть + развернуть + настройки + системное меню алертов
//+-----ObjectProperties---------------------------------------------+
#define   OBJ_PRP_X0         17    // левая координата (Х0)
#define   OBJ_PRP_Y0         18    // верхняя координата (Y0)
#define   OBJ_PRP_X1         19    // правая координата (Х0) 
#define   OBJ_PRP_Y1         20    // нижняя координата (Х0)
#define   OBJ_PRP_ZI         21    // Зет Индекс
#define   OBJ_PRP_CLS         22    // Класс Объекта
#define   OBJ_PRP_CRN         23    // Угол привязки объекта
#define   OBJ_PRP_CLR         24    // Цвет
#define   OBJ_PRP_WND         25    // Окно в котором объект находиться
#define   OBJ_PRP_LAY         26    // Резерв (здесь будет количество слоев, для более точного определения параметров элементов)
//+-----Массив аргументов для функции GetObjectName()----------------+
int      Props[ 10 ];                                                      
//              Props[0] = Лево         
//              Props[1] = Верх 
//              Props[2] = Право        
//              Props[3] = Низ  
//              Props[4] = Счетчик по Х 
//              Props[5] = Счетчик по У 
//              Props[6] = Зет индекс (основной)        
//              Props[7] = Зет индекс (дополнительный для объектов из нескольких слоев) 
//              Props[8] = Идентификатор зет индекса последнего (верхнего) слоя в объекте
//              Props[9] = Идентификатор типа объекта                                           
//+---Массивы с корректыми размерами шрифтв Webdings для >= 416 билда---------------+
int realSz[ 21 ] = { 15 , 23 , 31 , 35 , 43 , 47 , 55 , 67 , 75 , 83 , 87 , 91 , 95 , 99 , 119 , 123 , 127 , 143 , 148 , 156 , 164 }; // Таблица реальных размеров
int fontSz[ 21 ]  = { 11 , 17 , 23 , 26 , 32 , 35 , 41 , 50 , 56 , 62 , 65 , 68 , 71 , 74 , 89 , 92 , 95 , 107 , 110 , 116 , 122 }; // Таблица корректных шрифтов
int szCorr[ 21 ] = { 4 , 5 , 6 , 7 , 9 , 10 , 12 , 15 , 17 , 19 , 20 , 21 , 22 , 23 , 28 , 29 , 30 , 34 , 36 , 38 , 40 }; // Разница между размером шрифта, и реальным размером
int vertCr[ 21 ] = {- 3 ,- 2 ,- 1 ,- 1 ,- 2 , 0 ,- 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,   0 , - 1 ,   0 ,   0 ,   0 ,   0 ,   0 }; // Таблица cмещения по вертикали от размера шрифта

//+------------------------------------------------------------------+
//|  Includes                                                        |
//+------------------------------------------------------------------+
#include <OBJ_CANVAS.mqh> //SetCanvas(onm,xd,yd,xs,ys,[sz,zindx,oClr,crn,wnd,pnm,bord,bClr]);
#include <OBJ_LAB_TEXT.mqh> //SetTextString(onm,pnm,typ,txt,fnm,clr,[center,xd,yd,psz,fsz,crn,wnd]):int:error;
//#include <OBJ_BUTTON.mqh>//SetButton(onm,pnm,type[,xd,yd,xs,ys,text,tx_fnt,txClr,sz,bgClr,bdClr,crn,wnd]);
#include <OBJ_HEADER.mqh>
#include <OBJ_LED_SIMPLE.mqh>
//+------------------------------------------------------------------+
//|           Function  : string GetObjectName(string,int[],{string})|
//|           Copyright © 2012, XrustSolution. mail:xrustx@gmail.com |
//|          https://www.youtube.com/user/opmlv http://forexrust.info |
//+------------------------------------------------------------------+
//|                     Собирает полное имя объекта класса Interface |
//+------------------------------------------------------------------+
//|Полное имя объекта должно состоять из :                           |
//|wnd:        = Основной префикс имени                         4 зн |
//|z_0ax:      = Z индекс для опр. порядка отображения окна 1-9 6 зн |10 зн
//|c_30:       = Тип объекта класса (смотреть в списке типов)   5 зн |15 зн
//|lu_xxx_yyy: = Координаты левого верхнего угла               10 зн |25 зн
//|rd_xxx_yyy: = Координаты правого нижнего угла               10 зн |35 зн
//|id_xxx_yyy: = Номера объектов                               10 зн |45 зн
//|#name|parent= Собственное имя обьекта из максимум 15 знаков,    до|60 зн
//|состоящее из имени элемента класса, и имени родительского объекта |
//+------------------------------------------------------------------+
//|Разделители:  типов свойств     = двоеточите(:),                  |
//|              значений свойств  = нижнее подчеркивание(_)         |
//|              имя объекта       = решетка(#)конец описания свойств|
//|              имя родителя      = слеш[|]                         |
//+------------------------------------------------------------------+
string     ObjGetName( string Name,                                   // Имя объекта
                                                         int       Props[],                                 // Набор свойств объекта
                                                         string Parent = GlobalParent                   // Имя родителя, по умолчанию = "chart" , то есть основное окно графика
                                                        ){ string out= "" ;
//+------------------------------------------------------------------+
   if (Parent== "" ){Parent = "chart" ;}
   if (Props[ 9 ]!=OBJ_LAB_TXT){ // если объект текстовая строка добавляем в описание имя шрифта
        out = StringConcatenate (GlobalPrefix,                                   //
                                                                         "z_" ,Props[ 6 ],StringSetChar( "" , 0 ,Props[ 7 ]+ 97 ),StringSetChar( "" , 0 ,Props[ 8 ]+ 97 ), ":" ,
                                                                         "c_" ,Props[ 9 ], ":" ,
                                                                         "lu_" ,Props[ 0 ], "_" ,Props[ 1 ], ":" ,
                                                                         "rd_" ,Props[ 2 ], "_" ,Props[ 3 ], ":" ,
                                                                         "id" ,Props[ 4 ], "" ,Props[ 5 ], ":" ,
                                                                         "#"   ,Name    , "|" ,Parent);
        } else { // работаем как обычно
        out = StringConcatenate (GlobalPrefix,                                   //
                                                                         "z_" ,Props[ 6 ],StringSetChar( "" , 0 ,Props[ 7 ]+ 97 ),StringSetChar( "" , 0 ,Props[ 8 ]+ 97 ), ":" ,
                                                                         "c_" ,Props[ 9 ], ":" ,
                                                                         "lu_" ,Props[ 0 ], "_" ,Props[ 1 ], ":" ,
                                                                         "fn_font_name:" ,
                                                                         "id" ,Props[ 4 ], "" ,Props[ 5 ], ":" ,
                                                                         "#"   ,Name    , "|" ,Parent);
        }                                                               
         return (out);
}
MetaDriver :
Tem uma oferta específica?

Existe, e a tarefa está viva, mas tenho medo de pronunciá-la aqui, posso no pessoal.

 
C-4:
Hoje em dia, nenhum programador normal desenha fluxogramas. Tudo isto é um disparate teórico concebido para ser ensinado às crianças em idade escolar, mas não para trabalhar em projectos reais.
Não é um disparate. Era necessário quando os programas eram escritos em códigos de máquina. E depois foram arrastados para livros escolares e tornaram-se um disparate quando os programas eram descritos em línguas normais. E depois houve o USPD, o Sistema Unificado de Documentação de Programas. E para o submeter ao cliente teve de ser elaborado de acordo com regras muito estritas. Tinha de haver um diagrama de blocos e todo o tipo de descrições.
 
FAQ:

Sem DLL, puro MCL + winapi para processamento de eventos.

A este respeito, preciso de encontrar tempo para descrever tudo de forma agradável e fazer um grande artigo. Posso lançar um exemplo ou implementação de pseudoclasses visuais para MT4, mas receio que será difícil de digerir sem uma descrição detalhada. A essência é criar DOM (Data Object Module) para MT por analogia com o JS - eles são realmente semelhantes. Para uma cartilha - a função principal do coração, por assim dizer:

(Sim, com um balanço. ))

DOM - isso é muito. Dê-me pelo menos algumas imagens de ecrã... Ou (se disponível) algum exemplo compilado isoladamente, para o sentir no terminal. Tem um?

 
MetaDriver:

(Risos...) Com um estrondo. ))

DOM - isso é muito. Dê-me pelo menos algumas imagens de ecrã... Ou (se disponível) algum exemplo compilado isoladamente, para o sentir no terminal. Tem um?

veja aqui :https://www.youtube.com/user/opmlv há uma carruagem cheia de coisas para rastrear a sua evolução :)
Rustamzhan Salidzhanov
Rustamzhan Salidzhanov
  • www.youtube.com
Краткая сборка софта созданного мной , для торговой платформы MetaTrader 4. Все имущественные права на данный софт принадлежат заказчикам, как правообладателям. И не могут быть переданы третим лицам без их (правообладателей) согласия. Я за собою оставляю авторское право как создатель данного софта. Quick assembly of software created by me for...
 
MetaDriver:

Vamos fazer uma tentativa?

Nada.

1. O painel é directo à cauda. a estratégia é primária, se não arar, o painel é inútil e inútil.

2. A implementação da parte comercial depende da estratégia, pelo que não há nada a discutir no quadro da invasão de uma estratégia hipotética. A implementação da estratégia, curiosamente, também depende da estratégia :)

3. Fazer imediatamente um gatilho para desactivar a estratégia contabilizada no bloco comercial. E desactivar a colocação de novas encomendas.

4. Painel. O que é um painel - uma rotina.

 

Quanto a escrever o TS, é algo parecido com isto:

Fórum sobre comércio, sistemas automatizados de comércio e testes de estratégia comercial

Discussão sobre o comércio de alta frequência no MT5

hrenfx, 2013.02.06 14:30


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

Это чем-то напиминает копирование торговых сигналов с одного счета на другой. Только вместо примитивного копировщика работает грамотный синхронизатор.

К сожалению, правильную логику синхронизатора посмотреть где-либо практически невозможно, поэтому озадачевшемуся придется подумать самому - очень полезно.

Но и такая логика построения боевого-робота далеко не совершенна, т.к. встает дилема первичности курицы и яйца. Поэтому применяются более сложные свои схемы, основанные на опыте автора-алготрейдера.

Все эти действия совершаются только ради одного - адекватной настройки стратегии. Какой бы совершенной не была схема, все равно одинаковые боевые роботы на разных счетах одного и того же ECN/STP брокера покажут расхождения. И помимо поиска рыночных закономерностей, важной задачей для алготрейдера также является уменьшение этих расхождений. Как уже говорилось выше, чем ближе брокер к возможстям HFT, тем меньше расхождения.

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

 
TheXpert:

Nada.

1. O painel é directo à cauda. a estratégia é primária, se não arar, o painel é inútil e inútil.

2. A implementação da parte comercial depende da estratégia, pelo que não há nada a discutir no quadro de um hipotético ataque estratégico. A implementação da estratégia, curiosamente, depende também da estratégia :)

3. Fazer imediatamente um gatilho para desactivar a estratégia contabilizada no bloco comercial. E desactivar a colocação de novas encomendas.

4. Painel. Que painel - uma rotina.

Bem, aqui temos algo a discutir de imediato. :))

Não para discutir, digamos, mas para apontar as possibilidades:

1. A estratégia do painel é primária, se não for arado, o painel é inútil e inútil.

Até agora, concordo, mas com uma ressalva: o programa deve ser imediatamente orientado para trabalhar em dois modos, pelo que a parte de estratégia / comércio deve ser prescrita de uma só vez, tendo em conta a presença / ausência de controlo do painel e com / sem exibição de informação no painel.

2. A implementação da parte comercial depende da estratégia, .......

Não depende da minha estratégia. Toda a parte comercial é escrita numa classe (CMarketDriver), que implementa completamente a entrada de ordens, seguimento de posição, requisições e outras coisas relacionadas com a negociação. Para todos os símbolos de uma só vez. A parte de estratégia apenas recebe posições de mercado recomendadas para símbolos: ou seja, preenche o conjunto de estruturas do formato {string Instrument; double Position} e solicita sincronização com o servidor: MD.Synchronize(PositionArray). Por agora só negoceia com ordens do mercado mas uma versão que negoceia com limites estabelecidos dentro do spread (para reduzir os custos de negociação) está a caminho. Para a negociação, os takeprofits/stops não utilizam, mas a MarketDriver pode colocar paragens de protecção em caso de perda prolongada da ligação ao servidor (os parâmetros de paragem são especificados uma vez nas definições do controlador). A propósito, muito bem sucedido, quase não há solução estruturada de problemas. Para testar ideias estratégicas no testador - sem problemas com a negociação, toda a atenção pode ser dedicada à estratégia - toda a negociação foi há muito depurada e encapsulada no controlador de negociação.

2............., pelo que não há nada a discutir no âmbito de um hipotético assalto estratégico. A implementação da estratégia depende também, curiosamente, da estratégia :)

Por exemplo, tenho uma nova ideia - trocar na intersecção de um par de limpadores. Neste caso, o problema é reestruturar o programa de modo a que, ao desenvolvê-lo (por exemplo, adicionar um terceiro limpador), não tenha de alterar a maior parte do código. Então, o programa pode ser desenvolvido no sentido da moeda múltipla (por simplicidade do projecto, suponhamos que o comércio por símbolos é estritamente independente e as inter-relações não são consideradas). Como organizar a parte estratégica, antecipando tal desenvolvimento?

3. Imediatamente definir o gatilho para desactivar a estratégia tomada em consideração no bloco comercial. E desactivar a colocação de novas encomendas.

Mas não temos de o fazer. Afinal, não esperamos muitos problemas aqui.

4. Painel. Bem, o painel é uma tarefa difícil.

Mas a organização da comunicação da estratégia com o painel é uma tarefa bastante criativa, especialmente se tentarmos desenvolver um modelo mais ou menos universal para tal painel, que possa ser facilmente adaptado a diferentes Expert Advisors e facilmente desenvolvido à medida que o projecto cresce/desenvolve.

 
MetaDriver:

Não é preciso, quase nunca depende de mim.

Comigo quase sempre depende. Especialmente quando se trabalha com ECN. Quer dizer, nem tudo é feito ao nível mais baixo, claro, mas apenas através das conchas das funções comerciais normais.

Документация по MQL5: Торговые функции
Документация по MQL5: Торговые функции
  • www.mql5.com
Торговые функции - Документация по MQL5
 
TheXpert:

Comigo quase sempre depende. Especialmente quando se trabalha com ECN. Quer dizer, nem tudo é feito ao nível mais baixo, claro, mas apenas através das conchas das funções comerciais normais.

Bem, isso é um mau tipo de coisa. Não sei como é que a minha relação com a ECN vai acabar aí (vou abrir uma conta na RoboForex), mas vou tentar o meu melhor para manter este desacoplamento estrutural (estratégia/market driver). É tão conveniente, que até estou pronto para alguns custos comerciais moderados (como lucros perdidos).

Veja como o ciclo principal da EA parece simples no final:

// Тестовый советник для тестирования обученных в GPU-оптимизаторе нейросеток (или записи значений котировок/индикаторов для отправки исходных данных в тот же оптимизатор).
void OnTick()
  {
   if(Mode==TradesMode) //-- Если режим тестирования
     {
      for(int i=0;i<CountInd;i++)
        {
         vInds[i]=GetInd(i,0);   // получаем значения индикаторов
        }
      Net.CalcResult(vInds);             // рассчитываем значение нейросетки
      float net_result=Net.NetResult[0];  // забираем рекомендованную рыночную позицию      
      SP.Pos=net_result*Lot;             // заполняем структуру для MarketDriver'a
      int err;
      MD.Synhronize(SP,err);             // синхронизируемся с торговым сервером.
     }
   else // Mode==RecordMode  // Если режим записи
..............
Verifique a versão de teste simplificada e veja se gostou do esquema. Se alguma coisa, ajuste-o às suas necessidades e use-o a seu favor.
Arquivos anexados: