АвторСообщение





Сообщение: 28
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 01.11.14 13:52. Заголовок: Инкапсулировать ли массивы?


Пишу по мере необходимости новые классы, в дополнение к уже существующим. Возник вопрос, которые я не совсем продумал видимо.
Имеется класс, в котором есть метод, которые ищет позиции, и возвращает количество позиции по типам и общее количество.
Переменную для общего количества я поместил в приватный отсек.
А количества позиции по типам у меня хранятся в массиве. Их в приватный отсек разве можно поместить? Ведь придётся вызывать через Get- массив по ссылке. Такое разве бывает?
И вообще имеет ли смысл подобные данные делать приватными для классов? Ведь, по сути, они нужны во многих местах кода...
Вот мой класс, в котором, на данный момент 1 метод. Очень услышать критику в отношении своего подхода.
Что-то в экспертах, в которых используется данный класс не передавать по всему коду через параметры количества позиций и в разных случая другую информацию, проще ж завести пременные в классе, где имеется метод, которые заполняет данные переменные. И в момент отработки данного метода, заполнить их, верно?
А потом вызывать их постоянно, когда нужно из класса...

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 11 [только новые]







Сообщение: 904
Зарегистрирован: 03.03.13
Откуда: Украина, Днепродзержинск
Репутация: 2
ссылка на сообщение  Отправлено: 02.11.14 14:45. Заголовок: По большому счету по..


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

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 30
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 02.11.14 15:30. Заголовок: Игорь, я это и имел ..


Игорь, я это и имел ввиду. Функция поиска позиций это и есть один из методов класса, который будет нужен для сбора некоторой информации ордера На данный момент там 1 функция, но это не означает, что так будет всегда. Специального класса именно для поиска позиций заводить я и не собирался. Вопрос другой.
Кстати, вот эта функция:

Скрытый текст


Количество позиций каждого типа она возвращает через массив, который в параметрах данного метода. А так данный метод возвращает общее количество позиций.
Суть в том, что я думаю, может быть было б логично, чтоб не вызывать каждый раз когда нужно узнать количество каких-либо позиций, (например, на каждом тике,) завести в секторе private данного класса переменную OTotal( для хранения общего количества ордеров всех типов ) и массив AmountPosByType[], который хранит количесто ордеров по типам, который попадает через параметры в метод FindPositions (int& fia_AmountPosByType[]). Это логично, или нет?
Тут загвоздка, что придётся обращаться через Get., а значения помещать через Set. Вот и думаю, наверное это не совсем приемлимый вариант.
Просто бывает так, что поиск позиций, если не хранится где-то, и доступ есть у всего кода к этому месту, нужно вызвать в разных местах. Например, в функциях открытия позиции, модификации отложек, модификации рыночных ордеров, функции получающей сигнал и других. Вот я и подумал, грамотно ли вызывать функцию постоянно, или всё же как-то иначе вопрос решить. Понимаете о чём я?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 908
Зарегистрирован: 03.03.13
Откуда: Украина, Днепродзержинск
Репутация: 2
ссылка на сообщение  Отправлено: 02.11.14 15:57. Заголовок: В свое время тоже му..


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

В общих чертах программа разбивается на такие блоки:
1. Определение торгового критерия. К примеру, в советнике, работающем по пересечению МАшек, это простая функция, выдающая сигнал покупки при пересечении вверх, и сигнал продажи при пересечении вниз. В остальное время - нет сигнала.
2. Обработка текущих ордеров/позиций. Здесь и должна находиться функция поиска ордеров. Этот блок на основании своего алгоритма работы с ордерами и с учетом сигналов от блока 1 формирует торговый запрос. На примере МАшек:
    2.1. Если есть сигнал покупки и нет своих рыночных ордеров, то формируется запрос Buy с соответствующими параметрами.
    2.2. Если есть сигнал покупки и существует ордер Buy, то формируется запрос на модификацию ордера с соответствующими параметрами.
    2.3. Если есть сигнал покупки и существует ордер Sell, то формируется запрос на закрытие ордера с соответствующими параметрами. На следующей итерации после закрытия ордера ситуация будет как в п. 2.1
    2.4. Если есть сигнал продажи и нет своих рыночных ордеров, то формируется запрос Sell с соответствующими параметрами.
    2.5. Если есть сигнал покупки и существует ордер Sell, то формируется запрос на модификацию ордера с соответствующими параметрами.
    2.6. Если есть сигнал покупки и существует ордер Buy, то формируется запрос на закрытие ордера с соответствующими параметрами. На следующей итерации после закрытия ордера ситуация будет как в п. 2.4

3. Выполнение торгового запроса. Это как раз то место, где выполняются OrderSend, OrderClose и т. п. Этот блок знает только параметры запроса и состояние рыночного окружения, переданные ему, не больше.

При такой структуре советника не возникает необходимость в Get-методах для того, чтобы получить список ордеров. Все данные хранятся и обрабатываются одним и тем же классом.
В моих советниках описанная структура представлЕна классами:
1. CalculateTradeType - обработка торговых сигналов, поиск своих ордеров и обработка этих ордеров с последующей выдачей торгового запроса.
2. CalculateSignal - вычисление торгового критерия. Класс CalculateTradeType получает текущий сигнал у этого класса через Get-метод.
3. Trade - обработка торгового запроса, сформированного классом CalculateTradeType.

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 36
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 15.11.14 20:38. Заголовок: Scriptong пишет: Пр..


Scriptong пишет:

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


Тогда зачем у Вас в классе GetSymbolInfo методы Get ? Ведь если данные переменные хранятся и используются только внутри данного класс, то это излишнее...

И вот ещё что. Я смотри Ваш советник VPMA, и, хочу всё-таки понять, как всё там работает, в плане структуры данных. Вот есть момент такой:

SymbolInfo allSymbolInfo = m_symbolInfo.GetAllSymbolInfo();

Это значит, что создаётся объект allSymbolInfo структуры SymbolInfo, в который заносятся данный, в тот момент, когда отрабатывается метода m_symbolInfo.GetAllSymbolInfo(), верно?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 35
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 15.11.14 18:42. Заголовок: Я вот заглянул в кла..


Я вот заглянул в класс GetSymbolInfo, который в файле Common_GetSymbolInfo.mqh, и, обнаружил, что там, в класс GetSymbolInfo в приватной секции помещены 3 члана:

m_symbol,
m_slippage,
SymbolInfo m_symbolInfo;

Почему переменные m_symbol и m_slippage не вошли в структуру SymbolInfo ?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 957
Зарегистрирован: 03.03.13
Откуда: Украина, Днепродзержинск
Репутация: 2
ссылка на сообщение  Отправлено: 15.11.14 22:07. Заголовок: hoz пишет: Я вот за..


hoz пишет:

 цитата:
Я вот заглянул в класс GetSymbolInfo, который в файле Common_GetSymbolInfo.mqh, и, обнаружил, что там, в класс GetSymbolInfo в приватной секции помещены 3 члана:

m_symbol,
m_slippage,
SymbolInfo m_symbolInfo;

Почему переменные m_symbol и m_slippage не вошли в структуру SymbolInfo ?


Никаких принципиальных ограничений для этого нет (кроме одного небольшого - о нем ниже). Есть лишь логика. Структура SymbolInfo - это описание некоторого символа. Предполагается, что тот, кто делает запрос, уже знает имя символа. Так зачем же в таком случае возвращать ему избыточную информацию, дублируя то, что известно запрашивающей стороне? Для тех редких случаев, когда запрашивающая сторона не знает имя символа, соответствующий метод (GetSymbol) вынесен отдельно.
Подобная логика и с членом slippage. Эта информация была передана на этапе создания класса. Значит, тот кто создавал этот объект, уже владеет такими данными. Зачем передавать создателю ту информацию, которой он и без того владеет? Создателя в этом случае интересует информация, являющаяся "добычей" класса - данные о символе. И, опять же, для случая, когда данные будет запрашивать не создатель класса, а кто-то другой, предусмотрен отдельный метод, который предоставляет подобную информацию.

hoz пишет:

 цитата:
Тогда зачем у Вас в классе GetSymbolInfo методы Get ? Ведь если данные переменные хранятся и используются только внутри данного класс, то это излишнее...


С чего Вы взяли, что данные используются только внутри класса? Если таким данным соответствует метод Get, то это автоматически означает, что значения каких-то членов класса используется кем-то снаружи. Другое дело, что изменить значения приватных членов класса этот кто-то снаружи не может. Таким образом, гарантируется целостность данных.

hoz пишет:

 цитата:
Это значит, что создаётся объект allSymbolInfo структуры SymbolInfo, в который заносятся данный, в тот момент, когда отрабатывается метода m_symbolInfo.GetAllSymbolInfo(), верно?


Абсолютно верно.
Кстати, в этом примере продемонстрирован еще один ответ на вопрос о том, почему в структуру SymbolInfo не было внесено имя символа. Имя символа - строковый тип данных, который относится к сложным типам. А наличие сложных типов данных в структурах MQL4 автоматически запрещает прямое копирование структур.

Спасибо: 1 
ПрофильЦитата Ответить





Сообщение: 37
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 16.11.14 15:07. Заголовок: Игорь, смотрю я на т..


Игорь, смотрю я на тот же эксперт VPMAExtremum_Expert, и, одного не понимаю. Ведь у Вас классы, объявленные на глобальном уровне т.е. g_symbolInfo, g_trade и g_calcTradeType создаются в функции OnInit() т.е. на момент начала работы эксперта, например, для g_symbolInfo вот:

g_symbolInfo = new GetSymbolInfo(Symbol(), i_slippage);
if (g_symbolInfo == NULL)
{
Alert(WindowExpertName(), ": невозможно инициализировать класс GetSymbolInfo. Эксперт выключен!");
return false;
}

А удаляются в OnInit(), т.е. по окончанию работы эксперта. Отсюда логика такая, что динамическое выделение памяти тут не резонно т.е. данные классы не выгружаются на протяжении работы программы до момента прекращения работы. Ведь так? Тогда зачем здесь создавать объекты динамически?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 38
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 16.11.14 15:32. Заголовок: Игорь, смотрю я на В..


Игорь, смотрю я на Ваш метод GetAllSymbolInfo(void) класса GetSymbolInfo уже минут 30 и не понимаю его сути. Точнее понимаю, но как-то не уверенно, и, не в курсе, где про это можно прочитать.
Вот он:

//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Получение данных по символу в виде структуры |
//+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
SymbolInfo GetSymbolInfo::GetAllSymbolInfo(void) const
{
return m_symbolInfo;
}

Подскажите, как это правильно интерпретировать?

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 963
Зарегистрирован: 03.03.13
Откуда: Украина, Днепродзержинск
Репутация: 3
ссылка на сообщение  Отправлено: 16.11.14 16:25. Заголовок: hoz пишет: Игорь, с..


hoz пишет:

 цитата:
Игорь, смотрю я на тот же эксперт VPMAExtremum_Expert, и, одного не понимаю. Ведь у Вас классы, объявленные на глобальном уровне т.е. g_symbolInfo, g_trade и g_calcTradeType создаются в функции OnInit() т.е. на момент начала работы эксперта, например, для g_symbolInfo вот:

g_symbolInfo = new GetSymbolInfo(Symbol(), i_slippage);
if (g_symbolInfo == NULL)
{
Alert(WindowExpertName(), ": невозможно инициализировать класс GetSymbolInfo. Эксперт выключен!");
return false;
}

А удаляются в OnInit(), т.е. по окончанию работы эксперта. Отсюда логика такая, что динамическое выделение памяти тут не резонно т.е. данные классы не выгружаются на протяжении работы программы до момента прекращения работы. Ведь так? Тогда зачем здесь создавать объекты динамически?


В данном конкретном случае резона, действительно, нет. Вполне можно было бы обойтись и без динамического создания. Это настолько мелочная проблема, что она не рассматривалась в рамках именно этого эксперта. Был взят общий подход, который используется при конструировании эксперта. В этом подходе учитывается тот факт, что эксперт может оперировать несколькими символами, для каждого из которых создается свой экземпляр класса GetSymbolInfo. А когда нам заранее неизвестно, сколько символов будет использоваться при анализе, то и без динамического создания не обойтись. С другой стороны делать кучу статических объектов "про запас" - нерационально и чревато ограничениями.

hoz пишет:

 цитата:
Подскажите, как это правильно интерпретировать?


Это стандартный способ получения данных класса. Есть структура SymbolInfo. Нам нужно получить копию этой структуры. Класс GetSymbolInfo содержит значения структуры SymbolInfo в члене m_symbolInfo. Содержимое члена m_symbolInfo возвращает метод GetAllSymbolInfo.
Ведь это то же самое, что написать:

 цитата:
class classA
{
int m_value;
public:
int GetValue()
{
return m_value;
}
};


Здесь возвращается значение члена класса m_value, который имеет тип int. Ну а SymbolInfo - это такой же тип данных, как и int, только пользовательский, а не стандартный.

Спасибо: 1 
ПрофильЦитата Ответить





Сообщение: 39
Зарегистрирован: 30.05.13
Репутация: 0
ссылка на сообщение  Отправлено: 18.11.14 19:30. Заголовок: Scriptong пишет: В..


Scriptong пишет:

 цитата:
В этом подходе учитывается тот факт, что эксперт может оперировать несколькими символами, для каждого из которых создается свой экземпляр класса GetSymbolInfo


Мне вот интересно. Как это будет выглядеть? Имею ввиду, если эксперт будет оперировать не одним инструментом. Ведь всё-равно динамические объекты должны идентифицироваться как-то один от другого.

Scriptong пишет:

 цитата:
С другой стороны делать кучу статических объектов "про запас" - нерационально и чревато ограничениями.


Касательно, ограничений. Имеете ввиду, что все варианты инструментов( или ещё каких-то других возможных вариантов программы ) не прописать? Т.е. как вариант будут лишниеварианты, которые про запас висеть в памяти, а другие, наоборот, не создадутся нужные, так? Или что-то ещё?
Scriptong пишет:

 цитата:
Здесь возвращается значение члена класса m_value, который имеет тип int. Ну а SymbolInfo - это такой же тип данных, как и int, только пользовательский, а не стандартный.


Теперь понял. Но как-то всё это воспринимается дико...

Спасибо: 0 
ПрофильЦитата Ответить





Сообщение: 973
Зарегистрирован: 03.03.13
Откуда: Украина, Днепродзержинск
Репутация: 3
ссылка на сообщение  Отправлено: 18.11.14 21:20. Заголовок: hoz пишет: Мне вот ..


hoz пишет:

 цитата:
Мне вот интересно. Как это будет выглядеть? Имею ввиду, если эксперт будет оперировать не одним инструментом. Ведь всё-равно динамические объекты должны идентифицироваться как-то один от другого.


Простой массив:

 цитата:

GetSymbolInfo *g_symbolInfo[];

int OnInit()
{
ArrayResize(g_symbolInfo, /*количество используемых символов*/);
}



hoz пишет:

 цитата:
Касательно, ограничений. Имеете ввиду, что все варианты инструментов( или ещё каких-то других возможных вариантов программы ) не прописать?


Я имел в виду, что заменой массиву, который я указал выше, является только такой подход:

 цитата:
GetSymbolInfo g_symbolInfo1;
GetSymbolInfo g_symbolInfo2;
GetSymbolInfo g_symbolInfo3;
...
GetSymbolInfo g_symbolInfoN;


То есть будет ограничение в N символов. Более того, в коде будет слишком сложно оперировать этими переменными, т. к. к ним нельзя обратиться по индексу элемента массива. Будет ненужная куча swicth или if. Ну и, конечно же, лишние объекты будут просто висеть в памяти, бесполезно ее занимая, если символов у нас менее, чем N.
В варианте с массивом мы всегда будем выделять ровно столько памяти, сколько нужно, ни байтом больше.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  2 час. Хитов сегодня: 1
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет