проблемы с остановкой стратегии
Atom Ответить
24.08.2010


где-то в программе пытаюсь остановить стратегию
if (strat.ProcessState == StrategyProcessStates.Stopped)
strat.Start();
else
strat.Stop();

... в моей производной стратегии от Strategy ...
protected override void OnStopping()
{
Trader.QuotesChanged -= _trader_QuotesChanged;
}

после выхода из этого метода программа зависает(чаще чем не виснет) по
непонятным для меня причинам.
Если кто сталкивался подскажите в чем может быть проблема?
спс

Теги:


Спасибо:




21 Ответов
Tauler

Фотография
Дата: 24.08.2010
Ответить


Вы просто в момент остановки стратегии (когда она Stopped) заново ее
стартуете, а когда она Runned - останавливаетете. получается вечный
цикл - старт - остановка-старт-остановка

Спасибо:

Serg

Фотография
Дата: 24.08.2010
Ответить


Не совсем понимаю почему... ведь первая часть кода вызывается при
нажатии кнопки и никак не должна зацикливаться... или я не прав?
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 24.08.2010
Ответить


А что за стратегия? Собственная или из примеров?

Спасибо:

Serg

Фотография
Дата: 24.08.2010
Ответить


ÓÏÂÓÔ×ÅÎÎÁÑ.
public class Arbitrage : Strategy
{
... ÐÅÒÅÍÅÎÎÙÅ ...
public Arbitrage(QuikTrader trader, TradeSec ts1, TradeSec
ts2, double spreadInPercent, int minimalQty, int maxiQty)
: base()
{
_trader = trader;
this.Interval = TimeSpan.FromSeconds(1);
minQty = minimalQty;
maxQty = maxiQty;
Portf1 = ts1.p;
Portf2 = ts2.p;
ClientCode1 = ts1.client;
ClientCode2 = ts2.client;
Sec1 = ts1.s;
Sec2 = ts2.s;
k1 = ts1.koef;
k2 = ts2.koef;
Spread = spreadInPercent;
md1 = new MarketDepth(Sec1);
md2 = new MarketDepth(Sec2);
_trader.RegisterQuotes(Sec1);
_trader.RegisterQuotes(Sec2);
_trader.QuotesChanged += new
Action<MarketDepth>(_trader_QuotesChanged);
}

void _trader_QuotesChanged(MarketDepth md)
{
if (md.Security == Sec1)
{
md1 = md;
}
if (md.Security == Sec2)
{
md2 = md;
}
}

protected override bool OnProcess()
{
if (this.ProcessState == StrategyProcessStates.Stopping)
{
return false;
}
if (!this.buzzy)
{
this.buzzy = true;
var ords = AlgoSpread();
if (ords != null && ords.Length >= 2)
{
// done ËÌÉÒÉÎÇ?
if (!Sec1.Exchange.IsTradeTime(Trader) || !
Sec2.Exchange.IsTradeTime(Trader))
{
AddLog(ErrorState, "îÅÔÏÒÇÏ×ÒÅ ×ÒÅÍÑ", this);
return true;
}

foreach (Order o in ords)
{
if (o.Portfolio == Portf1)
_trader.ClientCode = ClientCode1 + "//" +
orderParNum.ToString();
else if (o.Portfolio == Portf2)
_trader.ClientCode = ClientCode2 + "//" +
orderParNum.ToString();
else
_trader.ClientCode = "X";

AddLog(ErrorState, "new order " +
o.Direction.ToString() + " " +
o.Security.Code + " " + o.Price + " " +
o.Volume,
this);

try
{
RegisterOrder(o);
}
catch (Exception regOrderError)
{
AddLog(this.ErrorState, " ïÛÉÂËÁ
×ÙÓÔÁ×ÌÅÎÉÑ ÚÁÑ×ËÉ", this);
AddLog(ErrorState, regOrderError.Message,
this);
}
}
}
this.buzzy = false;
}
return true;
}

protected override void OnRunned()
{
base.OnRunned();
buzzy = false;
}

void QuotesChanged(OrderDirections arg1, IDictionary<int,
Quote> arg2)
{
if (!buzzy)
this.OnProcess();
}

protected override void OnStopping()
{
Trader.QuotesChanged -= _trader_QuotesChanged;
base.OnStopping();
}
×ÏÔ ÐÒÉÍÅÒÎÏ ÔÁË. ÓÔÁÒÁÌÓÑ ÄÅÌÁÔØ ËÁË × ÐÒÉÍÅÒÁÈ ÎÏ ×ÉÄÉÍÏ ÞÔÏÔÏ
ÕÐÕÓÔÉÌ.

Автор топика
Спасибо:

Serg

Фотография
Дата: 24.08.2010
Ответить


после выхода из OnStopping() сразу завис :(
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 24.08.2010
Ответить


А что значит завис? В чем это проявилось?

Спасибо:

Serg

Фотография
Дата: 24.08.2010
Ответить


прога виснет. в логах вижу что стратегия останавливается но не вижу
что она остановилась. еще раз повторюсь такая ситуация проявляется не
регулярно но довольно часто.
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 24.08.2010
Ответить


Так прога виснет или стратегия не нотифицирует о своей остановке?
Какая версия S#?

Спасибо:

Serg

Фотография
Дата: 24.08.2010
Ответить


кажется разобрался. я видимо заумно (не правильно) использовал
Strategy.Log
вот как было:

private void ToLog(string message)
{
if (this.messageBox.InvokeRequired)
{
SetTextDeleg d = new SetTextDeleg(ToLog);
this.Invoke(d, new object[] { message });
}
else

messageBox.AppendText(DateTime.Now.ToString("HH:mm:ss.fff")+ ": " +
message + "\r\n");
}

void Log(Strategy arg1, StrategyErrorStates arg2, string arg3)
{
ToLog(arg3);
}

strat = new Arbitrage(quik, t1, t2, Convert.ToDouble(textBox1.Text),
1, 20);
strat.Log += new Action<Strategy, StrategyErrorStates, string>(Log);

избавившись от strat.Log += ... все стало работать нормально.
осталось понять где ошибка. думаю в методе ToLog...

Автор топика
Спасибо:

Serg

Фотография
Дата: 24.08.2010
Ответить


Михаил, а в чем может быть причина того что во время выполнения
стратегии метод ToLog работает нормально, а после OnStopping
происходит зависание?
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 25.08.2010
Ответить


А как часто вызывается Log событие? Invoke - это ведь синхронизация с
ГУИ потоком. Может быть фишка в том, что все время уходит на эту саму
синхронизацию?

Спасибо:

Serg

Фотография
Дата: 25.08.2010
Ответить


вызывается минимум раз в секунду, а то и чаще. пробую обновлять данные
порциями - не очень информативно.
видимо нужно придумать прокладку между гуи и логгированием. хотя по
сути логи нужны лишь при тестировании.
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 25.08.2010
Ответить


А если писать в файл?

Спасибо:

Serg

Фотография
Дата: 25.08.2010
Ответить


в файл пишу через StategyLogger все норм. но если часто писать то
бывает что строки одна на другую вылазят) А как обстоят дела с wpf и
LogWindow? там таких проблем нет?
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 25.08.2010
Ответить


Строки вылазят одна на другую - это как?

В LogWindow может быть чуть шустрее, за счет того, что он не
конкатенирует текст в контроле, а используется ListView. Попробуйте,
может и хватит скорости. А вообще вариант напрашивается писать в некую
очередь, из которой ГУИ поток выгребает данные и отображает на форме.

Спасибо:

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

Фотография
Дата: 25.08.2010
Ответить


Думаю, это когда несколько потоков параллельно пишут в один файл.

Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 25.08.2010
Ответить


А что с ними произойдет? Будут разрыва в строчках? Или просто строчки
будут идти одна за другой но из разных стратегий?

Спасибо:

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

Фотография
Дата: 26.08.2010
Ответить


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

Разрывы в строках да, могут быть. Может быть перемешано. Это в лучшем
случае =) А в худшем можно получить мусор, потому что StreamWriter не
тредсейфовый и можно поломать его состояние. Но такое получить
непросто, надо высокую concurrency иметь, чтобы постоянно ловить.

Лечится просто.
private object _syncRoot; // вместо этого можно использовать любой
reference type филд

lock(_syncRoot)
{
_writer.WriteLine("{0:T} {1}", DateTime.Now, message);

Вряд ли синхронизация спасёт автора темы, но с логом всё будет
нормально.

Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 26.08.2010
Ответить


Да, почитал про StreamWriter. Не все так хорошо. Заодно наткнулся на
интересный методhttp://msdn.microsoft.com/en-us/library/system.io.textwriter.synchronized.aspx

Думаю будет элегантнее, чем вводить в коде свой маркер.

Спасибо:

Serg

Фотография
Дата: 26.08.2010
Ответить


Вот что иногда бывает в лог файле (первые 5 строк):

S S 12:33:36.0820929 working
0820929 S запущена.
S запуS 12:33:36.0977180 working
S 12:33:36.0977180 working
S 12:33:36.1133431 working

а в OnProcess сделано так:
protected override bool OnProcess()
{
if (this.ProcessState == StrategyProcessStates.Stopping)
return false;

int inUse = Interlocked.CompareExchange(ref _inUse, 1, 0);
if (inUse == 0)
{
try
{
AddLog(StrategyErrorStates.Error, /
*DateTime.Now.ToString("H:mm:ss:fff") + */" working", this);
AddLog(StrategyErrorStates.None, /
*DateTime.Now.ToString("H:mm:ss:fff") + */" working", this);
AddLog(StrategyErrorStates.Warning, /
*DateTime.Now.ToString("H:mm:ss:fff") + */" working", this);
}
finally
{
Interlocked.Exchange(ref _inUse, 0);
}
}
return true;
}
а интервал стратегии this.Interval = TimeSpan.Zero;

Автор топика
Спасибо:

Serg

Фотография
Дата: 26.08.2010
Ответить


Свою проблему решил следующим образом:
создал список в который добавляются данные из Strategy.Log.
добавил таймер на форму и теперь по таймеру синхронизирую гуи и свой
список с логом. пока вроде все работает)
Автор топика
Спасибо:


Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy