Проблемы с закрытием, пожалуйста, помогите - страница 5

 

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

Пример:

// < Структура 17 элементов в 4 доменах > //< >
// < 1. Данные 8 элементов в 2 доменах /> //< >
// < 2. Код 9 элементов в 2 доменах /> //< >
// </ Структура 17 элементов в 4 доменах > //< >
// //< >
// < 1. Данные 8 = 5 i 3 d - s > //< >
// < 1.1. Вход 7 = 4 i 3 d - s /> //< >
// < 1.2. Буфер 1 = 1 i - d - s /> //< > //< >
// </1. Данные 8 = 5 i 3 d - s > //< >
// //< >

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

Еще раз спасибо. Я буду изучать программу, и у меня будет больше вопросов в самом ближайшем будущем.
Будь здоров

 

Здравствуйте, Гекльберри

Рад вас слышать.


1. Структура

Структура разработана и отформатирована мной самостоятельно.

//                                                                //<          >
// < Structure             16 elements  in      4 domains       > //<          >
// < 1. Data                7 elements  in      2 domains      /> //<          >
// < 2. Code                9 elements  in      2 domains      /> //<          >
// </Structure             16 elements  in      4 domains       > //<          >
//                                                                //<          >
     

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


2. Форматирование

Форматирование - это простой HTML.
Следующий тег открывает часть программы:

// <                                                            > //<          >
      


Следующий тег закрывает часть программы:

// </                                                           > //<          >
      


Следующий тег используется для частей программы в одну строку:

// <                                                           /> //<          >
      

Завершающая часть тега сейчас используется для подсчета страниц.
В будущем использование этой части тегов может быть расширено.

                                                                  //<          >
      

Структура страниц помогает легко ориентироваться в программе.
Используя <Page Up> и <Page Down>, я всегда вижу одни и те же типы тегов на одних и тех же местах.



3. Элементы

Элемент данных - это одна глобальная переменная.
Я также вижу массив как единственный элемент.
Локальные переменные - это просто временные сущности элементов кода.

Элемент кода - это одна функция.
Также я могу использовать слово "метод".
Я использую слово "интерфейс" для объединенного набора функций.

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

Для контроля целостности элементов данных и элементов кода используется подсчет.


//                                                                //<          >
// < 1. Data                7 =       4 i       3 d       - s   > //<          >
// < 1.1. Input             7 =       4 i       3 d       - s  /> //<          >
// < 1.2. Buffer            - =       - i       - d       - s  /> //<          >
// </1. Data                7 =       4 i       3 d       - s   > //<          >
//                                                                //<          >
// < 2. Code                9 /       - i      82 l       4 o   > //<          >
// < 2.1. Interface         6 /       - i      71 l       4 o  /> //<          >
// < 2.2. Special           3 /       - i      11 l       - o  /> //<          >
// </2. Code                9 /       - i      82 l       4 o   > //<          >
//                                                                //<          >
     

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

Для контроля целостности данных используется следующая нотация.
Количество элементов данных "integer" обозначается как "i".
Количество элементов данных "double" обозначается как "d".
Количество элементов данных "строка" обозначается как "s".
Левый столбец содержит сумму строки "i" + "d" + "s".

Для контроля целостности кода используется следующая нотация.
Количество входов функции, то есть количество аргументов функции, обозначается как "i".
Количество открытых строк кода обозначается как "l".
Количество выходов функции обозначается как "o".
Всегда "1" для единственной функции, возвращающей любое значение, и "-" во всех остальных случаях.
Левая колонка содержит количество функций в домене.


4. Домены

Это заголовки доменов.
.

////////////////////////////////////////////////////////////////////<         2>
// < 1.1. Data : Input >                                          //<          >
//                                                                //<          >
// < 1.1. Input             7 =       4 i       3 d       - s   > //<          >
// <      1. Strategy       4 =       2 i       2 d       - s  /> //<          >
// <      2. Trading        3 =       2 i       1 d       - s  /> //<          >
// </1.1. Input             7 =       4 i       3 d       - s   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<         3>
// < 1.2. Data : Buffer >                                         //<          >
//                                                                //<          >
// < 1.2. Buffer            - =       - i       - d       - s   > //<          >
// </1.2. Buffer            - =       - i       - d       - s   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<         4>
// < 2.1. Code : Interface >                                      //<          >
//                                                                //<          >
// < 2.1. Interface         6 /       - i      71 l       4 o   > //<          >
// <      1. iNewBar                  - i       4 l       1 o  /> //<          >
// <      2. iSignalOpen              - i      15 l       1 o  /> //<          >
// <      3. iSignalClose             - i      15 l       1 o  /> //<          >
// <      4. iGetTicket               - i       7 l       1 o  /> //<          >
// <      5. iTryOpen                 - i      15 l       - o  /> //<          >
// <      6. iTryClose                - i      15 l       - o  /> //<          >
// </2.1. Interface         6 /       - i      71 l       4 o   > //<          >
//                                                                //<          >
     
////////////////////////////////////////////////////////////////////<        11>
// < 2.2. Code : Special >                                        //<          >
//                                                                //<          >
// < 2.2. Special           3 /       - i      11 l       - o   > //<          >
// <      1. init                     - i       1 l       - o  /> //<          >
// <      2. deinit                   - i       1 l       - o  /> //<          >
// <      3. start                    - i       9 l       - o  /> //<          >
// </2.2. Special           3 /       - i      11 l       - o   > //<          >
//                                                                //<          >
     


Правила и обозначения для подсчета такие же, как и для заголовка программы.
Я просто копирую открывающие теги заголовков доменов в заголовок программы.

Каждая страница в домене имеет открывающий и закрывающий теги.
Например:

////////////////////////////////////////////////////////////////////<        12>
// < 2.2.1. Code : Special : Init >                               //<          >
..
// </2.2.1. Code : Special : Init >                               //<          >
     

Ведущие числа используются для подсчета и навигации по частям структуры.
Затем следует обозначение части программы "Данные" или "Код".
Затем следует имя домена.
Затем следует имя элемента домена.


Надеюсь, это может помочь.

До свидания и жду вашего ответа
.

 

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

 

Здравствуйте, Айс,,,,,,,,,<это было отредактировано>
Программа еще не усвоена. Извините, что она отнимает у вас так много времени. Есть область, которую я, должно быть, пропустил,
потому что я столкнулся с одной ошибкой.
Я должен идти, но вернусь завтра.
Пока.

 

Hello Huckleberry
Некоторые функции были добавлены для примера и могут быть легко изменены или удалены.
Улучшение программы - это постоянный процесс.
Пока
:)

 
Ais wrote >>

Hello Huckleberry
Некоторые функции были добавлены для примера и могут быть легко изменены или удалены.
Улучшение программы - это постоянный процесс.
Пока
:)


Здравствуйте Ais
Спасибо за все, что вы сделали.
Вчера вечером я наконец-то нашел свою ошибку, когда копировал вашу программу.
В настоящее время я пытаюсь понять, для чего нужны некоторые переменные и как они работают.
В iSignalClose я вставляю часть моей другой программы, чтобы установить OrderClosePrice. С помощью
Ваше предложение:

dDelta = OrderOpenPrice () - OrderClosePrice ().

программа становится более гибкой.
Вернусь с новыми вопросами. И комментариями.
Ваше здоровье
 

Здравствуйте Ais
Возникли вопросы. В вашей программе указано ..... iTryOpen ().

else if     ( iCommand       == OP_BUY )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else         
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;           

Из моего любопытства, должно ли быть

else if     ( iCommand       == OP_BUY  )
   {          
string        sType           = "Buy"   ;   
int           iColor          =  Blue   ;               }
else if     ( iCommand       == OP_SELL )   // Was this ommitted     
   {          sType           = "Sell"  ;    
              iColor          =  Red    ;               }
Вот еще один вопрос для лучшего понимания
// < 2.1.1. Code : Interface : iNewBar >                          //<          >
int       iNewBar ()         //       - i       4 l       1 o     //<          >
{                                                                 //<          >
static    int       iTime_0 = 0                                 ; //<          >
//                                                                //<          >
if      ( iTime_0 < iTime   ( 0 , 0 , 0 ) )                       //<          >
        { iTime_0 = iTime   ( 0 , 0 , 0 ) ;  return ( TRUE  ) ; } //<          >
else    {                                    return ( EMPTY ) ; } //<          >
//                                                  
Если iNewBar равен TRUE, то управление передается iSignalOpen. Если iNewBar равен TRUE (равен текущему бару??), ИЛИ iFirstRun ==1, то iFirstBar = 0. Это запутано только потому, что я не понимаю определение iNewBar () и/или определение iFirstRun. Я вижу, где iFirstRun разлагается и инициализируется, но что это значит.
Извините, что гружу вас такими простыми вопросами. Я не могу вычислить или увидеть, как эти два элемента работают в функции. Когда у вас будет время, не могли бы вы прояснить это, пожалуйста.
Еще раз спасибо за ваши усилия : )
Спасибо
 

Привет, Гекльберри

Оба вопроса важны!

Ответ 1.

Оба условия верны, но если:
1.1. мы знаем, что

int       iCommand          = iSignalOpen ()                    ; //<          >
     

1.2. мы знаем, что "iSignalOpen ()" может вернуть только 3 возможных значения: "EMPTY", "OP_BUY" и "OP_SELL";
1.3. первое значение уже проверено

if      ( iCommand         == EMPTY  )                return    ; //<          >
     

1.4. второе значение также проверяется

if      ( iCommand         == OP_BUY )                            //<          >
     

то можно опустить последнюю проверку "if", чтобы немного ускорить вычисления.

else if     ( iCommand       == OP_SELL )                    //<          >
     


Ответ 2.

2.1. Мы узнаем, что бар номер 0 изменен, сравнивая время открытия бара номер 0 с последним сохраненным временем открытия бара номер 0.
"iTime ( 0, 0, 0 )" возвращает время открытия текущего неполного бара.
Индекс текущего бара всегда 0, это третье значение в "iTime ( 0, 0, 0 )".
Объявление переменной "int iTime_0" как "статической" означает, что значение этой переменной сохраняется между вызовами функции.
Каждый раз, когда время открытия изменяется, мы:
2.1.1. присваиваем "iTime_0 = iTime ( 0, 0, 0 ) ;" для хранения времени открытия текущего бара;
2.1.2. возвращаем "TRUE", что означает, что текущий бар - это новый бар, последний бар номер 0 стал баром номер 1.


////////////////////////////////////////////////////////////////////<         5>
// < 2.1.1. Code : Interface : iNewBar >                          //<          >
int       iNewBar ()         //       - i       4 l       1 o     //<          >
{                                                                 //<          >
static    int       iTime_0 = 0                                 ; //<          >
//                                                                //<          >
if      ( iTime_0 < iTime   ( 0 , 0 , 0 ) )                       //<          >
        { iTime_0 = iTime   ( 0 , 0 , 0 ) ;  return ( TRUE  ) ; } //<          >
else    {                                    return ( EMPTY ) ; } //<          >
}                                                                 //<          >
// </2.1.1. Code : Interface : iNewBar >                          //<          >
     

2.2. Наш начальный бар для вычисления "dHigh" и "dLow" в "iSignalOpen ()", и "dATR" в "iSignalClose ()", это "iBaseBar=1".
Поскольку бар номер 1 один и тот же, эти значения одинаковы.
Это повод вычислять эти значения только на новых барах.
Это ускоряет работу программы.
Переменная "static int iFirstRun" является простым триггером.
Начальное значение "1" заставляет вычислять "dHigh", "dLow" и "dATR" при первом запуске программы, независимо от любого условия.
Это повышает надежность программы.

<добавлено позже>
Именно, при первом запуске программы "iNewBar ()" в "iSignalOpen ()" возвращает "TRUE", а в "iSignalClose" возвращает "EMPTY"!
Это происходит потому, что при первом вызове "iNewBar ()", то есть внутри первого запуска "iSignalOpen ()", значение "iTime_0 = 0", а при втором вызове "iNewBar ()", то есть внутри первого выполнения "iSignalClose ()", "iTime_0 = iTime ( 0, 0, 0 )"!
В результате без первого прогона управление может быть "dATR = 0".
Таков первый прогон.
<

Сразу после этого присваиваем "iFirstRun = 0" и следующее условие будет истинным только на новых барах:

if    ( ( iNewBar () == TRUE )   ||   ( iFirstRun  == 1 ) )       //<          >
     

Но!
Остатки кода "iSignalOpen ()" и "iSignalClose ()" выполняются на каждом тике!
Пропускаются только вычисления неизменных значений.

////////////////////////////////////////////////////////////////////<         6>
// < 2.1.2. Code : Interface : iSignalOpen >                      //<          >
int       iSignalOpen ()     //       - i      15 l       1 o     //<          >
{                                                                 //<          >
static    int                           iFirstRun   = 1         ; //<          >
if    ( ( iNewBar () == TRUE )   ||   ( iFirstRun  == 1 ) )       //<          >
        {                               iFirstRun   = 0         ; //<          >
          int iIndexH = iHighest      ( 0 , 0    , MODE_HIGH  ,   //<          >
                                        iBaseLag , iBaseBar   ) ; //<          >
          int iIndexL = iLowest       ( 0 , 0    , MODE_LOW   ,   //<          >
                                        iBaseLag , iBaseBar   ) ; //<          >
          static double dHigh ; dHigh = High     [ iIndexH    ] ; //<          >
          static double dLow  ; dLow  = Low      [ iIndexL    ] ; //<          >
        } // if                                                   //<          >
//                                                                //<          >
double    dAsk    = MarketInfo        ( Symbol () , MODE_ASK  ) ; //<          >
if      ( dAsk    > dHigh )             return    ( OP_BUY    ) ; //<          >
//                                                                //<          >
double    dBid    = MarketInfo        ( Symbol () , MODE_BID  ) ; //<          >
if      ( dBid    < dLow  )             return    ( OP_SELL   ) ; //<          >
//                                                                //<          >
                                        return    ( EMPTY     ) ; //<          >
}                                                                 //<          >
// </2.1.2. Code : Interface : iSignalOpen >                      //<          >
     


Надеюсь, это может помочь.
Будьте здоровы!
:)

P.S. Некоторые замечания добавлены позже.
И, глядя на эти замечания, очевидно, что "iNewBar ()" должен быть исправлен.
Это потому, что эта функция вызывается дважды для проверки одного события.
Теперь для одного и того же события при первом вызове "iNewBar ()" возвращает правильное значение, а при втором возвращает неправильное значение.
Будет исправлено.



 

Здравствуйте, Ais
Спасибо за разъяснения. Я продолжу читать дальше. У меня пока нет полного представления о коде.
Но вы упомянули, что есть что-то, что должно быть исправлено в отношении iNewBar? Я не уверен, что iNewBar виноват в проблеме, которую выявил бэктест. Возможны две проблемы?
Вот что я увидел, когда открыл график после бэктеста. Мы знаем, что вход на покупку происходит, когда Ask находится выше самого высокого максимума за последние двадцать баров. Вход на продажу - наоборот. Однако входы не являются последовательными. Это та область, которую вы видели?
Нашел еще одну вещь. Жесткий стоп рассчитывается Atr*2. Это правильно, но я не вижу, где это вычисляется. Но настоящая проблема в том, что TakeProfit имеет тот же самый расчет Atr*2. Если бы я знал, где рассчитывается Hard Stop, я мог бы, возможно, исправить TakeProfit. TakeProfit в этом случае должен быть только Atr*1.
Всего доброго, и я вернусь завтра.
Спасибо

 

Привет Гекльберри

Условие TakeProfit было придумано мной самостоятельно в тестовых целях.
Теперь оно изменено.
Вместо "Atr*2" и "Atr*1" я использую "dATR * dFactorTP" и "dATR * dFactorSL".
Начальные значения "dFactorTP = 1.0" и "dFactorSL = 2.0" находятся на странице 2 "Данные : Input".
Такое решение позволяет легко оптимизировать эти значения.

Я изменил функции "iSignalOpen ()" и "iSignalClose ()".
Проверка нового бара теперь реализована в этих функциях.
Условия для "Buy" и "Sell" в "iSignalOpen ()" кажутся, вероятно, правильными.

Полная программа находится в прикрепленном файле на следующей странице.

Будьте здоровы
.