где-то в программе пытаюсь остановить стратегию if (strat.ProcessState == StrategyProcessStates.Stopped) strat.Start(); else strat.Stop();
... в моей производной стратегии от Strategy ... protected override void OnStopping() { Trader.QuotesChanged -= _trader_QuotesChanged; }
после выхода из этого метода программа зависает(чаще чем не виснет) по непонятным для меня причинам. Если кто сталкивался подскажите в чем может быть проблема? спс
Comments (21)
Login or Create account, Log in or register to leave a comment
Вы просто в момент остановки стратегии (когда она Stopped) заново ее стартуете, а когда она Runned - останавливаетете. получается вечный цикл - старт - остановка-старт-остановка
Не совсем понимаю почему... ведь первая часть кода вызывается при нажатии кнопки и никак не должна зацикливаться... или я не прав?
А что за стратегия? Собственная или из примеров?
ÓÏÂÓÔ×ÅÎÎÁÑ. 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); }
Sec2.Exchange.IsTradeTime(Trader)) { AddLog(ErrorState, "îÅÔÏÒÇÏ×ÒÅ ×ÒÅÍÑ", this); return true; }
orderParNum.ToString(); else if (o.Portfolio == Portf2) _trader.ClientCode = ClientCode2 + "//" + orderParNum.ToString(); else _trader.ClientCode = "X";
o.Direction.ToString() + " " + o.Security.Code + " " + o.Price + " " + o.Volume, this);
×ÙÓÔÁ×ÌÅÎÉÑ ÚÁÑ×ËÉ", this); AddLog(ErrorState, regOrderError.Message, this); } } } this.buzzy = false; } return true; }
Quote> arg2) { if (!buzzy) this.OnProcess(); }
×ÏÔ ÐÒÉÍÅÒÎÏ ÔÁË. ÓÔÁÒÁÌÓÑ ÄÅÌÁÔØ ËÁË × ÐÒÉÍÅÒÁÈ ÎÏ ×ÉÄÉÍÏ ÞÔÏÔÏ ÕÐÕÓÔÉÌ.
после выхода из OnStopping() сразу завис :(
А что значит завис? В чем это проявилось?
прога виснет. в логах вижу что стратегия останавливается но не вижу что она остановилась. еще раз повторюсь такая ситуация проявляется не регулярно но довольно часто.
Так прога виснет или стратегия не нотифицирует о своей остановке? Какая версия S#?
кажется разобрался. я видимо заумно (не правильно) использовал Strategy.Log вот как было:
private void ToLog(string message) { if (this.messageBox.InvokeRequired) { SetTextDeleg d = new SetTextDeleg(ToLog); this.Invoke(d, new object[] ); } 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...
Михаил, а в чем может быть причина того что во время выполнения стратегии метод ToLog работает нормально, а после OnStopping происходит зависание?
А как часто вызывается Log событие? Invoke - это ведь синхронизация с ГУИ потоком. Может быть фишка в том, что все время уходит на эту саму синхронизацию?
вызывается минимум раз в секунду, а то и чаще. пробую обновлять данные порциями - не очень информативно. видимо нужно придумать прокладку между гуи и логгированием. хотя по сути логи нужны лишь при тестировании.
А если писать в файл?
в файл пишу через StategyLogger все норм. но если часто писать то бывает что строки одна на другую вылазят) А как обстоят дела с wpf и LogWindow? там таких проблем нет?
Строки вылазят одна на другую - это как?
В LogWindow может быть чуть шустрее, за счет того, что он не конкатенирует текст в контроле, а используется ListView. Попробуйте, может и хватит скорости. А вообще вариант напрашивается писать в некую очередь, из которой ГУИ поток выгребает данные и отображает на форме.
Думаю, это когда несколько потоков параллельно пишут в один файл.
А что с ними произойдет? Будут разрыва в строчках? Или просто строчки будут идти одна за другой но из разных стратегий?
Строчки одна за другой, но из разных стратегий, будут идти при любом раскладе -- организовывать в многопоточной многопроцессорной среде ордеринг потоков данных обычно неразумно. Где-то рядом обсуждали про приход данных об изменении баланса для закрытой сделки или что-то типа того -- это из той же серии. Если я правильно понял про строки -- каждая строка это одна запись в лог.
Разрывы в строках да, могут быть. Может быть перемешано. Это в лучшем случае =) А в худшем можно получить мусор, потому что StreamWriter не тредсейфовый и можно поломать его состояние. Но такое получить непросто, надо высокую concurrency иметь, чтобы постоянно ловить.
Лечится просто. private object _syncRoot; // вместо этого можно использовать любой reference type филд
lock(_syncRoot) { _writer.WriteLine("{0:T} {1}", DateTime.Now, message);
Вряд ли синхронизация спасёт автора темы, но с логом всё будет нормально.
Да, почитал про StreamWriter. Не все так хорошо. Заодно наткнулся на интересный методhttp://msdn.microsoft.com/en-us/library/system.io.textwriter.synchronized.aspx
Думаю будет элегантнее, чем вводить в коде свой маркер.
Вот что иногда бывает в лог файле (первые 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;
*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;
Свою проблему решил следующим образом: создал список в который добавляются данные из Strategy.Log. добавил таймер на форму и теперь по таймеру синхронизирую гуи и свой список с логом. пока вроде все работает)