English 中文 Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
Стать хорошим программистом (Часть 6): 9 привычек для эффективной разработки

Стать хорошим программистом (Часть 6): 9 привычек для эффективной разработки

MetaTrader 5Примеры | 18 января 2022, 16:00
2 009 0
Omega J Msigwa
Omega J Msigwa

Введение

Как программисты, мы можем приобрести некоторые привычки, которые помогут оставаться сосредоточенным все время, пока мы работаем. Может оказаться так, что мы сидим, что-то разрабатываем, но эффективность процесса далека от идеальной. Причины могут быть разными, например неумение фокусироваться, отсутствие плана или неверно составленный план.

Эффективная разработка

Содержание:

  • Планирование проекта до начала разработки
  • Создание коллекции сниппетов кода
  • Распорядок дня
  • Планирование дней интенсивной работы
  • Создание небольших функции и тестирование
  • Добавление комментариев для работы в будущем
  • Слепая печать
  • Использование лучших инструментов
  • Контроль версий

Внимание!

Все фрагменты кода и примеры, используемые в статье, предназначены только для демонстрации. Для некоторых из них не проводилось тестирование/отладка. Они используются только для иллюстрации идей. Если вы решите использовать какой-либо код, используйте его на свой страх и риск.

1. Планирование проекта до начала разработки


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

А ведь умение составлять хороший план — важный навык для эффективной разработки.

Вы поедете на общественном транспорте, скажем, автобусе, не зная, куда едете? Точно нет.

Прежде чем приступать к написанию кода, напишите тип желаемой программы, инструменты, библиотеки, которые хотите в ней использовать, и т.д.

В разделе Фриланс есть техническое задание. Это тоже пример планирования, и такой план должен быть у каждого разработчика до начала разработки.

Можно использовать любые стандартные программы, например Microsoft Word или WPS, или, если так удобнее, записывать план ручкой на бумаге. Можно рисовать схемы и картинки, объясняющие, как будет работать.

Я абсолютно согласен с Чарльзом Кеттерингом, который сказал: «Хорошо сформулированная проблема — это наполовину решенная проблема».

Например, нужно создать советник Simple Grid Expert Advisor с управлением капитала на основе системы Лабушера.

Вот простой план работы.

Примечание: все начальные значения ниже можно оптимизировать/они являются входными переменными

Начальные значения: Lotsize = 0.01; xgrid = 100; LotIncrement = 0.01;

Моя стратегия

Формула расчета размера лота по типу позиции

Условия сетки (стратегия в более понятном виде)

Мани-менеджмент

Библиотеки

Условие 1. Если нет открытых позиций, открываем две позиции — одну на покупку, вторую на продажу.

X = Lotsize + (LotIncrement * Количество позиций по типу позиции)

 Пример: BuyLotsize = 0.01 + ( 0.01 * Количество позиций на покупку);

Условие на покупку возникает, когда количество позиций на покупку = 0 (ноль) или когда уже есть позиции на покупку и при этом цена Bid ниже <цена открытия последней позиции на покупку> минус xgrid пунктов  

StopLoss = 0 (по умолчанию)

 

Стандартная библиотека — классы позиций

Стандартная библиотека — информация о символе

Стандартная библиотека — торговые классы

Условие 2 (условие на продажу). Если цена прошла xgrid пунктов вверх от цены открытия последней позиции на продажу, открыть позицию Sell с Lotsize равным размеру лота предыдущей позиции Lotsize плюс LotIncrement.    Условие на продажу возникает, когда количество позиций на продажу = 0 (ноль) или когда уже есть позиции на продажу и при этом цена Ask выше <цена открытия последней позиции на продажу> плюс xgrid

TakeProfit = 100 (по умолчанию)

 
Условие 3 (условие на покупку). Если цена прошла xgrid пунктов вниз от цены открытия последней позиции на покупку, открыть позицию на покупку с Lotsize равным размеру лота предыдущей позиции Lotsize плюс LotIncrement.        

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

Это хороший совет — начинать любой проект с составления плана работы. И чем детальнее, тем лучше.

2. Создание коллекции сниппетов кода


Довольно часто одни и те же функции или классы используются в разных программах, советниках, индикаторах или скриптах. В таком случае очень удобно создать коллекцию кодов таких функций и использовать в проектах, а не создавать их каждый раз с нуля. Вот здесь пригодятся навыки объектно-ориентированного программирования (OOP).

На примере выше из плана видно, что в советнике нужно будет создать две функции: 

  1. Функция для подсчета позиций по типу
  2. Функция для получения цены открытия последней позиции по типу позиции

Такие функции используются почти в каждом сеточном советнике, поэтому можно создать include-файл (.mqh), назвать его, скажем gridmodule и хранить в нем эти функции. А из него эти функции можно подключать к основному файлу .mq5.

Что в gridmodule.mqh

//+------------------------------------------------------------------+
//|                                                  gridmodule.mqh |
//|                                     Copyright 2021, Omega Joctan |
//|                        https://www.mql5.com/en/users/omegajoctan |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Omega Joctan"
#property link      "https://www.mql5.com/en/users/omegajoctan"
//+------------------------------------------------------------------+
//| Libraries                                                        |
//+------------------------------------------------------------------+ 
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>

CSymbolInfo   m_symbol;
CPositionInfo m_position;
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
class CGrid
  {
   protected:
     int                   MagicNumber;
  
   public:
                           CGrid(void);
                          ~CGrid(void);
      void                 InitializeModule(int magic) { MagicNumber = magic; }
      double               LastPositionOpenPrice(ENUM_POSITION_TYPE type);
      int                  CountPositions(ENUM_POSITION_TYPE type);
   
  };
//+------------------------------------------------------------------+
//|               Constructor                                        |
//+------------------------------------------------------------------+
CGrid::CGrid(void)
 {
 
 }
//+------------------------------------------------------------------+
//|                Destructor                                        |
//+------------------------------------------------------------------+
CGrid :: ~CGrid(void)
 {
 
 }
//+------------------------------------------------------------------+
//|           Last Position Open Price By Position Type              |
//+------------------------------------------------------------------+
double CGrid::LastPositionOpenPrice(ENUM_POSITION_TYPE type)
 {
  double LastPrice = -1;
  ulong  LastTime = 0; 
   for (int i=PositionsTotal()-1; i>=0; i--)
     if (m_position.SelectByIndex(i))
       if (m_position.Magic() == MagicNumber && m_position.Symbol()==Symbol() && m_position.PositionType()==type)
          {
             ulong positionTime = m_position.TimeMsc();
             if ( positionTime > LastTime ) //FInd the latest position
               {
                  LastPrice = m_position.PriceOpen();
                  LastTime = m_position.TimeMsc();
               }
          }
       return LastPrice;
 }
//+------------------------------------------------------------------+
//|                Count Positions By Type                           |
//+------------------------------------------------------------------+
int CGrid::CountPositions(ENUM_POSITION_TYPE type)
 {
   int counter = 0; //variable to store our positions number
   for (int i=PositionsTotal()-1; i>=0; i--)
     if (m_position.SelectByIndex(i)) // Select position by its index
        if (m_position.Magic() == MagicNumber && m_position.Symbol() == Symbol() && m_position.PositionType() == type)
          {
            counter++; 
          }
      return counter;
 }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

Преимуществ у такого использования очень много. Например, это упростит отладку кода — у вас уже будут готовые отлаженные функции, а кода для отладки в основном файле .mq5 будет меньше.

3. Распорядок дня

Распорядок дня помогает мозгу настроиться на работу в нужное время и в целом повышает продуктивность. Кроме того, следуя распорядку, вы будете последовательно изо дня в день посвящать определенное время программированию.

Например, можно четко прописать часы работы: с 08:00 до 11:00 без перерыва.

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

Составьте удобное для себя расписание, по которому вы сможете работать.


4. Планирование дней интенсивной работы

В наше время так много отвлекающих моментов. Так сложно сосредоточиться на чем-то одном, особенно если это монотонная работа. Замечали, что всего несколько минут/часов в день получается быть гипер-сосредоточенным.

Иногда для решения каких-то моментов нужно именно такое состояние — сфокусироваться на работе и не отвлекаться ни на что другое. Для таких случаев нужно запланировать дни интенсивной работы.

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

5. Создание небольших функции и тестирование

Не стоит включать слишком много операций в одну функцию. Если программируете основные операции, лучше написать новую функцию, чем добавлять ее в существующую.

Так, если добавить кучу циклов в функцию Ontick (да и в любую другую важную или не очень функцию), проблем не избежать. Это как вытащить чеку из гранаты, которая лежит в кармане.

Разместить всю логику в одном месте и превратить простые алгоритмы в сложные — один из лучших способов получить ошибок, которые будут стоить вам денег и самого ценного ресурса в вашей жизни — времени.

Я верю, что программирование должно приносить удовольствие, чтобы не возникало желания все бросить. В запутанных алгоритмах нет ничего интересного, неважно насколько опытен или умен читатель такого кода. Пусть одна функция выполняет одно действие. Более того, пусть у каждой функции будет понятное и читаемое имя, из которого легко можно понять, что же она делает.

Посмотрим на функцию CountPositions с аргументом для типа позиции из предыдущего примера:

int CGrid::CountPositions(ENUM_POSITION_TYPE type)
 {
   int counter = 0; //variable to store our positions number
   for (int i=PositionsTotal()-1; i>=0; i--)
     if (m_position.SelectByIndex(i)) // Select position by its index
        if (m_position.Magic() == MagicNumber && m_position.Symbol() == Symbol() && m_position.PositionType() == type)
          {
            counter++; 
          }
      return counter;
 }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

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

6. Добавление комментариев для работы в будущем

Комментарии могут показаться незначительными — зачем тратить на них время? Но при правильном использовании они становятся просто жизненно необходимы.

input    group        "Money management"
input    double       InitialLots = 0.01; //Начальный объем позиции
input    int          EquityUse = 50;  // Процент резервных средств, которые не будут использоваться в торговле
input    group        "Average True Range";
input    int          AtrBarSignal = 1; //Расчет значения Atr на указанной свече

Через несколько недель или даже дней вы забудете большинство переменных, функций и фрагментов кода, над которыми работаете сейчас. Без осмысленных комментариев через некоторое время может быть сложно понять собственный код.

Добавляйте комментарии в код MQL5, а редактор кода MetaEditor поможет вспомнить, о чем он, когда вы вернетесь к этому коду в будущем.

Комментарии в MetaEditor

Вот такие подсказки будет давать редактор — очень удобно.

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

7. Слепая печать


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

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

Надо заставить себя отказаться от т.н. зрячей/двупальцевой печати (англ. hunt-and-peck) и приучать себя набирать код, не глядя на клавиатуру. Для этого нужно выработать мышечную память.

Не так просто освоить метод слепой печати, но пользы от нее очень много. Все дело в практике.

Лично мне понадобилось несколько недель практики на бесплатном сайте keybr.com. Это очень удобный сайт для тренировки, я рекомендую его всем, кто хочет научиться печатать, не глядя на клавиатуру.

8. Использование лучших инструментов 


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

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

9. Контроль версий


Бывало так, что вы писали программу, вносили изменения и после нескольких из них вы по какой-то причине хотите вернуться к коду, который вы писали ранее?

Очень важно вести контроль версий кода: помимо того, что в любой момент можно вернуться к любой из предыдущих версий, вы сможете следить за ходом работы.

Я знаю два способа. Первый — это использование Git, а второй — вручную копировать и вставлять методы хранения кода через текстовый файл.

Использование Git

Нет быстрого способа научить использовать гит, поэтому если вы не знакомы с Git и Github, рекомендую почитать документацию по гиту.

Использование текстового файла

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

Текстовый файл


После больших изменений файла .mq5, например, вы добавили новую функцию, создайте текстовый файл. В имени укажите версию кода и что было добавлено. Посмотрите пример на картинке

Контроль версий с текстовыми файлами

Можно открыть текстовый файл вместе с основным файлом .mq5 или .mqh и сохранить все одним нажатием CTRL+F7 - команда скомпилирует все файлы в редакторе. После компиляции ошибки, связанные с текстовым файлом, можно игнорировать - просто закройте файл.

Текстовый файл вместе с файлом mq5


Заключение

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

Спасибо за внимание!


Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/9923

Прикрепленные файлы |
gridmodule.mqh (3.58 KB)
Пишем глубокую нейронную сеть с нуля на языке MQL Пишем глубокую нейронную сеть с нуля на языке MQL
Статья познакомит вас с глубокой нейронной сетью, написанной на MQL, и с различными функциями активации этой сети, такими как функция гиперболического тангенса для скрытых слоев и Softmax для выходного слоя. Мы будем изучать нейросеть постепенно, двигаясь от первого шага до последнего, и вместе создадим глубокую нейронную сеть.
Работаем со временем (Часть 2): Функции Работаем со временем (Часть 2): Функции
Научимся автоматически распознавать смещения времени у брокера и время по Гринвичу. Вместо того, чтобы обращаться к брокеру, который скорее всего даст недостаточно полный ответ (а кто захочет объяснять, куда пропал торговый час?), мы сами посмотрим, по какому времени приходят от них котировки в те недели, когда переводят часы. Но конечно же, это мы будем делать не вручную — пусть за нас работает программа.
Графика в библиотеке DoEasy (Часть 93): Готовим функционал для создания составных графических объектов Графика в библиотеке DoEasy (Часть 93): Готовим функционал для создания составных графических объектов
В статье начнём разработку функционала для создания составных графических объектов. Наша библиотека будет поддерживать создание сложных составных графических объектов, в которых эти объекты смогут иметь любую иерархию связей. Подготовим все необходимые классы для последующей реализации таких объектов.
Как правильно выбирать советник в Маркете? Как правильно выбирать советник в Маркете?
В данной статье рассмотрим моменты, на которые следует обращать внимание при покупке советника в первую очередь. А также поищем способы повышения прибыли и, что самое, главное, как потратить деньги с умом и еще заработать на этом. Кроме того, после прочтения вы поймете, что заработать можно даже на простых и бесплатных продуктах.