public void MarketOrder(SignalInfo signal, IExpert adv) { try { if (adv == null) { return; } // decimal priceInOrder = Math.Round(tool.LastPrice + tool.Step * 5, tool.PriceAccuracy); // decimal priceInOrder = 0;// Math.Round(tool.LastPrice, tool.PriceAccuracy); int qty = (int)adv.Volume(); var portfolio = Portfolios.Where(x => x.Name == adv.AccountName()).FirstOrDefault(); if (!Trader.RegisteredPortfolios.Contains(portfolio)) { Trader.RegisterPortfolio(portfolio); } Order order = new Order(); order.Type = OrderTypes.Market; var securities = Securities.Where(x => x.Code == adv.Symbol()); if (securities != null && securities.Count() > 0) { order.Security = securities.FirstOrDefault(); } else { order.Security = new Security(); order.Security.Code = adv.Symbol(); order.Security.Id = adv.Symbol() + "@FORTS"; } order.Comment = adv.Comment(); order.Portfolio = portfolio; if (!Trader.RegisteredSecurities.Contains(order.Security)) { Trader.RegisterSecurity(order.Security); Trader.RegisterTrades(order.Security); } order.Volume = qty; order.Direction = signal.Value == 0 ? Sides.Buy : Sides.Sell; Log( $"Expert <{adv.AccountName()}> On {adv.Symbol()} {order.Direction.ToString()} Register order: lots=" + qty); Trader.RegisterOrder(order); } catch (Exception e) { Log($"Expert <{adv.AccountName()}> Error registering order: " + e); } }
static void Main() { try { Console.Write(LocalizedStrings.Str2992); var account1 = Console.ReadLine(); Console.Write(LocalizedStrings.Str2993); var account2 = Console.ReadLine(); using (var quikTrader1 = new QuikTrader { LuaFixServerAddress = "127.0.0.1:5001".To <EndPoint>() }) using (var quikTrader2 = new QuikTrader { LuaFixServerAddress = "127.0.0.1:5002".To <EndPoint>() }) { // подписываемся на событие ошибок обработки данных и разрыва соединения // quikTrader1.Error += OnError; quikTrader2.Error += OnError; quikTrader1.ConnectionError += OnError; quikTrader2.ConnectionError += OnError; var portfoliosWait = new ManualResetEvent(false); Action <IEnumerable <Portfolio> > newPortfolios = portfolios => { if (_portfolio1 == null) { _portfolio1 = portfolios.FirstOrDefault(p => p.Name == account1); } if (_portfolio2 == null) { _portfolio2 = portfolios.FirstOrDefault(p => p.Name == account2); } // если оба инструмента появились if (_portfolio1 != null && _portfolio2 != null) { portfoliosWait.Set(); } }; // подписываемся на события новых портфелей quikTrader1.NewPortfolios += newPortfolios; quikTrader2.NewPortfolios += newPortfolios; var securitiesWait = new ManualResetEvent(false); // подписываемся на события новых инструментов quikTrader1.NewSecurities += securities => { if (_lkoh == null) { _lkoh = securities.FirstOrDefault(s => s.Code == "LKOH"); } // если оба инструмента появились if (_lkoh != null && _riz0 != null) { securitiesWait.Set(); } }; quikTrader2.NewSecurities += securities => { if (_riz0 == null) { _riz0 = securities.FirstOrDefault(s => s.Code == "RIZ0"); } // если оба инструмента появились if (_lkoh != null && _riz0 != null) { securitiesWait.Set(); } }; // запускаем экспорты в Quik-ах, когда получим событие об успешном соединении // quikTrader1.Connected += () => { Console.WriteLine(LocalizedStrings.Str2994Params.Put(quikTrader1.LuaFixServerAddress)); }; quikTrader2.Connected += () => { Console.WriteLine(LocalizedStrings.Str2994Params.Put(quikTrader2.LuaFixServerAddress)); }; // производим подключение каждого из QuikTrader-а // quikTrader1.Connect(); quikTrader2.Connect(); Console.WriteLine(LocalizedStrings.Str2995); portfoliosWait.WaitOne(); securitiesWait.WaitOne(); Console.WriteLine(LocalizedStrings.Str2996); if (_lkoh.BestBid == null || _riz0.BestBid == null) { throw new Exception(LocalizedStrings.Str2990); } quikTrader1.RegisterOrder(new Order { Portfolio = _portfolio1, Volume = 1, Security = _lkoh, Price = _lkoh.BestBid.Price }); Console.WriteLine(LocalizedStrings.Str2997); quikTrader2.RegisterOrder(new Order { Portfolio = _portfolio2, Volume = 1, Security = _riz0, Price = _riz0.BestBid.Price }); Console.WriteLine(LocalizedStrings.Str2998); } } catch (Exception ex) { Console.WriteLine(ex); } }
static void Main() { try { // для теста выбираем бумагу Лукойл const string secCode = "LKOH"; var quikPath = QuikTerminal.GetDefaultPath(); if (quikPath.IsEmpty()) { Console.WriteLine(LocalizedStrings.Str2984); return; } Console.WriteLine(LocalizedStrings.Str2985.Put(quikPath)); Console.Write(LocalizedStrings.Str2986); var account = Console.ReadLine(); using (var waitHandle = new AutoResetEvent(false)) { // создаем подключение к Quik-у using (var trader = new QuikTrader(quikPath) { IsDde = true }) { // необходимо раскомментировать, если идет работа с РТС Стандарт //trader.FormatTransaction += builder => builder.RemoveInstruction(Transaction.TimeInForce); // подписываемся на событие успешного подключения // все действия необходимо производить только после подключения trader.Connected += () => { Console.WriteLine(LocalizedStrings.Str2169); // извещаем об успешном соединени waitHandle.Set(); }; Console.WriteLine(LocalizedStrings.Str2170); trader.DdeTables = new[] { trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable, trader.EquityPortfoliosTable, trader.OrdersTable }; trader.Connect(); // дожидаемся события об успешном соединении waitHandle.WaitOne(); trader.NewPortfolio += portfolio => { if (_portfolio == null && portfolio.Name == account) { // находим нужный портфель и присваиваем его переменной _portfolio _portfolio = portfolio; Console.WriteLine(LocalizedStrings.Str2171Params, account); // если инструмент и стакан уже появились, // то извещаем об этом основной поток для выставления заявки if (_lkoh != null && _depth != null) { waitHandle.Set(); } } }; // подписываемся на событие появление инструментов trader.NewSecurity += security => { if (_lkoh == null) { if (!security.Code.CompareIgnoreCase(secCode)) { return; } // находим Лукойл и присваиваем ее переменной lkoh _lkoh = security; if (_lkoh != null) { Console.WriteLine(LocalizedStrings.Str2987); // запускаем экспорт стакана trader.RegisterMarketDepth(_lkoh); if (_portfolio != null && _depth != null) { waitHandle.Set(); } } } }; // подписываемся на событие появления моих новых сделок trader.NewMyTrade += myTrade => { var trade = myTrade.Trade; Console.WriteLine(LocalizedStrings.Str2173Params, trade.Id, trade.Price, trade.Security.Code, trade.Volume, trade.Time); }; // подписываемся на событие обновления стакана trader.MarketDepthChanged += depth => { if (_depth == null && _lkoh != null && depth.Security == _lkoh) { _depth = depth; Console.WriteLine(LocalizedStrings.Str2988); // если портфель и инструмент уже появился, то извещаем об этом основной поток для выставления заявки if (_portfolio != null && _lkoh != null) { waitHandle.Set(); } } }; Console.WriteLine(LocalizedStrings.Str2989Params.Put(account)); // дожидаемся появления портфеля и инструмента waitHandle.WaitOne(); // 0.1% от изменения цены const decimal delta = 0.001m; // запоминаем первоначальное значение середины спреда var firstMid = _lkoh.BestPair.SpreadPrice / 2; if (_lkoh.BestBid == null || firstMid == null) { throw new Exception(LocalizedStrings.Str2990); } Console.WriteLine(LocalizedStrings.Str2991Params, _lkoh.BestBid.Price + firstMid); while (true) { var mid = _lkoh.BestPair.SpreadPrice / 2; // если спред вышел за пределы нашего диапазона if (mid != null && ((firstMid + firstMid * delta) <= mid || (firstMid - firstMid * delta) >= mid) ) { var order = new Order { Portfolio = _portfolio, Price = _lkoh.ShrinkPrice(_lkoh.BestBid.Price + mid.Value), Security = _lkoh, Volume = 1, Direction = Sides.Buy, }; trader.RegisterOrder(order); Console.WriteLine(LocalizedStrings.Str1157Params, order.Id); break; } else { Console.WriteLine(LocalizedStrings.Str2176Params, _lkoh.BestBid.Price + mid); } // ждем 1 секунду Thread.Sleep(1000); } // останавливаем подключение trader.Disconnect(); } } } catch (Exception ex) { Console.WriteLine(ex); } }
static void Main() { try { // для теста выбираем бумагу Лукойл const string secCode = "LKOH"; var quikPath = QuikTerminal.GetDefaultPath(); if (quikPath.IsEmpty()) { Console.WriteLine("Не найден ни один запущенный Quik"); return; } Console.WriteLine("Запущенный Quik найден по пути " + quikPath); Console.Write("Введите код клиента, через который будет выставлена заявка: "); var account = Console.ReadLine(); using (var waitHandle = new AutoResetEvent(false)) { // создаем шлюз к Quik-у using (var trader = new QuikTrader(quikPath)) { // необходимо раскомментировать, если идет работа с РТС Стандарт //trader.FormatTransaction += builder => builder.RemoveInstruction(TransactionBuilder.ExecutionCondition); // подписываемся на событие успешного подключения // все действия необходимо производить только после подключения trader.Connected += () => { Console.WriteLine("Подключение было произведено успешно."); // извещаем об успешном соединени waitHandle.Set(); }; Console.WriteLine("Производим подключение..."); trader.Connect(); // дожидаемся события об успешном соединении waitHandle.WaitOne(); trader.NewPortfolios += portfolios => { if (_portfolio == null) { // находим Лукойл и присваиваем ее переменной lkoh _portfolio = portfolios.FirstOrDefault(p => p.Name == account); if (_portfolio != null) { Console.WriteLine("Портфель {0} появился.", account); // если инструмент и стакан уже появились, // то извещаем об этом основной поток для выставления заявки if (_lkoh != null && _depth != null) { waitHandle.Set(); } } } }; // подписываемся на событие появление инструментов trader.NewSecurities += securities => { if (_lkoh == null) { // находим Лукойл и присваиваем ее переменной lkoh _lkoh = securities.FirstOrDefault(sec => sec.Code == secCode); if (_lkoh != null) { Console.WriteLine("Инструмент Лукойл появился."); // запускаем экспорт стакана trader.RegisterQuotes(_lkoh); if (_portfolio != null && _depth != null) { waitHandle.Set(); } } } }; // подписываемся на событие появления моих новых сделок trader.NewMyTrades += myTrades => { foreach (var myTrade in myTrades) { var trade = myTrade.Trade; Console.WriteLine("Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}.", trade.Id, trade.Price, trade.Security.Code, trade.Volume, trade.Time); } }; // подписываемся на событие обновления стакана trader.QuotesChanged += depths => { if (_depth == null && _lkoh != null) { _depth = depths.FirstOrDefault(d => d.Security == _lkoh); if (_depth != null) { Console.WriteLine("Стакан Лукойла появился."); // если портфель и инструмент уже появился, то извещаем об этом основной поток для выставления заявки if (_portfolio != null && _lkoh != null) { waitHandle.Set(); } } } }; Console.WriteLine("Дожидаемся появления в программе инструмента Лукойл и портфеля {0}...".Put(account)); // запускаем экспорт по DDE trader.StartExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable, trader.EquityPortfoliosTable, trader.OrdersTable); // дожидаемся появления портфеля и инструмента waitHandle.WaitOne(); // 0.1% от изменения цены const decimal delta = 0.001m; // запоминаем первоначальное значение середины спреда var firstMid = _lkoh.BestPair.SpreadPrice / 2; if (_lkoh.BestBid == null) { throw new Exception("Нет лучшего бида для котировки."); } Console.WriteLine("Первоначальное значение середины спреда {0:0.##}", _lkoh.BestBid.Price + firstMid); while (true) { var mid = _lkoh.BestPair.SpreadPrice / 2; // если спред вышел за пределы нашего диапазона if ( ((firstMid + firstMid * delta) <= mid) || ((firstMid - firstMid * delta) >= mid) ) { var order = new Order { Portfolio = _portfolio, Price = _lkoh.ShrinkPrice(_lkoh.BestBid.Price + mid), Security = _lkoh, Volume = 1, Direction = OrderDirections.Buy, }; trader.RegisterOrder(order); Console.WriteLine("Заявка {0} зарегистрирована.", order.Id); break; } else { Console.WriteLine("Текущее значение середины спреда {0:0.##}", _lkoh.BestBid.Price + mid); } // ждем 1 секунду Thread.Sleep(1000); } // останавливаем экспорт по DDE trader.StopExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable, trader.EquityPortfoliosTable, trader.OrdersTable); } } } catch (Exception ex) { Console.WriteLine(ex); } }
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ private void butStartStrategy_Click(object sender, RoutedEventArgs e) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { if (threadStrategy == null) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { //if (threadStrategy == null) threadStrategy = new Thread ( new ThreadStart (() => { try { while (true) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { //бесконечный цикл обработки стратегии if (analizationPool.Count != 0) { ProcessStrategy(); } Thread.Sleep(processStrategyRate); } //бесконечный цикл обработки стратегии //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ } catch (Exception ex) { //SendMessage("ERROR", "Error on Thread startegy:>>" + ex.ToString()); } finally { //status = StrategyStatus.Stopped; } } ) ); threadStrategy.Name = "StrategyThread_" + DateTime.Now.Ticks.ToString(); threadStrategy.IsBackground = true; threadStrategy.Priority = ThreadPriority.Normal; } //if (threadStrategy == null) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ if (threadTrader == null) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { //if (threadTrader == null) threadTrader = new Thread ( new ThreadStart (() => { try { while (true) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { //бесконечный цикл обработки стратегии if (ordersCancel.Count != 0) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { //отмена ордеров MyOrder myOrder; while (ordersCancel.TryDequeue(out myOrder)) { if (myOrder.ssOrder == null) { throw new Exception("Unexpected state of order"); continue; } //lock (order) //{ //if (order.Status == Trade.Order.OrderStatus.Cancelling) //{ myOrder.Status = MyOrderStatus.SentToCancel; trader.CancelOrder(myOrder.ssOrder); //} //} //Thread.Sleep(1000); } } //отмена ордеров //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ if (ordersSend.Count != 0) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ { //отправка ордеров MyOrder myOrder; while (ordersSend.TryDequeue(out myOrder)) { //_o.rwLock.EnterWriteLock(); MyOrder _order = myOrder; StockSharp.BusinessEntities.Order ssOrd = new StockSharp.BusinessEntities.Order() { Trader = trader, Portfolio = portfolio, Security = security, Comment = "GISMO", Direction = StockSharp.BusinessEntities.OrderDirections.Buy, // : StockSharp.BusinessEntities.OrderDirections.Sell, Price = (decimal)_order.price, Type = StockSharp.BusinessEntities.OrderTypes.Limit, Volume = _order.amount }; _order.ssOrder = ssOrd; //_order.rulerContainer = StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer; var ruleRegFail = ssOrd.WhenRegisterFailed(); var ruleReg = ssOrd.WhenRegistered(); //_order.RegisterToken(ruleRegFail.Token); //_order.RegisterToken(ruleReg.Token); ruleReg.Do((StockSharp.BusinessEntities.Order _ssOrd) => { try { //GISMO.Trade.Order __order = QTrader._orders[_ssOrd.TransactionId]; //__order.rwLock.EnterWriteLock(); _order.Status = MyOrderStatus.AcceptedByServer; _order.AddStage("WhenRegistered:OrderRegistered"); //__order.rwLock.ExitWriteLock(); _order.OnOrderRegistered(); } catch (Exception ex) { int i = 0; } }) .Once() .Apply(StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer) .Exclusive(ruleRegFail); ruleRegFail.Do((StockSharp.BusinessEntities.OrderFail f) => { try { //GISMO.Trade.Order __order = QTrader._orders[f.Order.TransactionId]; //__order.rwLock.EnterWriteLock(); _order.Status = MyOrderStatus.Failed; _order.AddStage("WhenRegisteredFail:OrderRegisteredFail"); //__order.rwLock.ExitWriteLock(); _order.OnOrderRegisterFailed(new OrderFailEventArg() { order = _order, fail = new OrderFail() { ssFail = f } }); } catch (Exception ex) { int i = 0; } }) .Once() .Apply(StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer) .Exclusive(ruleReg); var ruleCancelled = ssOrd.WhenCanceled(); var ruleCancelledFail = ssOrd.WhenCancelFailed(); //_order.RegisterToken(ruleCancelled.Token); //_order.RegisterToken(ruleCancelledFail.Token); ruleCancelled.Do((StockSharp.BusinessEntities.Order _ssOrd) => { try { //GISMO.Trade.Order __order = QTrader._orders[_ssOrd.TransactionId]; //__order.rwLock.EnterWriteLock(); _order.Status = MyOrderStatus.Cancelled; //__order.rwLock.ExitWriteLock(); //StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer.Rules.RemoveRulesByToken(ruleCancelled.Token, ruleCancelled); _order.OnOrderCancelled(); } catch (Exception ex) { int i = 0; } }) .Once() .Apply(StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer) .Exclusive(ruleCancelledFail); ruleCancelledFail.Do((StockSharp.BusinessEntities.OrderFail f) => { try { //GISMO.Trade.Order __order = QTrader._orders[f.Order.TransactionId]; //__order.rwLock.EnterWriteLock(); _order.Status = MyOrderStatus.Failed; _order.AddStage("WhenCancelFail:OrderCancelFail"); //__order.rwLock.ExitWriteLock(); _order.OnOrderCancelFailed(new OrderFailEventArg() { order = _order, fail = new OrderFail() { ssFail = f } }); } catch (Exception ex) { int i = 0; } }) .Once() .Apply(StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer) .Exclusive(ruleCancelled); var ruleMatched = _order.ssOrder.WhenMatched(); //_order.RegisterToken(ruleMatched.Token); ruleMatched.Do(() => { try { //_order.rwLock.EnterWriteLock(); _order.Status = MyOrderStatus.Filled; //_order.rwLock.ExitWriteLock(); StockSharp.Algo.MarketRuleHelper.DefaultRuleContainer.Rules.RemoveRulesByToken(ruleMatched.Token, ruleMatched); _order.OnOrderMatched(); } catch (Exception ex) { int i = 0; } }) .Once() .Apply(); var rulePartMatched = _order.ssOrder.WhenPartiallyMatched(); //_order.RegisterToken(rulePartMatched.Token); rulePartMatched.Do(() => { try { //_order.rwLock.EnterWriteLock(); _order.Status = MyOrderStatus.PartlyFilled; //_order.rwLock.ExitWriteLock(); _order.OnOrderPartlyMatched(); } catch (Exception ex) { int i = 0; } }).Apply(); var ruleNewTrades = _order.ssOrder.WhenNewTrades(); //_order.RegisterToken(ruleNewTrades.Token); ruleNewTrades.Do((IEnumerable <MyTrade> trades) => { try { //List<OrderExecution> execs = new List<OrderExecution>(); //foreach (MyTrade mt in trades) execs.Add(new OrderExecution() { ssMyTrade = mt }); //_order.OnOrderTrades(new OrderExecutionEventArg() //{ // order = _order, // executions = execs //}); } catch (Exception ex) { int i = 0; } }) .Apply(); _order.Status = MyOrderStatus.SentToServer; trader.RegisterOrder(ssOrd); //Thread.Sleep(1000); //QTrader._orders.Add(ssOrd.TransactionId, _order); //_o.rwLock.ExitWriteLock(); //if (_order.Strategy != null) _order.Strategy.SendMessage("QSEND", "Order price " + _order.price.ToString() + " Sent (TransID = " + ssOrd.TransactionId + ")"); } } //отправка ордеров //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Thread.Sleep(processStrategyRate); } //бесконечный цикл обработки стратегии //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ } catch (Exception ex) { //SendMessage("ERROR", "Error on Thread startegy:>>" + ex.ToString()); } finally { //status = StrategyStatus.Stopped; } } ) ); threadTrader.Name = "TraderThread_" + DateTime.Now.Ticks.ToString(); threadTrader.IsBackground = true; threadTrader.Priority = ThreadPriority.Normal; } //if (threadTrader == null) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ try { //bool tRunning = threadStrategy...ThreadState.HasFlag(ThreadState.Running); if (!threadStrategy.IsAlive) { threadStrategy.Start(); } if (!threadTrader.IsAlive) { threadTrader.Start(); } } catch (Exception ex) { } }