Stock# с несколькими квиками


Stock# с несколькими квиками
Atom
8/3/2010


Со сколькими копиями квика можно безболезненно запускать одного
робота?
Как происходит экспорт через DDE в Stock# - одинаковые данные, я так
понимаю, фильтруются?

Вопрос возник не случайно - сейчас с 7ми квиками роботы съедают до
50-60% от нашего довольно мощного сервера (на каждом квике запущен 1-2
робота, каждый робот запускается 1 секунду). Стоит ли искать ошибку,
пытаться оптимизировать самого робота или лучше закинуть часть квиков
на другой сервер?

Tags:


Thanks:


1 2 3  > >>
Mikhail Sukhov

Avatar
Date: 8/4/2010
Reply


1. Да, одинаковые данные отбрасываются. Если это разные Квики, то это
будут все сделки и инструменты (если конечно у Вас не шарица еще что-
то). Хотя и сделки могут быть уникальными, если каждый Квик торгует
только свой диапазон инструментов.
2. А кто съедает? Робот или Квики? Роботов несколько или же он только
один? Распределение 50-60 по прогам можете привести?

Thanks:

Alexander

Avatar
Date: 8/5/2010
Reply


Съедает сам робот. Он запущен только 1, просто там идёт работа со
многими квиками.
Что это за распределение и как его сделать? :)

Ещё я заметил следующее при работе с несколькими квиками - возьмём, к
примеру, таблицу Всех сделок. Она передаётся насколько я понимаю из
какого-то одного квика (к примеру, который был первым добавлен в
AggregatedTrades), из остальных игнорируется. Как только теряется
связь с сервером у первого квика (остальные при этом работают) -
таблица всех сделок перестаёт экспортироваться (хотя могла бы из
других квиков) - получается нельзя таким образом подстраховаться...

Thanks:

Mikhail Sukhov

Avatar
Date: 8/5/2010
Reply


Можно через Process Explorer. Он покажет, какие потоки тормозят. А
потокам можно понять, что в них делается. Все S# потоки именованы.
Робота, если Вы этого не делали, не именованы.

Насчет прекращения экспорта. Схема не такая. Роботу льется все. А он
уже смотрит на уникальность. Так что, если какой-то из Квиков лили
дубли и он упал, то на экспорт это не должно отразиться. Тут случаем
ReConnectionManager не вступает в работу? Вот он может все остальные
Квики перезапускать.

Thanks:

Alexander

Avatar
Date: 8/5/2010
Reply


ðÏËÁÚÁÌ, ÔÏÒÍÏÚÉÔ LogHelp, ×ÏÔ StackTrace:
ntkrnlpa.exe!NtBuildNumber+0xe
ntkrnlpa.exe!RtlUpcaseUnicodeString+0xa2
ntkrnlpa.exe!ZwYieldExecution+0x4f3
ntkrnlpa.exe!MmIsDriverVerifying+0xbb2
hal.dll+0x2ef2
clr.dll+0x1a5e
clr.dll!CoUninitializeEE+0x378e
clr.dll!CoUninitializeEE+0x7663
clr.dll!LogHelp_TerminateOnAssert+0x6a1fd
clr.dll!LogHelp_TerminateOnAssert+0x3c642
clr.dll!LogHelp_TerminateOnAssert+0x3c560
clr.dll!LogHelp_TerminateOnAssert+0x3c6de
clr.dll!LogHelp_TerminateOnAssert+0x40b22
clr.dll!LogHelp_TerminateOnAssert+0x3aab2
mscorlib.ni.dll+0x2aae5b
mscorlib.ni.dll+0x237ff4
mscorlib.ni.dll+0x237f34
mscorlib.ni.dll+0x2aade8
clr.dll+0x21db
clr.dll!CoUninitializeEE+0x6862
clr.dll!CoUninitializeEE+0x6a04
clr.dll!CoUninitializeEE+0x6a39
clr.dll!GetPrivateContextsPerfCounters+0x8a13
clr.dll!LogHelp_TerminateOnAssert+0x591ad
clr.dll!LogHelp_TerminateOnAssert+0x5922f
clr.dll!LogHelp_TerminateOnAssert+0x592ea
clr.dll!LogHelp_TerminateOnAssert+0x59381
clr.dll!GetPrivateContextsPerfCounters+0x88e6
clr.dll!GetPrivateContextsPerfCounters+0x87e1
clr.dll!LogHelp_TerminateOnAssert+0x58fb0
KERNEL32.dll!GetModuleFileNameA+0x1ba

ReConnectionManager, ËÏÎÅÞÎÏ, ×ÓÔÕÐÁÅÔ × ÒÁÂÏÔÕ ÅÓÌÉ ÏÄÉÎ ÉÚ Ë×ÉËÏ×
ÕÐÁÌ, Á ÄÒÕÇÏÊ - ÎÅÔ. ô.Å., ×ÉÄÉÍÏ, ÓÔÏÉÔ ReconnectionManager
ÎÁÚÎÁÞÁÔØ ÏÔÄÅÌØÎÏ ÄÌÑ Ë×ÉËÏ×, Á ÎÅ ÄÌÑ ×ÓÅÇÏ MultiTrader?

Thanks:

Alexander

Avatar
Date: 8/5/2010
Reply


Отключил логгирование для стратегий (убрал обработчик OnLog и не
добавляю StrategyLogger) - теперь робот ест от 0 до 50% процессора.
50% - крайне редко, всплески. в основном висит на 0%. т.е. разница
колоссальная.

Thanks:

Mikhail Sukhov

Avatar
Date: 8/6/2010
Reply


Хм, или логов много или дисковая операция тяжелая. Есть вероятность
что StrategyLogger глючит, он там так мало кода. Фактически, вот он
весь (что используется при активизации события):

_writer = new StreamWriter(logDirectory.IsEmpty() ? this.FileName :
Path.Combine(logDirectory, fileName)) { AutoFlush = true };

private void StrategyLog(Strategy strategy, StrategyErrorStates state,
string message)
{
WriteMessage(strategy + " " + message);

/// <summary>
/// Записать специальное сообщение, которое относится ко всем
статегиям <see cref="Strategies"/>.
/// </summary>
/// <param name="message">Сообщение.</param>
public void WriteMessage(string message)
{
if (message.IsEmpty())
throw new ArgumentNullException("message");

Debug.WriteLine(message);
_writer.WriteLine("{0} {1}", DateTime.Now.TimeOfDay, message);

Thanks:

Иванов Андрей

Avatar
Date: 8/7/2010
Reply


Про тяжёлую дисковую операцию не понял =) Дисковые операции едят время
(iowait), а не CPU.

Про много лог-записей в точку -- операция конкатенации самая дорогая
по CPU в .NET (из тех, что не ожидаешь).
Единственный способ борьбы это писать сразу в файл. Если убрать
конкатенацию в _writer.WriteLine(..), производительность логирования
вырастет в полтора раза =)

То есть, оформить запись в виде трёх вызовов -- время, разделитель,
сообщение.

Захотите проверить мою теорию, включите логирование, а все строки с
конкатенацией замените на строки-константы примерно той же длины.

Ещё эффективнее по CPU будет, если событие лога генерировать не со
строкой конкатенации стратегии и сообщения, а объектом с двумя полями
или вызовом метода с двумя параметрами.

Единственный вариант привязать к CPU запись на диск это отключить DMA
для ATA-дисков. Я никогда не сталкивался с необходимостью такое
делать, но можно попровать начать с этого -- проверять надо в дисковом
контроллере, на всех системах названия свои. Раньше было переключение
между режимами (PIO/*DMA), в семёрке чекбокс выключения DMA.

Thanks:

Alexander

Avatar
Date: 8/8/2010
Reply


логов много - каждая запущенная стратегия каждую секунду что-то да
пишет. про тяжёлую дисковую операцию я тоже не понял =)

Хотелось бы ещё закрыть вопрос с прекращением экспорта - я так понимаю
в случае с MultiTrader необходимо ReconnetionManager создавать для
каждого из добавленных AggregatedTraders? В этом случае экспорт не
прекратится если отвалится лишь один из квиков

Thanks:

Иванов Андрей

Avatar
Date: 8/10/2010
Reply


У меня на процессоре Q6600 конкатенация съедала одно ядро примерно за
100 тысяч записей в секунду.
Если у вас 100 стратегий с тайм-фреймом секунда, современный процессор
не заметит этого -- тайм-фрейм должен быть 10 миллисекунд. У вас либо
очень много стратегий (100 тысяч), либо они не все работают с тайм-
фреймом, либо предположение о конкатенации неверно.

Посчитайте, сколько у вас записей в лог за секунду делается. Вместо
записи в лог инкрементируйте счётчик через

Interlocked.Increment(ref _logCounter);

и пишите это значение куда-нибудь раз в секунду примерно вот так:

int count = Interlocked.Exchange(ref _logCounter, 0);
Console.WriteLine("Log rps: {0}", count);

_logCounter -- глобальная переменная. Стратегии вроде сами по себе
ничего не пишут в лог, поэтому вы можете получить точное значение.

Thanks:

Mikhail Sukhov

Avatar
Date: 8/11/2010
Reply


private class MyStrategy : Strategy
{
public void DoLog(string message)
{
base.AddLog(StrategyErrorStates.None, message);
}

protected override bool OnProcess()
{
return false;
}

var str = new MyStrategy();

var logger = new StrategyLogger("1.txt");
logger.Strategies.Add(str);

const int count = 100000;

var t1 = Watch.Do(() =>
{
for (var i = 0; i < count; i++)
{
str.DoLog("111");
}

logger.Strategies.Remove(str);

var writer = new StreamWriter("2.txt") { AutoFlush = true };

str.Log += (s, e, m) =>
{
writer.Write(DateTime.Now.TimeOfDay);
writer.Write(" ");
writer.Write(s);
writer.Write(" ");
writer.WriteLine(m);

var t2 = Watch.Do(() =>
{
for (var i = 0; i < count; i++)
{
str.DoLog("111");
}

ňĹÚŐĚŘÔÁÔ ÎÁ ÍĎĹÍ ÍÁŰÉÎËĹ. t1 - 55 ÓĹËŐÎÄ. t2 - 1 ÓĹËŐÎÄÁ. îÉŢĹÇĎ
ÓĹÂĹ! áÎÄŇĹĘ, ÖÄŐ ËĎÍÍĹÎÔÁŇÉĘ. đĎÔĎÍŐ ËÁË Ń ÄĎ ÓÉČ ĐĎŇ ÓŢÉÔÁĚ, ŢÔĎ
ĎĐĹŇÁĂÉŃ ÚÁĐÉÓÉ × ĆÁĘĚ ÍÎĎÇĎ ÄĎŇĎÖĹ ËÁËĎĘ-ÔĎ ËĎÎËÁÔĹÎÁĂÉÉ ÓÔŇĎË.

Thanks:
1 2 3  > >>

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

loading
clippy