Комментарии и предложения

Комментарии и предложения
Atom
3/11/2011
skuvv


Заметил пару нюансов по PlazaTrader: 1)


_plazaStreamManager = new PlazaStreamManager(_plazaConnectionPool, TRequestType.RT_COMBINED_DYNAMIC, 1000);

Почему рекваест тайп фиксированный? надо конкретно задавать, например у меня так было:

"FORTS_FUTAGGR20_REPL" - RT_REMOTE_ONLINE "FORTS_FUTTRADE_REPL" - RT_REMOTE_ONLINE "FORTS_FUTINFO_REPL" - RT_COMBINED_DYNAMIC "FORTS_FUTCOMMON_REPL" - RT_REMOTE_ONLINE "FORTS_POS_REPL" - RT_COMBINED_DYNAMIC "FORTS_PART_REPL" - RT_COMBINED_DYNAMIC "FORTS_VM_REPL" - RT_COMBINED_DYNAMIC Допустим если FORTS_FUTCOMMON_REPL задать в RT_COMBINED_DYNAMIC, то при реконнекте будет перекачиваться весь поток заново. +Revision тоже надо указывать в некоторых потоках.

  1. в PlazaStreamManager void Run() Не обрабатывает состояния типа DS_STATE_ERROR или DS_STATE_CLOSE, те в случае чего будет затык и поток будет висеть закрытым или с ошибкой. Я для себя брал реализацию с примера(могу выложить если что) PS У меня несколько сместились приоритеты - придется задержаться на квике, но постораюсь не пропадать.

Tags:


Thanks:


< 1 2 3 4 5  > >>
Mikhail Sukhov

Avatar
Date: 3/26/2011
Reply


aspirant: Dictionary отсортировал бы свои элементы по алфавиту (ключи ведь string).

Ты путаешь с SortedDictionary. И то там не по алфавиту... Это хеш алгоритм. Там сортировка не нужна. Группировка значения идет по хэшу ключа. Соответственно, когда обращаемся по ключу, сначала берется его хэш (PlazaColumn.GetHashCode) и получаются все значения, соответствующие хэшу. Операция O(1). И далее, если у нас коллизия, перебором всех ключей идет сравнение (PlazaColumn.Equals) и находится первый попавшийся (ага, уникальность там не проверяется).

Итого, в лучшем варианте O(1). В худшем O(n). Но чтобы добиться последнее, надо еще постараться.[smile]

Thanks:

aspirant

Avatar
Date: 3/26/2011
Reply


Mikhail Sukhov:

aspirant: Dictionary отсортировал бы свои элементы по алфавиту (ключи ведь string).

Ты путаешь с SortedDictionary. И то там не по алфавиту... Это хеш алгоритм. Там сортировка не нужна. Группировка значения идет по хэшу ключа. Соответственно, когда обращаемся по ключу, сначала берется его хэш (PlazaColumn.GetHashCode) и получаются все значения, соответствующие хэшу. Операция O(1). И далее, если у нас коллизия, перебором всех ключей идет сравнение (PlazaColumn.Equals) и находится первый попавшийся (ага, уникальность там не проверяется).

Итого, в лучшем варианте O(1). В худшем O(n). Но чтобы добиться последнее, надо еще постараться.[smile]

Да, насчет сортировки я был не прав.

Thanks:

Mikhail Sukhov

Avatar
Date: 3/26/2011
Reply


aspirant: Я изменил класс PlazaListener. Посмотри, пожалуйста, нужны твои комментарии + желательно кусок псевдокода - твое видение, как пользователь создает таблицу с набором колонок для передачи ее в PlazaListener.

Посмотрел и доделал кое-что.

Рассмешило название PlazaPartColumns. Долго думал, что за "часть". Оказалось, это Партфэл, дарагой!

Что осталось до переделать:

  1. Сейчас PlazaListener создается в самом начале со всеми колонками. Как я уже писал, использовать надо только те колонки, что определены схемами PlazaTable.Columns.
  2. PlazaListener выглядит как лишний класс (возможно, что в него потом будет засунута еще какая-то логика, если да, то какая?). Что он делает сейчас. Берет данные из PlazaStream и передает их в PlazaTrader. Тоесть, такой бюрократически посредник, который бумажки из стола на стол несет.
  3. enum TableName лучше сделать статическим классом со строковыми константами. Я так понял, такие безобразные названия нужны лишь для того, чтобы ini файлы создавать? Если да, то по логике простой. Мы создаем текстовый файл, используем string. Вся логика в имени полей TableName - приведение в string... Так может тогда сразу сделать string?
  4. Давайте подумаем насчет фильтрации. Сейчас это выглядит как то не очень. Аспирант, ты же вроде как уже что-то делал по фильтрам?
  5. PlazaSchemaParser предлагаю упрятать в PlazaTableSerializer.
Thanks:

skuvv

Avatar
Date: 3/26/2011
Reply


aspirant:

skuvv: К примеру я сравнил проект со своей старой программой plaza2, данные в текущий s# проект поступают медленнее на 6-10мс(время снимал с OnNewSecurityChanged к примеру).

Получается, ты делал свою реализацию PlazaTrader? Нет у меня не интерфейс как в s#, а напрямую работа c потоками и событиями

Thanks:

Mikhail Sukhov

Avatar
Date: 3/26/2011
Reply


skuvv:

aspirant:

skuvv: К примеру я сравнил проект со своей старой программой plaza2, данные в текущий s# проект поступают медленнее на 6-10мс(время снимал с OnNewSecurityChanged к примеру).

Получается, ты делал свою реализацию PlazaTrader? Нет у меня не интерфейс как в s#, а напрямую работа c потоками и событиями

Может выложить это ввиде отдельного теста для сравнения перфоманса? Насчет OnNewSecurityChanged - конечно. Если вместо поиска по словарю устраивать Exist Find и т.д., то я не удивлюсь и пол минутными задержками.[smile]

Thanks:

aspirant

Avatar
Date: 3/26/2011
Reply


Mikhail Sukhov: Сейчас PlazaListener создается в самом начале со всеми колонками. Как я уже писал, использовать надо только те колонки, что определены схемами PlazaTable.Columns. Как клиентский код создает таблицу с колонками и схемами? Твое видение с куском кода.

Mikhail Sukhov: enum TableName лучше сделать статическим классом со строковыми константами. Я так понял, такие безобразные названия нужны лишь для того, чтобы ini файлы создавать? Если да, то по логике простой. Мы создаем текстовый файл, используем string. Вся логика в имени полей TableName - приведение в string... Так может тогда сразу сделать string? Этот enum был служебным, для внутреннего пользования. Клиенту его можно не показывать. Зачем я его сделал? Когда нужно набить пару десятков классов, enum + intellisense здорово помогает. Потом подстраховка от случайное опечатки в string. Сам я его не набивал: вместо этого пропарсил папку со всеми схемами.

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

// вместо: public TableName SystemName { get; private set; }
public string SystemName { get{ _systemName.ToString(); }

Mikhail Sukhov: Давайте подумаем насчет фильтрации. Сейчас это выглядит как то не очень. Я вообще собирался это делать внутри PlazaListener, но пока думал, skuvv успел привинтить свой фильтр[smile]. Что насчет методов RegisterSecurity/UnRegisterSecurity? С помощью них будем включать фильтрацию или они нужно для чего-то другого?

Mikhail Sukhov: PlazaSchemaParser предлагаю упрятать в PlazaTableSerializer Сделаю, когда устаканится модель метаданных. С тех пор как я написал PlazaSchemaParser, модель уже раза-три менялась, и я решил отложить доделку этого класса на самый конец.

Thanks:

skuvv

Avatar
Date: 3/26/2011
Reply


Mikhail Sukhov:

skuvv:

aspirant:

skuvv: К примеру я сравнил проект со своей старой программой plaza2, данные в текущий s# проект поступают медленнее на 6-10мс(время снимал с OnNewSecurityChanged к примеру).

Получается, ты делал свою реализацию PlazaTrader? Нет у меня не интерфейс как в s#, а напрямую работа c потоками и событиями

Может выложить это ввиде отдельного теста для сравнения перфоманса? Насчет OnNewSecurityChanged - конечно. Если вместо поиска по словарю устраивать Exist Find и т.д., то я не удивлюсь и пол минутными задержками.[smile]


void m_conn4_StreamDataInserted(CP2DataStream stream, String tableName, CP2Record rec)
        {
            try
            {
                if (stream.StreamName == streamFutCommonID)
                {
                    int index = instruments.GetIndex(rec.GetValAsLong("isin_id"));
                    if(index>=0)
                    {
                        double best_sell = Convert.ToDouble(rec.GetValAsVariant("best_sell"));
                        double best_buy = Convert.ToDouble(rec.GetValAsVariant("best_buy"));
                        if (best_buy != 0 && best_sell != 0)
                        {
                            instruments._bestask[index] = best_sell;
                            instruments._bestask_vol[index] = rec.GetValAsLong("amount_sell");
                            instruments._bestbid[index] = best_buy;
                            instruments._bestbid_vol[index] = rec.GetValAsLong("amount_buy");
                            instruments._lasttrade[index] = Convert.ToDouble(rec.GetValAsVariant("price"));
                            instruments._lasttrade_vol[index] = rec.GetValAsLong("amount");
                            instruments._lasttrade_time[index] = Convert.ToDateTime(rec.GetValAsString("deal_time"));
                            instruments._bidask_time[index] = DateTime.Now;

                            curr_rev_futcommon = rec.GetValAsLong("replRev");

                            log_buffer.Add(t4.Name, rec.GetValAsString("replID") + ";" + rec.GetValAsString("replRev") + ";" + instruments._isin_id[index] + ";" + instruments._bestask[index] + ";" + instruments._bestask_vol[index] + ";" +
                                instruments._bestbid[index] + ";" + instruments._bestbid_vol[index] + ";" + instruments._lasttrade[index] + ";" + instruments._lasttrade_vol[index] + ";" + instruments._lasttrade_time[index].ToString(timefmt) + ";" + rec.GetValAsString("deal_count") + ";" + rec.GetValAsString("pos"));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                 log_buffer.Add("error", "[" + t4.Name + "] " + e.ToString());
            }
        }

Event datainserted Все типы таблицы я получал в соответсвующих им win thread. Событий никаких нет [biggrin], заполняется статик массив instruments,а роботы на каждом прогоне его чекают. Ну и в конце запись в текстовики, через самописный логгер. ps фильтрация опять же массиву instruments

Thanks:

Mikhail Sukhov

Avatar
Date: 3/27/2011
Reply


aspirant:

Mikhail Sukhov: Сейчас PlazaListener создается в самом начале со всеми колонками. Как я уже писал, использовать надо только те колонки, что определены схемами PlazaTable.Columns. Как клиентский код создает таблицу с колонками и схемами? Твое видение с куском кода.

Взял за основу отсюда:

PlazaTableRegistry.FutCommon.Columns.Add(PlazaColumnRegistry.FuturesCommon.CurKotir);

PlazaTableRegistry.FutAggr5.Columns.Add(PlazaColumnRegistry.FuturesAggregation5.Moment);

aspirant:

Mikhail Sukhov: enum TableName лучше сделать статическим классом со строковыми константами. Я так понял, такие безобразные названия нужны лишь для того, чтобы ini файлы создавать? Если да, то по логике простой. Мы создаем текстовый файл, используем string. Вся логика в имени полей TableName - приведение в string... Так может тогда сразу сделать string? Этот enum был служебным, для внутреннего пользования. Клиенту его можно не показывать. Зачем я его сделал? Когда нужно набить пару десятков классов, enum + intellisense здорово помогает. Потом подстраховка от случайное опечатки в string. Сам я его не набивал: вместо этого пропарсил папку со всеми схемами.

Ок, не поняли друг друга. Тогда ремарка и код. Если enum используется для задания строковых констант, то используется класс со строками:

static class TableName
{
  public const string BaseContractsParams = "base_contracts_params";
  ..
}

public static PlazaTable FutAggr50 = new PlazaTable(TableName.BaseContractsParams, ReplicationStream.FutAggr50, "Фьючерсы: стакан глубиной 50 котировок");

На этом примере сразу видно недостаток именования перечислений (не ReplicationStreams, а ReplicationStream). Сходу кажется, что идет работа с потоком. А на самом деле к потокам это имеет о посредственное значение.

aspirant: Вообще PlazaTable сейчас и есть то, что ты предлагаешь. За исключением полей метаданных все остальные методы закомментены (причем, делал это не я). Можно сделать вот так:

// вместо: public TableName SystemName { get; private set; } public string SystemName { get{ _systemName.ToString(); }


Не понял, что за рокировка.

> **[aspirant](@message(7053)):**
> > **[Mikhail Sukhov](@message(7048)):**
> > Давайте подумаем насчет фильтрации. Сейчас это выглядит как то не очень.
> Я вообще собирался это делать внутри PlazaListener, но пока думал, skuvv успел привинтить свой фильтр[smile].  Что насчет методов RegisterSecurity/UnRegisterSecurity?  С помощью них будем включать фильтрацию или они нужно для чего-то другого?

Да, именно включение фильтра. Во всех АПИ (и я думаю в Плазе тоже рано или поздно сделают), фильтрация идет на серверной стороне и этот фильтра изменяется через методы, аналогичные Register Unregister.
Thanks:

aspirant

Avatar
Date: 3/28/2011
Reply


Mikhail Sukhov: ODE0�

Вопросы:

  1. То есть мы исходим из того, что клиент подписывается на каждый поток только один раз? Напоминаю, у Плазы можно подписываться на один поток несколько раз. Клиенты не будут спрашивать? Когда проект будет зарелизен, изменить архитекутру будет сложно.
  2. Что делать с нашими стандартными потоками, которые нужны, чтобы мапить объекты. Мы договорились, что их скроем от клиента, чтобы гарантировать в них нужный набор колоннок. Придется все равно создавать какие-то отдельные таблицы.

Mikhail Sukhov: Если enum используется для задания строковых констант, то используется класс со строками:

static class TableName...


OK, сделаю после фильтрации.  Сейчас все работает, а это рефакторинг функционала не добавит, только эстетику.

> **[Mikhail Sukhov](@message(7064)):**
> Не понял, что за рокировка.
Теперь она уже не нужна.

> **[Mikhail Sukhov](@message(7064)):**
> На этом примере сразу видно недостаток именования перечислений (не ReplicationStreams, а ReplicationStream)

Не знаю, дело вкуса.  Я уже привык к единственному числу.  Вот, кстати, MSDN'овский [guideline](http://msdn.microsoft.com/en-us/library/4x252001(v=vs.71).aspx).
Thanks:

Mikhail Sukhov

Avatar
Date: 3/28/2011
Reply


aspirant: Вопросы:

  1. То есть мы исходим из того, что клиент подписывается на каждый поток только один раз? Напоминаю, у Плазы можно подписываться на один поток несколько раз. Клиенты не будут спрашивать? Когда проект будет зарелизен, изменить архитекутру будет сложно.
  1. Что делать с нашими стандартными потоками, которые нужны, чтобы мапить объекты. Мы договорились, что их скроем от клиента, чтобы гарантировать в них нужный набор колоннок. Придется все равно создавать какие-то отдельные таблицы.

  2. Давай еще раз обсудим. С точки зрения практики - зачем это нужно?

  3. Хм, а почему бы просто не оставить как есть сейчас?

Thanks:
< 1 2 3 4 5  > >>

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy