← Back

takeprofit & stoploss

😀 я наверное уже замучал)) Вот из этого примера http://www.stocksharp.com/doc/html/63952fce-6e43-4427-985a-1654e8d9cfc1.htm не понятно мне, сл и тп для общей позиции устанавливается? (просто когда ставим там сл и тп, мы нигде не упоминаем longPos) И есть ли где рабочий пример, так проще понять.

Comments (41)

Login or Create account, Log in or register to leave a comment

tmt
tmt Author

Попробовал вот так.. Но ошибки показывает..

**Элемент "ChildStrategies" не существует в текущем контексте.

**Наиболее подходящий перегруженный метод для "StockSharp.Algo.Strategies.StrategyRule<System.Collections.Generic.IEnumerable<StockSharp.BusinessEntities.MyTrade>>. Do(System.Action<StockSharp.Algo.Strategies.StrategyRule<System.Collections.Generic. IEnumerable<StockSharp.BusinessEntities.MyTrade>>,System.Collections.Generic.IEnumerable<StockSharp.BusinessEntities.MyTrade>>)"

имеет несколько недопустимых аргументов

**Вместе с аргументами-типами нельзя использовать не универсальный тип "System.Collections.IEnumerable"

**Аргумент "1": преобразование типа из "группа методов" в "System.Action<StockSharp.Algo.Strategies.StrategyRule<System.Collections.Generic. IEnumerable<StockSharp.BusinessEntities.MyTrade>>,System.Collections.Generic.IEnumerable<StockSharp.BusinessEntities.MyTrade>>" невозможно

Помогите пожалуйста

namespace SampleSmartConsole
{
	using System;
    using System.Net;
	using System.Linq;
	using System.Threading;
    using System.Collections;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.BusinessEntities;
	using StockSharp.Smart;
	using StockSharp.Algo;
    using StockSharp.Algo.Strategies;


	class Program
	{
		private static Security _instrument;
		private static Portfolio _portfolio;
        private static MarketDepth _depth;
        private static Position _position;


            public class buy : Strategy
    {
        public void OpenPosition()
        {
            // создаем заявку для открытия длинной позиции
            var longPos = this.BuyAtMarket();

            // регистрируем правило, отслеживающее появление новых сделок по заявке
            this
                .When(longPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => longPos.IsMatched());

            // отправляем заявку на регистрацию
            RegisterOrder(longPos);
        }
    }


    private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
{
    // для каждой сделки добавляем для защитную пару стратегии
    var protectiveStrategies = trades.Select(t =>
    {
        // выставляет тейк-профит в 40 пунктов
        var takeProfit = new TakeProfitStrategy(t, 40);

        // выставляет стоп-лосс в 20 пунктов
        var stopLoss = new StopLossStrategy(t, 20);

        return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
    });

    ChildStrategies.AddRange(protectiveStrategies);
}


		static void Main()
		{
			try
			{
				// для теста выбираем бумагу
				const string secCode = "RIH2";

				//Console.Write("Введите логин: ");
				//var login = Console.ReadLine();
                var login = "ST12858";

				//Console.Write("Введите пароль: ");
				//var password = Console.ReadLine();
                var password = "8YDJ7E";

				//Console.Write("Введите номер счета, через который будет выставлена заявка: ");
				//var account = Console.ReadLine();
                var account = "ST12858-RF-01";

                IPAddress ipadress = IPAddress.Parse("95.131.26.246");
                IPEndPoint ip = new IPEndPoint(ipadress, 8090);
                
				using (var waitHandle = new AutoResetEvent(false))
				{
					// создаем шлюз к Smart-у
					using (var trader = new SmartTrader(login, password, ip))
					{
						// подписываемся на событие успешного подключения
						// все действия необходимо производить только после подключения
						trader.Connected += () =>
						{
							Console.WriteLine("Подключение было произведено успешно.");

							// извещаем об успешном соединени
							waitHandle.Set();
						};

						Console.WriteLine("Производим подключение...");

						trader.Connect();

						// дожидаемся события об успешном соединении
						waitHandle.WaitOne();

						// подписываемся на все портфели-счета
						trader.NewPortfolios += portfolios =>
						{
							// необходимое условие работы в SmartCOM
							portfolios.ForEach(trader.RegisterPortfolio);

							if (_portfolio == null)
							{
								_portfolio = portfolios.FirstOrDefault(p => p.Name == account);

								if (_portfolio != null)
								{
									Console.WriteLine("Портфель {0} появился.", account);

                                    if (_instrument != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

						// подписываемся на событие появление инструментов
                        trader.NewPositions += positions =>
                        {
                            if (_position == null)
                            {
                                _position = positions.FirstOrDefault(sec => sec.Security.Code == secCode);
                                if (_position != null)
                                {
                                    Console.WriteLine("Информация о портфеле появилась.");
                                    if (_portfolio != null && _depth != null && _instrument != null)
                                        waitHandle.Set();
                                }
                            }
                        };
						trader.NewSecurities += securities =>
						{
							if (_instrument == null)
							{
                                // находим инструмент и присваиваем ее переменной _instrument
                                _instrument = securities.FirstOrDefault(sec => sec.Code == secCode && sec.Type == SecurityTypes.Future);

								if (_instrument != null)
								{
									Console.WriteLine("Инструмент появился.");
                                    trader.RegisterQuotes(_instrument); // запускаем экспорт стакана
                                    if (_portfolio != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

                        // подписываемся на событие обновления стакана
                        trader.QuotesChanged += depths =>
                        {
                            if (_depth == null && _instrument != null)
                            {
                                _depth = depths.FirstOrDefault(d => d.Security == _instrument);

                                if (_depth != null)
                                {
                                    Console.WriteLine("Стакан появился.");

                                    if (_portfolio != null && _position != 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);
							}
						};

						Console.WriteLine("Дожидаемся появления в программе инструмента и портфеля {0}...".Put(account));

						// запускаем экспорт по инструментам и портфелям
						trader.StartExport();

						// дожидаемся появления портфеля и инструмента
						waitHandle.WaitOne();

						trader.SecuritiesChanged += securities =>
						{
							// если инструмент хоть раз изменился (по нему пришли актуальные данные)
							if (securities.Contains(_instrument))
								waitHandle.Set();
						};

						Console.WriteLine("Дожидаемся обновления данных по инструменту...");

						// запускаем обновление по инструменту
						trader.RegisterSecurity(_instrument);
						waitHandle.WaitOne();

						// запоминаем первоначальное значение середины спреда
                        var totb = _depth.TotalBidsVolume;
                        var tota = _depth.TotalAsksVolume;

                        int maxaskv = 0;
                        int maxbidv = 0;
                        int maxaskp = 0;
                        int maxbidp = 0;
                        var asks = _depth.Asks;
                        var bids = _depth.Bids;
                        for (int i = 0; i < 50; i++)
                        {
                            if (asks[i].Volume > maxaskv) { maxaskv = (int)asks[i].Volume; maxaskp = (int)asks[i].Price; }
                            if (bids[i].Volume > maxbidv) { maxbidv = (int)bids[i].Volume; maxbidp = (int)bids[i].Price; }
                            //Console.WriteLine("asks {0}", asks[i].Price);
                            //Console.WriteLine("asks {0}", asks[i].Volume);
                        }
                        Console.WriteLine("maxask {0}", maxaskv);
                        Console.WriteLine("maxbid {0}", maxbidv);

						if (_instrument.BestBid == null)
							throw new Exception("Нет лучшего бида для котировки.");

                        Console.WriteLine("общий объем bid {0}", totb);
                        Console.WriteLine("общий объем ask {0}", tota);
                        // objem = _instrument.OpenInterest;
                        //Console.WriteLine("открытые позиции {0}", objem);
                        //Console.WriteLine("asks {0}", asks[0]);

						while (true)
						{
                            var objem = _position.CurrentValue;
                            Console.WriteLine("открытые позиции {0}", objem);
                            
							// если спред вышел за пределы нашего диапазона
                            /*if (totb > tota)
                            {*/
                                var order = new Order
                                {
                                    Portfolio = _portfolio,
                                    Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                                    Security = _instrument,
                                    Volume = 1,
                                    Direction = OrderDirections.Sell,
                                };
                                trader.RegisterOrder(order);
                                Console.WriteLine("Заявка {0} зарегистрирована.", order.Id);
                                //break;
                            /*}
                            else
                            {
                                var order = new Order
                                {
                                    Portfolio = _portfolio,
                                    Price = _instrument.ShrinkPrice(_instrument.BestBid.Price),
                                    Security = _instrument,
                                    Volume = 1,
                                    Direction = OrderDirections.Buy,
                                };
                                trader.RegisterOrder(order);
                                Console.WriteLine("Заявка {0} зарегистрирована.", order.Id);
                                //break;
                            }
								//Console.WriteLine("Текущее значение середины спреда {0:0.##}", _instrument.BestBid.Price + mid);
                            */
							// ждем 1 секунду
							Thread.Sleep(1000);
						}

						// останавливаем экспорт
						trader.StopExport();
					}
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
			}
		}
	}
}
ak
ak

Форматируйте код (значек справа от "Цитата" - "Выберите тип подсветки кода"), потому что так понять что-либо очень сложно.

  1. Обработчик OnNewOrderTrades должен быть методом класса стратегии (находиться внутри ).
  2. Generic тип IEnumerable<Type> принадлежит сборке System.Collections.Generic (using System.Collections.Generic;) А логин и пароль в коде измененные, правда? Я на это очень надеюсь.
Sergey Masyura tmt
tmt
tmt Author

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

var ord = new buy();
        public class buy : Strategy
        {
            public void OpenPosition()
            {
                // создаем заявку для открытия длинной позиции
                //var longPos = this.BuyAtMarket();
                var longPos = new Order
                {
                    Portfolio = _portfolio,
                    Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                    Security = _instrument,
                    Volume = 1,
                    Direction = OrderDirections.Sell,
                };

                // регистрируем правило, отслеживающее появление новых сделок по заявке
                this
                .When(longPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => longPos.IsMatched());

                // отправляем заявку на регистрацию
                RegisterOrder(longPos);
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 40 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 40);

                    // выставляет стоп-лосс в 20 пунктов
                    var stopLoss = new StopLossStrategy(t, 20);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }
ak
ak

tmt: Спасибо сделал вот так, а насчет логина(пароля) они реальные.. от демки правда.. А как теперь этот класс вызвать? (можно ли так)

var ord = new buy();


А вы сами попробуйте ;-) Не могу сейчас проверить, но насколько я помню родительский класс Strategy содержит конструктор без параметров (или конструктор по умолчанию - не важно). Ваш класс также имеет конструктор по умолчанию - так что такой конструкцией вы создадите объект стратегии. Но вот чтобы ее запустить (заставить работать) надо переопределить (override) как минимум один метод, какой - внимательно читать тут http://stocksharp.com/doc/html/8c0327db-494a-4fe0-aba8-0d4b93dea60e.htm
tmt
tmt Author

ak:

tmt: Спасибо сделал вот так, а насчет логина(пароля) они реальные.. от демки правда.. А как теперь этот класс вызвать? (можно ли так)

var ord = new buy();

> 
> А вы сами попробуйте ;-) Не могу сейчас проверить, но насколько я помню родительский класс Strategy содержит конструктор без параметров (или конструктор по умолчанию - не важно). Ваш класс также имеет конструктор по умолчанию - так что такой конструкцией вы создадите объект стратегии. Но вот чтобы ее запустить (заставить работать) надо переопределить (override) как минимум один метод, какой - внимательно читать тут http://stocksharp.com/doc/html/8c0327db-494a-4fe0-aba8-0d4b93dea60e.htm

Да так то я уже попробовал)) выяснил что не работает. Сейчас прочту и снова попробую
Alexander
Alexander

tmt: Да так то я уже попробовал)) выяснил что не работает. Сейчас прочту и снова попробую

У нас если что есть поддержка платная, там на подобные вопросы как раз отвечаем. Это если лень разбираться по документации и примерам.

tmt
tmt Author

Это выходит нужно добавить override примерно вот так, а потом он сам запустится, как вызов метода Strategy.Start произойдет? и условия для открытия уже в OpenPosition нужно добавлять, а не в programm..

        public class buy : Strategy
        {
            public override void OpenPosition()
            {
                // создаем заявку для открытия длинной позиции
                //var longPos = this.BuyAtMarket();
                var longPos = new Order
                {
                    Portfolio = _portfolio,
                    Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                    Security = _instrument,
                    Volume = 1,
                    Direction = OrderDirections.Sell,
                };

                // регистрируем правило, отслеживающее появление новых сделок по заявке
                this
                .When(longPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => longPos.IsMatched());

                // отправляем заявку на регистрацию
                RegisterOrder(longPos);
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 40 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 40);

                    // выставляет стоп-лосс в 20 пунктов
                    var stopLoss = new StopLossStrategy(t, 20);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }
tmt
tmt Author

просмотрев пример sma для quik. Увидел, что сначало объявляется класс SmaStrategy, а потом _strategy присваиваем саму стратегию, после уже _strategy.Start();

_strategy = new SmaStrategy(_candleManager, new SimpleMovingAverage { Length = 80 }, new SimpleMovingAverage { Length = 10 }, _timeFrame)
				{
					Volume = 1,
					Security = _lkoh,
					Portfolio = Portfolios.SelectedPortfolio,
					Trader = _trader,
				};

Но вот мне не нужны машки... как реализовать?

tmt
tmt Author

сделал вот так, вроде как должно работать, но ошибка ""SampleSmartConsole.Program.buy.OpenPosition()": не найден метод, пригодный для переопределения"

namespace SampleSmartConsole
{
	using System;
    using System.Net;
	using System.Linq;
	using System.Threading;
    using System.Collections.Generic;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.BusinessEntities;
	using StockSharp.Smart;
	using StockSharp.Algo;
    using StockSharp.Algo.Strategies;

	class Program
	{
		private static Security _instrument;
		private static Portfolio _portfolio;
        private static MarketDepth _depth;
        private static Position _position;
        private static buy _strategy;

		static void Main()
		{
			try
			{
				// для теста выбираем бумагу
				const string secCode = "RIH2";

				//Console.Write("Введите логин: ");
				//var login = Console.ReadLine();
                var login = "ST12858";

				//Console.Write("Введите пароль: ");
				//var password = Console.ReadLine();
                var password = "8YDJ7E";

				//Console.Write("Введите номер счета, через который будет выставлена заявка: ");
				//var account = Console.ReadLine();
                var account = "ST12858-RF-01";

                IPAddress ipadress = IPAddress.Parse("95.131.26.246");
                IPEndPoint ip = new IPEndPoint(ipadress, 8090);
                
				using (var waitHandle = new AutoResetEvent(false))
				{
					// создаем шлюз к Smart-у
					using (var trader = new SmartTrader(login, password, ip))
					{
						// подписываемся на событие успешного подключения
						// все действия необходимо производить только после подключения
						trader.Connected += () =>
						{
							Console.WriteLine("Подключение было произведено успешно.");

							// извещаем об успешном соединени
							waitHandle.Set();
						};

						Console.WriteLine("Производим подключение...");

						trader.Connect();

						// дожидаемся события об успешном соединении
						waitHandle.WaitOne();

						// подписываемся на все портфели-счета
						trader.NewPortfolios += portfolios =>
						{
							// необходимое условие работы в SmartCOM
							portfolios.ForEach(trader.RegisterPortfolio);

							if (_portfolio == null)
							{
								_portfolio = portfolios.FirstOrDefault(p => p.Name == account);

								if (_portfolio != null)
								{
									Console.WriteLine("Портфель {0} появился.", account);

                                    if (_instrument != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

						// подписываемся на событие появление инструментов
                        trader.NewPositions += positions =>
                        {
                            if (_position == null)
                            {
                                _position = positions.FirstOrDefault(sec => sec.Security.Code == secCode);
                                if (_position != null)
                                {
                                    Console.WriteLine("Информация о портфеле появилась.");
                                    if (_portfolio != null && _depth != null && _instrument != null)
                                        waitHandle.Set();
                                }
                            }
                        };
						trader.NewSecurities += securities =>
						{
							if (_instrument == null)
							{
                                // находим инструмент и присваиваем ее переменной _instrument
                                _instrument = securities.FirstOrDefault(sec => sec.Code == secCode && sec.Type == SecurityTypes.Future);

								if (_instrument != null)
								{
									Console.WriteLine("Инструмент появился.");
                                    trader.RegisterQuotes(_instrument); // запускаем экспорт стакана
                                    if (_portfolio != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

                        // подписываемся на событие обновления стакана
                        trader.QuotesChanged += depths =>
                        {
                            if (_depth == null && _instrument != null)
                            {
                                _depth = depths.FirstOrDefault(d => d.Security == _instrument);

                                if (_depth != null)
                                {
                                    Console.WriteLine("Стакан появился.");

                                    if (_portfolio != null && _position != 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);
							}
						};

						Console.WriteLine("Дожидаемся появления в программе инструмента и портфеля {0}...".Put(account));

						// запускаем экспорт по инструментам и портфелям
						trader.StartExport();

						// дожидаемся появления портфеля и инструмента
						waitHandle.WaitOne();

						trader.SecuritiesChanged += securities =>
						{
							// если инструмент хоть раз изменился (по нему пришли актуальные данные)
							if (securities.Contains(_instrument))
								waitHandle.Set();
						};

						Console.WriteLine("Дожидаемся обновления данных по инструменту...");

						// запускаем обновление по инструменту
						trader.RegisterSecurity(_instrument);
						waitHandle.WaitOne();

						// запоминаем первоначальное значение середины спреда
                        var totb = _depth.TotalBidsVolume;
                        var tota = _depth.TotalAsksVolume;

                        int maxaskv = 0;
                        int maxbidv = 0;
                        int maxaskp = 0;
                        int maxbidp = 0;
                        var asks = _depth.Asks;
                        var bids = _depth.Bids;
                        for (int i = 0; i < 50; i++)
                        {
                            if (asks[i].Volume > maxaskv) { maxaskv = (int)asks[i].Volume; maxaskp = (int)asks[i].Price; }
                            if (bids[i].Volume > maxbidv) { maxbidv = (int)bids[i].Volume; maxbidp = (int)bids[i].Price; }
                            //Console.WriteLine("asks {0}", asks[i].Price);
                            //Console.WriteLine("asks {0}", asks[i].Volume);
                        }
                        Console.WriteLine("maxask {0}", maxaskv);
                        Console.WriteLine("maxbid {0}", maxbidv);

						if (_instrument.BestBid == null)
							throw new Exception("Нет лучшего бида для котировки.");

                        Console.WriteLine("общий объем bid {0}", totb);
                        Console.WriteLine("общий объем ask {0}", tota);
                        // objem = _instrument.OpenInterest;
                        //Console.WriteLine("открытые позиции {0}", objem);
                        //Console.WriteLine("asks {0}", asks[0]);

						while (true)
						{
                            var objem = _position.CurrentValue;
                            Console.WriteLine("открытые позиции {0}", objem);


                            _strategy = new buy();
                            _strategy.Start();

                            //Strategy.Start();
                            /*
							// если спред вышел за пределы нашего диапазона
                            if (totb > tota)
                            {
                                var order = new Order
                                {
                                    Portfolio = _portfolio,
                                    Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                                    Security = _instrument,
                                    Volume = 1,
                                    Direction = OrderDirections.Sell,
                                };
                                trader.RegisterOrder(order);
                                Console.WriteLine("Заявка {0} зарегистрирована.", order.Id);
                                //break;
                            }
                            else
                            {
                                var order = new Order
                                {
                                    Portfolio = _portfolio,
                                    Price = _instrument.ShrinkPrice(_instrument.BestBid.Price),
                                    Security = _instrument,
                                    Volume = 1,
                                    Direction = OrderDirections.Buy,
                                };
                                trader.RegisterOrder(order);
                                Console.WriteLine("Заявка {0} зарегистрирована.", order.Id);
                                //break;
                            }
								//Console.WriteLine("Текущее значение середины спреда {0:0.##}", _instrument.BestBid.Price + mid);
                            */
							// ждем 1 секунду
							Thread.Sleep(1000);
						}

						// останавливаем экспорт
						trader.StopExport();
					}
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
			}
		}

        public class buy : Strategy
        {
            public override void OpenPosition()
            {
                var objem = _position.CurrentValue;
                if (objem == 0)
                {
                    // создаем заявку для открытия длинной позиции
                    //var longPos = this.BuyAtMarket();
                    var longPos = new Order
                    {
                        Portfolio = _portfolio,
                        Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                        Security = _instrument,
                        Volume = 1,
                        Direction = OrderDirections.Sell,
                    };

                    // регистрируем правило, отслеживающее появление новых сделок по заявке
                    this
                    .When(longPos.NewTrades())
                    .Do(OnNewOrderTrades)
                    .Periodical(() => longPos.IsMatched());

                    // отправляем заявку на регистрацию
                    RegisterOrder(longPos);
                }
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 40 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 40);

                    // выставляет стоп-лосс в 20 пунктов
                    var stopLoss = new StopLossStrategy(t, 20);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }
	}
}
vfreeman
vfreeman

tmt: сделал вот так, вроде как должно работать, но ошибка ""SampleSmartConsole.Program.buy.OpenPosition()": не найден метод, пригодный для переопределения"

namespace SampleSmartConsole { using System; using System.Net; using System.Linq; using System.Threading; using System.Collections.Generic;

using Ecng.Collections;
using Ecng.Common;

using StockSharp.BusinessEntities;
using StockSharp.Smart;
using StockSharp.Algo;
using StockSharp.Algo.Strategies;

}


возможно не хватает нужного

```csharp
using XXX;

где собственно и реализован метод OpenPosition

на нечто подобное недавно наступал

BigBen
BigBen

сделал вот так, вроде как должно работать, но ошибка ""SampleSmartConsole.Program.buy.OpenPosition()": не найден метод, пригодный для переопределения"

    public class buy : Strategy
    {
        public override void OpenPosition()
        {
             ....................................................
        }
    }

В базовом классе Strategy отсутствует метод OpenPosition(), так что переопределять нечего.

tmt
tmt Author

BigBen: В базовом классе Strategy отсутствует метод OpenPosition(), так что переопределять нечего. Подскажите пожалуйста, как тогда делать? (я это брал из примера http://stocksharp.com/doc/html/63952fce-6e43-4427-985a-1654e8d9cfc1.htm )

возможно не хватает нужного using XXX; Ссылки на сборки все указаны =)

BigBen
BigBen

В указанном примере присутствует следующая строка:

public void OpenPosition()

Модификатор override не указан.

tmt
tmt Author

BigBen: В указанном примере присутствует следующая строка:

public void OpenPosition()

Модификатор override не указан. без нее компилируется программа, но при запуске (видимо как доходит до этого класса) прога вылетает

BigBen
BigBen

Что значит "прога вылетает"?

tmt
tmt Author

BigBen: Что значит "прога вылетает"? ну вообще программа у меня не должна выключаться, а она выключается.. незнаю как это еще объяснить

BigBen
BigBen

Какие сообщения выводятся на консоль? Программа зациклилась? Программа завершает свою работу?

tmt
tmt Author

BigBen: Какие сообщения выводятся на консоль? Программа зациклилась? Программа завершает свою работу? Последнее что должно выводить "открытые позиции" -кол-во купленных акций (очень быстро.. ничего толком не увидишь) Если честно, то я не знаю зациклилась ли она или нет, но она выключается, хотя она не должна выключаться, а должна крутиться в цикле..

Я чуть поже попробую еще посмотреть что это может быть, щас параллельно изучаю сам язык си шарп просто =)

BigBen
BigBen

Чтобы окно не закрывалось, введи после trader.StopExport(); // останавливаем экспорт например, Console.WriteLine("StopExport"); Console.ReadKey(); и после Console.WriteLine(ex); например, Console.WriteLine("catch"); Console.ReadKey();

До нажатия любой клавиши окно не закроется.

tmt
tmt Author

BigBen: Чтобы окно не закрывалось, введи после trader.StopExport(); // останавливаем экспорт например, Console.WriteLine("StopExport"); Console.ReadKey(); и после Console.WriteLine(ex); например, Console.WriteLine("catch"); Console.ReadKey();

До нажатия любой клавиши окно не закроется. Спасибо, я после Console.WriteLine(ex); забыл поставить реадкей.. Вот что выводит

на 247 строке у меня вот что

246  buy _strategy = new buy();
247  _strategy.Start();
Alexander
Alexander

Советую хотя бы раз прочитать документацию. Количество подобных вопросов уменьшится. :) В документации и примерах есть как именно инициализировать, создавать и запускать стратегию.

tmt
tmt Author

А где мне искать, какой шлюз? я почитал, и в примерах шлюз создается ```csharp var trader = new SmartTrader(login, password, ip)

<имя класса> <объект> = new <класс>
BigBen
BigBen

Для начала, в посте http://stocksharp.com/posts/m/15613/ buy _strategy = new buy(); _strategy.Start(); находятся внутри бесконечного цикла while (true)

Эачем?

tmt
tmt Author

BigBen: Для начала, в посте http://stocksharp.com/posts/m/15613/ buy _strategy = new buy(); _strategy.Start(); находятся внутри бесконечного цикла while (true)

Эачем? Из цикла я давно убрал, поставил перед (да и цикл думаю можно убрать, если класс будет повторяться)

BigBen
BigBen

Не знаю, как в последней версии программы, но по тексту в http://stocksharp.com/posts/m/15613/ не видно, чтобы вызывался метод OnStarting(), т.е. отсутствует

protected override void OnStarting()

tmt
tmt Author

BigBen: Не знаю, как в последней версии программы, но по тексту в http://stocksharp.com/posts/m/15613/ не видно, чтобы вызывался метод OnStarting(), т.е. отсутствует

protected override void OnStarting()

protected ProcessResults OnProcess() тоже не было у меня.. А что то должно быть в этом OnStarting() Ниже код последней версии

И спасибо большое что помогаешь!

namespace SampleSmartConsole
{
	using System;
    using System.Net;
	using System.Linq;
	using System.Threading;
    using System.Collections.Generic;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.BusinessEntities;
	using StockSharp.Smart;
	using StockSharp.Algo;
    using StockSharp.Algo.Strategies;

	class Program
	{
		private static Security _instrument;
		private static Portfolio _portfolio;
        private static MarketDepth _depth;
        private static Position _position;
        //private static buy _strategy;

        public class buy : Strategy
        {

            protected override void OnStarting()
            {
                //OpenPosition(); тут вобщем какие то действия при старте (в примере вроде как машки рисует или какие то значения присваивает)
                base.OnStarting();
            }

            protected ProcessResults OnProcess()
            {
                OpenPosition(); //а это уже процесс работы стратегии
                return ProcessResults.Continue;
            }

            public void OpenPosition()
            {
                var objem = _position.CurrentValue;
                if (objem == 0)
                {
                    // создаем заявку для открытия длинной позиции
                    //var longPos = this.BuyAtMarket();
                    var longPos = new Order
                    {
                        Portfolio = _portfolio,
                        Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                        Security = _instrument,
                        Volume = 1,
                        Direction = OrderDirections.Sell,
                    };

                    // регистрируем правило, отслеживающее появление новых сделок по заявке
                    this
                    .When(longPos.NewTrades())
                    .Do(OnNewOrderTrades)
                    .Periodical(() => longPos.IsMatched());

                    // отправляем заявку на регистрацию
                    RegisterOrder(longPos);
                }
                //base.OpenPosition();
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 40 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 40);

                    // выставляет стоп-лосс в 20 пунктов
                    var stopLoss = new StopLossStrategy(t, 20);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }

		static void Main()
		{
			try
			{
				// для теста выбираем бумагу
				const string secCode = "RIH2";

				//Console.Write("Введите логин: ");
				//var login = Console.ReadLine();
                var login = "ST12858";

				//Console.Write("Введите пароль: ");
				//var password = Console.ReadLine();
                var password = "8YDJ7E";

				//Console.Write("Введите номер счета, через который будет выставлена заявка: ");
				//var account = Console.ReadLine();
                var account = "ST12858-RF-01";

                IPAddress ipadress = IPAddress.Parse("95.131.26.246");
                IPEndPoint ip = new IPEndPoint(ipadress, 8090);
                
				using (var waitHandle = new AutoResetEvent(false))
				{
					// создаем шлюз к Smart-у
					using (var trader = new SmartTrader(login, password, ip))
					{
						// подписываемся на событие успешного подключения
						// все действия необходимо производить только после подключения
						trader.Connected += () =>
						{
							Console.WriteLine("Подключение было произведено успешно.");

							// извещаем об успешном соединени
							waitHandle.Set();
						};

						Console.WriteLine("Производим подключение...");

						trader.Connect();

						// дожидаемся события об успешном соединении
						waitHandle.WaitOne();

						// подписываемся на все портфели-счета
						trader.NewPortfolios += portfolios =>
						{
							// необходимое условие работы в SmartCOM
							portfolios.ForEach(trader.RegisterPortfolio);

							if (_portfolio == null)
							{
								_portfolio = portfolios.FirstOrDefault(p => p.Name == account);

								if (_portfolio != null)
								{
									Console.WriteLine("Портфель {0} появился.", account);

                                    if (_instrument != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

						// подписываемся на событие появление инструментов
                        trader.NewPositions += positions =>
                        {
                            if (_position == null)
                            {
                                _position = positions.FirstOrDefault();
                                //_position = positions.FirstOrDefault(sec => sec.Security.Code == secCode);
                                if (_position != null)
                                {
                                    Console.WriteLine("Информация о портфеле появилась.");
                                    if (_portfolio != null && _depth != null && _instrument != null)
                                        waitHandle.Set();
                                }
                            }
                        };
						trader.NewSecurities += securities =>
						{
							if (_instrument == null)
							{
                                // находим инструмент и присваиваем ее переменной _instrument
                                _instrument = securities.FirstOrDefault(sec => sec.Code == secCode && sec.Type == SecurityTypes.Future);

								if (_instrument != null)
								{
									Console.WriteLine("Инструмент появился.");
                                    trader.RegisterQuotes(_instrument); // запускаем экспорт стакана
                                    if (_portfolio != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

                        // подписываемся на событие обновления стакана
                        trader.QuotesChanged += depths =>
                        {
                            if (_depth == null && _instrument != null)
                            {
                                _depth = depths.FirstOrDefault(d => d.Security == _instrument);

                                if (_depth != null)
                                {
                                    Console.WriteLine("Стакан появился.");

                                    if (_portfolio != null && _position != 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);
							}
						};
                        
						Console.WriteLine("Дожидаемся появления в программе инструмента и портфеля {0}...".Put(account));

						// запускаем экспорт по инструментам и портфелям
						trader.StartExport();

						// дожидаемся появления портфеля и инструмента
						waitHandle.WaitOne();

						trader.SecuritiesChanged += securities =>
						{
							// если инструмент хоть раз изменился (по нему пришли актуальные данные)
							if (securities.Contains(_instrument))
								waitHandle.Set();
						};

						Console.WriteLine("Дожидаемся обновления данных по инструменту...");

						// запускаем обновление по инструменту
						trader.RegisterSecurity(_instrument);
						waitHandle.WaitOne();

						// запоминаем первоначальное значение середины спреда
                        var totb = _depth.TotalBidsVolume;
                        var tota = _depth.TotalAsksVolume;

                        int maxaskv = 0;
                        int maxbidv = 0;
                        int maxaskp = 0;
                        int maxbidp = 0;
                        var asks = _depth.Asks;
                        var bids = _depth.Bids;
                        for (int i = 0; i < 50; i++)
                        {
                            if (asks[i].Volume > maxaskv) { maxaskv = (int)asks[i].Volume; maxaskp = (int)asks[i].Price; }
                            if (bids[i].Volume > maxbidv) { maxbidv = (int)bids[i].Volume; maxbidp = (int)bids[i].Price; }
                        }
                        Console.WriteLine("maxask {0}", maxaskv);
                        Console.WriteLine("maxbid {0}", maxbidv);

						if (_instrument.BestBid == null)
							throw new Exception("Нет лучшего бида для котировки.");

                        Console.WriteLine("общий объем bid {0}", totb);
                        Console.WriteLine("общий объем ask {0}", tota);

                        buy _strategy = new buy();
                        _strategy.Start();


                        for (int i = 0; i <= 50; i++)
                        {
                            var objem = _position.CurrentValue;
                            Console.WriteLine("открытые позиции {0}", objem);

                            // ждем 1 секунду
                            Thread.Sleep(1000);
                        }

						// останавливаем экспорт
						trader.StopExport();
                        Console.WriteLine("StopExport");
                        Console.ReadKey();
					}
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
                Console.WriteLine("catch");
                Console.ReadKey();
			}
		}
	}
}
BigBen
BigBen

Почитай про событийную модель, там и пример есть http://stocksharp.com/doc/html/8c0327db-494a-4fe0-aba8-0d4b93dea60e.htm

fau
fau

а почему у вас в процедуре OpenPosition регистрация заявки после ожидания сделок по ней?

tmt
tmt Author

fau: а почему у вас в процедуре OpenPosition регистрация заявки после ожидания сделок по ней? Я взял консольный пример и из него пытаюсь сделать нужное мне, ну и собственно учусь, как это сделать (возможно там куча ошибок, но я с такими простыми разобраться не мог... И спасибо за замечание!)

BigBen, Я походу разобрался! по крайней мере ошибки при запуске нету, посмотрим через пол часика, откроет ли он позицию (ну и собственно СЛ и ТП)

fau
fau

fau: а почему у вас в процедуре OpenPosition регистрация заявки после ожидания сделок по ней? как выяснилось все правильно сначала создается правило, а работать оно будет после регистрации заявки

tmt
tmt Author

fau:

fau: а почему у вас в процедуре OpenPosition регистрация заявки после ожидания сделок по ней? как выяснилось все правильно сначала создается правило, а работать оно будет после регистрации заявки а по поводу ошибки которая сейчас, не знаете как помочь?

tmt
tmt Author

В общем вот так сделал

            protected override void OnStarting()
            {
                this
            .When(base.Security.Changed())
            .Do(OpenPosition);
                //OpenPosition();
                base.OnStarting();
            }

            /*protected ProcessResults OnProcess()
            {
                OpenPosition();
                return ProcessResults.Continue;
            }*/

теперь выводит

на 262 строке _strategy.Start(); а 30 строка. там this из процедуры OnStarting()

Вобщем думаю что проблема с правилами для стратегии.. щас почитаю в докуметакции про правила

fau
fau

похоже не передали в стратегию инструмент попробуйте что-то вроде Strategy _strategy = new buy() ;

tmt
tmt
tmt Author

fau: похоже не передали в стратегию инструмент попробуйте что-то вроде Strategy _strategy = new buy() ; Спасибо огромное! вроде как заработало 😀 завтра протестирую

tmt
tmt Author

Спасибо, все получилось! выложу готовый код, вдруг кому из новеньких понадобится))

namespace SampleSmartConsole
{
	using System;
    using System.Net;
	using System.Linq;
	using System.Threading;
    using System.Collections.Generic;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.BusinessEntities;
	using StockSharp.Smart;
	using StockSharp.Algo;
    using StockSharp.Algo.Strategies;

	class Program
	{
		private static Security _instrument;
		private static Portfolio _portfolio;
        private static MarketDepth _depth;
        private static Position _position;
        //private static buy _strategy;

        public class buy : Strategy
        {
            protected override void OnStarting()
            {
                this
                    .When(Security.MarketDepthChanged())
                    .Do(OpenPosition);

                //OpenPosition();
                base.OnStarting();
            }

            /*protected ProcessResults OnProcess()
            {
                OpenPosition();
                return ProcessResults.Continue;
            }*/

            public void OpenPosition()
            {
                var objem = _position.CurrentValue;
                if (objem == 0)
                {
                    // создаем заявку для открытия длинной позиции
                    //var longPos = this.BuyAtMarket();
                    var longPos = new Order
                    {
                        Portfolio = _portfolio,
                        Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                        Security = _instrument,
                        Volume = 1,
                        Direction = OrderDirections.Sell,
                    };

                    // регистрируем правило, отслеживающее появление новых сделок по заявке
                    this
                    .When(longPos.NewTrades())
                    .Do(OnNewOrderTrades)
                    .Periodical(() => longPos.IsMatched());

                    // отправляем заявку на регистрацию
                    RegisterOrder(longPos);
                }
                //base.OpenPosition();
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 40 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 40);

                    // выставляет стоп-лосс в 20 пунктов
                    var stopLoss = new StopLossStrategy(t, 20);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }

		static void Main()
		{
			try
			{
				// для теста выбираем бумагу
				const string secCode = "RIH2";

				//Console.Write("Введите логин: ");
				//var login = Console.ReadLine();
                var login = "ST12858";

				//Console.Write("Введите пароль: ");
				//var password = Console.ReadLine();
                var password = "8YDJ7E";

				//Console.Write("Введите номер счета, через который будет выставлена заявка: ");
				//var account = Console.ReadLine();
                var account = "ST12858-RF-01";

                IPAddress ipadress = IPAddress.Parse("95.131.26.246");
                IPEndPoint ip = new IPEndPoint(ipadress, 8090);
                
				using (var waitHandle = new AutoResetEvent(false))
				{
					// создаем шлюз к Smart-у
					using (var trader = new SmartTrader(login, password, ip))
					{
						// подписываемся на событие успешного подключения
						// все действия необходимо производить только после подключения
						trader.Connected += () =>
						{
							Console.WriteLine("Подключение было произведено успешно.");

							// извещаем об успешном соединени
							waitHandle.Set();
						};

						Console.WriteLine("Производим подключение...");

						trader.Connect();

						// дожидаемся события об успешном соединении
						waitHandle.WaitOne();

						// подписываемся на все портфели-счета
						trader.NewPortfolios += portfolios =>
						{
							// необходимое условие работы в SmartCOM
							portfolios.ForEach(trader.RegisterPortfolio);

							if (_portfolio == null)
							{
								_portfolio = portfolios.FirstOrDefault(p => p.Name == account);

								if (_portfolio != null)
								{
									Console.WriteLine("Портфель {0} появился.", account);

                                    if (_instrument != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

						// подписываемся на событие появление инструментов
                        trader.NewPositions += positions =>
                        {
                            if (_position == null)
                            {
                                _position = positions.FirstOrDefault();
                                //_position = positions.FirstOrDefault(sec => sec.Security.Code == secCode);
                                if (_position != null)
                                {
                                    Console.WriteLine("Информация о портфеле появилась.");
                                    if (_portfolio != null && _depth != null && _instrument != null)
                                        waitHandle.Set();
                                }
                            }
                        };
						trader.NewSecurities += securities =>
						{
							if (_instrument == null)
							{
                                // находим инструмент и присваиваем ее переменной _instrument
                                _instrument = securities.FirstOrDefault(sec => sec.Code == secCode && sec.Type == SecurityTypes.Future);

								if (_instrument != null)
								{
									Console.WriteLine("Инструмент появился.");
                                    trader.RegisterQuotes(_instrument); // запускаем экспорт стакана
                                    if (_portfolio != null && _depth != null && _position != null)
										waitHandle.Set();
								}
							}
						};

                        // подписываемся на событие обновления стакана
                        trader.QuotesChanged += depths =>
                        {
                            if (_depth == null && _instrument != null)
                            {
                                _depth = depths.FirstOrDefault(d => d.Security == _instrument);

                                if (_depth != null)
                                {
                                    Console.WriteLine("Стакан появился.");

                                    if (_portfolio != null && _position != 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);
							}
						};
                        
						Console.WriteLine("Дожидаемся появления в программе инструмента и портфеля {0}...".Put(account));

						// запускаем экспорт по инструментам и портфелям
						trader.StartExport();

						// дожидаемся появления портфеля и инструмента
						waitHandle.WaitOne();

						trader.SecuritiesChanged += securities =>
						{
							// если инструмент хоть раз изменился (по нему пришли актуальные данные)
							if (securities.Contains(_instrument))
								waitHandle.Set();
						};

						Console.WriteLine("Дожидаемся обновления данных по инструменту...");

						// запускаем обновление по инструменту
						trader.RegisterSecurity(_instrument);
						waitHandle.WaitOne();

						// запоминаем первоначальное значение середины спреда
                        var totb = _depth.TotalBidsVolume;
                        var tota = _depth.TotalAsksVolume;

                        int maxaskv = 0;
                        int maxbidv = 0;
                        int maxaskp = 0;
                        int maxbidp = 0;
                        var asks = _depth.Asks;
                        var bids = _depth.Bids;
                        for (int i = 0; i < 50; i++)
                        {
                            if (asks[i].Volume > maxaskv) { maxaskv = (int)asks[i].Volume; maxaskp = (int)asks[i].Price; }
                            if (bids[i].Volume > maxbidv) { maxbidv = (int)bids[i].Volume; maxbidp = (int)bids[i].Price; }
                            //Console.WriteLine("asks {0}", asks[i].Price);
                            //Console.WriteLine("asks {0}", asks[i].Volume);
                        }
                        Console.WriteLine("maxask {0}", maxaskv);
                        Console.WriteLine("maxbid {0}", maxbidv);

						if (_instrument.BestBid == null)
							throw new Exception("Нет лучшего бида для котировки.");

                        Console.WriteLine("общий объем bid {0}", totb);
                        Console.WriteLine("общий объем ask {0}", tota);

                        buy _strategy = new buy()
                        {
                            Volume = 1,
                            Portfolio = _portfolio,
                            Security = _instrument,
                            Trader = trader
                        };
                        _strategy.Start();


                        //for (int i = 0; i <= 50; i++)
                        while(true)
                        {
                            var objem = _position.CurrentValue;
                            Console.WriteLine("открытые позиции {0}", objem);

                            // ждем 1 секунду
                            Thread.Sleep(1000);
                        }

						// останавливаем экспорт
						trader.StopExport();
                        Console.WriteLine("StopExport");
                        Console.ReadKey();
					}
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
                Console.WriteLine("catch");
                Console.ReadKey();
			}
		}
	}
}
tmt
tmt Author

Вновь хочу вернуться к этой теме, т.к. у меня СЛ не срабатывает! (заявка то выставляется, но цена уже уша от нее.. и позиция может уйти далеко в минус!) В чем может быть ошибка? на форуме где то читал, что у кого то закрывало минус 190, когда СЛ всего 10.. а у меня не закрывает

        public class buy : Strategy
        {
            int i;
            protected override void OnStarting()
            {
                this
                    .When(Security.MarketDepthChanged())
                    .Do(str);

                base.OnStarting();
            }

            public void str()
            {

                var totb = _depth.TotalBidsVolume;// общий объем продажи
                var tota = _depth.TotalAsksVolume;// общий объем покупки

                int maxaskv = 0;// максимальная покупка по объему
                int maxbidv = 0;// максимальная продажа по объему
                int maxaskp = 0;// цена максимальной продажи по объему
                int maxbidp = 0;// цена максимальной покупки по объему
                var asks = _depth.Asks;
                var bids = _depth.Bids;
                for (int i = 0; i < 50; i++)
                {
                    if (asks[i].Volume > maxaskv) { maxaskv = (int)asks[i].Volume; maxaskp = (int)asks[i].Price;  }
                    if (bids[i].Volume > maxbidv) { maxbidv = (int)bids[i].Volume; maxbidp = (int)bids[i].Price;  }
                }

                var objem = _position.CurrentValue;

                if (objem != 0)
                {
                    i = 0;
                }

                if (i == 1)
                {
                    if ((_instrument.BestBid.Price - posPrice >= 50 && pos == 0) || (posPrice - _instrument.BestAsk.Price >= 50 && pos == 1))
                    {
                        var orderClose = Trader.Orders.First(o => o.Id == posId);
                        
                        /* получаем статус заявки */
                        int stateOrderClose = (int)orderClose.State; 
                        /*
                         * 0 - Не отправлена в торговую систему.
                         * 1 - Заявка принята биржей и активна.
                         * 2 - Заявка больше не активна на бирже (была полностью удовлетворена или снята из программы). 
                         * 3 - Заявка не принята торговой системой.
                        */

                        if (stateOrderClose == 1)
                        {
                            Trader.CancelOrder(orderClose);
                        }
                        if (stateOrderClose == 2)
                        {
                            i = 0;
                        }
                    }
                }

                if (objem == 0 && i == 0)
                {
                    i = 1;
                    if (totb > tota) // если общий объем продаж больше покупок, то продаем
                    {
                        if ()
                        {
                            shortPos();
                        }
                    }
                    else
                    {
                        if ()
                        {
                            longPos();
                        }
                    }
                }
            }

            public void longPos()
            {
                // создаем заявку для открытия длинной позиции
                var longPos = new Order
                {
                    Portfolio = _portfolio,
                    Price = _instrument.ShrinkPrice(_instrument.BestBid.Price),
                    Security = _instrument,
                    Volume = 1,
                    Direction = OrderDirections.Buy,
                };

                // регистрируем правило, отслеживающее появление новых сделок по заявке
                this
                .When(longPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => longPos.IsMatched());

                // отправляем заявку на регистрацию
                RegisterOrder(longPos);
                pos = 0;
                posPrice = _instrument.BestBid.Price;
            }

            public void shortPos()
            {
                // создаем заявку для открытия длинной позиции
                var shortPos = new Order
                {
                    Portfolio = _portfolio,
                    Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                    Security = _instrument,
                    Volume = 1,
                    Direction = OrderDirections.Sell,
                };

                // регистрируем правило, отслеживающее появление новых сделок по заявке
                this
                .When(shortPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => shortPos.IsMatched());

                // отправляем заявку на регистрацию
                RegisterOrder(shortPos);
                pos = 1;
                posPrice = _instrument.BestAsk.Price;
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 100 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 100);

                    // выставляет стоп-лосс в 50 пунктов
                    var stopLoss = new StopLossStrategy(t, 50);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }

Спасибо

BigBen
BigBen

Что-то ты намутил с int i. В for это переменная цикла, в if-ах принимает два значения - 0 и 1, т.е. в них это логическая переменная. Если (var objem = _position.CurrentValue) == 0, то чему равно i ? Какой из if-ов выполнится?

tmt
tmt Author

Насчет цикла я и не заметил, что там тоже i.. А вообще с помощью i я проверяю есть ли отложники (если есть, то 1, нет 2), а когда позиция не равна 0, то i=0 (те считаем что у нас нету отложников)

tmt
tmt Author

Вот в общем какая позиция у меня😌 У стратегии снова стоп в 50 пунктов, а на скрине минус в 5 раз больше его. и как видно в стакане висит заявка - это и есть стоп.. Помогите разобраться пожалуйста, может я как то не так стаканы объявляю или еще что?

Вот это весь код программы (точнее тока 1 файл, где все происходит) Не много прокоментировал, чтобы было понятнее разбирать мой замысел весь.

namespace SampleSmart
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Windows;
	using MessageBox = System.Windows.MessageBox;
    using System.Net;
    using System.Threading;

    using System.Linq;

    using Ecng.Collections;
    using Ecng.Common;

    using StockSharp.BusinessEntities;
    using StockSharp.Smart;
    using StockSharp.Algo;
    using StockSharp.Algo.Strategies;

	using Ecng.Xaml;

	public partial class MainWindow
	{
		private bool _isConnected;
        private bool _str = false;

		public SmartTrader Trader;

		private readonly SecuritiesWindow _securitiesWindow = new SecuritiesWindow();
		private readonly TradesWindow _tradesWindow = new TradesWindow();
		private readonly MyTradesWindow _myTradesWindow = new MyTradesWindow();
		private readonly OrdersWindow _ordersWindow = new OrdersWindow();
		private readonly PortfoliosWindow _portfoliosWindow = new PortfoliosWindow();
		private readonly PositionsWindow _positionsWindow = new PositionsWindow();
		private readonly StopOrdersWindow _stopOrdersWindow = new StopOrdersWindow();

        private static Security _instrument;
        private static Portfolio _portfolio;
        private static MarketDepth _depth;
        private static Position _position;
        buy _strategy;

        static int pos = 2; // 0 - buy; 1 - sell
        static decimal posPrice = 0;
        static long posId;

        public class buy : Strategy
        {
            int i;
            protected override void OnStarting()
            {
                this
                    .When(Security.MarketDepthChanged())
                    .Do(str);

                base.OnStarting();
            }

            public void str()
            {

                var totb = _depth.TotalBidsVolume;// общий объем покупки
                var tota = _depth.TotalAsksVolume;// общий объем продажи

                if (_position.CurrentValue != 0) // если позиция не равна 0, то будем считать, что заявок у нас нету
                {
                    i = 0;
                }

                if (i == 1) // если заявка есть, то...
                {
                    if ((_instrument.BestBid.Price - posPrice >= 50 && pos == 0) || (posPrice - _instrument.BestAsk.Price >= 50 && pos == 1)) // если цена ушла от заявки на 50 и более пунктов то закрываем ее
                    {
                        var orderClose = Trader.Orders.First(o => o.Id == posId);
                        
                        /* получаем статус заявки */
                        int stateOrderClose = (int)orderClose.State; 
                        /*
                         * 0 - Не отправлена в торговую систему.
                         * 1 - Заявка принята биржей и активна.
                         * 2 - Заявка больше не активна на бирже (была полностью удовлетворена или снята из программы). 
                         * 3 - Заявка не принята торговой системой.
                        */

                        if (stateOrderClose == 1)
                        {
                            Trader.CancelOrder(orderClose);
                        }
                        if (stateOrderClose == 2)
                        {
                            i = 0;
                        }
                    }
                }

                if (_position.CurrentValue == 0 && i == 0)
                {
                    if (totb > tota) // если общий объем покупок больше продаж, то продаем
                    {
                            i = 1;
                            shortPos();
                    }
                    else
                    {
                            i = 1;
                            longPos();
                    }
                }
            }

            public void longPos()
            {
                // создаем заявку для открытия длинной позиции
                var longPos = new Order
                {
                    Portfolio = _portfolio,
                    Price = _instrument.ShrinkPrice(_instrument.BestBid.Price),
                    Security = _instrument,
                    Volume = 1,
                    Direction = OrderDirections.Buy,
                };

                // регистрируем правило, отслеживающее появление новых сделок по заявке
                this
                .When(longPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => longPos.IsMatched());

                // отправляем заявку на регистрацию
                RegisterOrder(longPos);
                pos = 0;
                posPrice = _instrument.BestBid.Price;
            }

            public void shortPos()
            {
                // создаем заявку для открытия длинной позиции
                var shortPos = new Order
                {
                    Portfolio = _portfolio,
                    Price = _instrument.ShrinkPrice(_instrument.BestAsk.Price),
                    Security = _instrument,
                    Volume = 1,
                    Direction = OrderDirections.Sell,
                };

                // регистрируем правило, отслеживающее появление новых сделок по заявке
                this
                .When(shortPos.NewTrades())
                .Do(OnNewOrderTrades)
                .Periodical(() => shortPos.IsMatched());

                // отправляем заявку на регистрацию
                RegisterOrder(shortPos);
                pos = 1;
                posPrice = _instrument.BestAsk.Price;
            }

            private void OnNewOrderTrades(IEnumerable<MyTrade> trades)
            {
                // для каждой сделки добавляем для защитную пару стратегии
                var protectiveStrategies = trades.Select(t =>
                {
                    // выставляет тейк-профит в 100 пунктов
                    var takeProfit = new TakeProfitStrategy(t, 100);

                    // выставляет стоп-лосс в 50 пунктов
                    var stopLoss = new StopLossStrategy(t, 50);

                    return new TakeProfitStopLossStrategy(takeProfit, stopLoss);
                });

                ChildStrategies.AddRange(protectiveStrategies);
            }
        }

		public MainWindow()
		{
			InitializeComponent();

			_ordersWindow.MakeHideable();
			_myTradesWindow.MakeHideable();
			_tradesWindow.MakeHideable();
			_securitiesWindow.MakeHideable();
			_stopOrdersWindow.MakeHideable();
			_portfoliosWindow.MakeHideable();
            _positionsWindow.MakeHideable();


			MainWindow.Instance = this;
		}
        
		protected override void OnClosing(CancelEventArgs e)
		{
			_ordersWindow.DeleteHideable();
			_myTradesWindow.DeleteHideable();
			_tradesWindow.DeleteHideable();
			_securitiesWindow.DeleteHideable();
			_stopOrdersWindow.DeleteHideable();
			_portfoliosWindow.DeleteHideable();
			_positionsWindow.DeleteHideable();
			
			_securitiesWindow.Close();
			_tradesWindow.Close();
			_myTradesWindow.Close();
			_stopOrdersWindow.Close();
			_ordersWindow.Close();
			_portfoliosWindow.Close();
			_positionsWindow.Close();

			if (Trader != null)
				Trader.Dispose();

			base.OnClosing(e);
		}

		public static MainWindow Instance { get; private set; }

		private void Connect_Click(object sender, RoutedEventArgs e)
		{
			if (!_isConnected)
			{
                // для теста выбираем бумагу
                const string secCode = "RIH2";

                //Console.Write("Введите логин: ");
                //var login = Console.ReadLine();
                var login = "ST12858";

                //Console.Write("Введите пароль: ");
                //var password = Console.ReadLine();
                var password = "8YDJ7E";

                //Console.Write("Введите номер счета, через который будет выставлена заявка: ");
                //var account = Console.ReadLine();
                var account = "ST12858-RF-01";

                IPAddress ipadress = IPAddress.Parse("95.131.26.246");
                IPEndPoint ip = new IPEndPoint(ipadress, 8090);

				if (Trader == null)
				{
					// создаем шлюз
                    Trader = new SmartTrader(login, password, ip);

					// инициализируем механизм переподключения (будет автоматически соединяться
					// каждые 10 секунд, если шлюз потеряется связь с сервером)
					Trader.ReConnectionSettings.Interval = TimeSpan.FromSeconds(10);
					Trader.ReConnectionSettings.WorkingTime = Exchange.Rts.WorkingTime;
					Trader.ReConnectionSettings.ConnectionRestored += () => this.GuiAsync(() =>
					{
						// разблокируем кнопку Экспорт (соединение было восстановлено)
						ChangeConnectStatus(true);
						MessageBox.Show(this, "Соединение восстановлено.");
					});

					// подписываемся на событие успешного соединения
					Trader.Connected += () =>
					{
						// возводим флаг, что соединение установлено
						_isConnected = true;

						// разблокируем кнопку Экспорт
						this.GuiAsync(() => ChangeConnectStatus(true));
					};

					// подписываемся на событие разрыва соединения
					Trader.ConnectionError += error => this.GuiAsync(() =>
					{
						// заблокируем кнопку Экспорт (так как соединение было потеряно)
						ChangeConnectStatus(false);

						MessageBox.Show(this, error.ToString(), "Ошибка соединения");	
					});

					Trader.ProcessDataError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));

					Trader.NewSecurities += securities => this.GuiAsync(() => _securitiesWindow.AddSecurities(securities));
					Trader.NewMyTrades += trades => this.GuiAsync(() => _myTradesWindow.Trades.AddRange(trades));
					Trader.NewTrades += trades => this.GuiAsync(() => _tradesWindow.Trades.AddRange(trades));
					Trader.NewOrders += orders => this.GuiAsync(() => _ordersWindow.Orders.AddRange(orders));
					Trader.NewStopOrders += orders => this.GuiAsync(() => _stopOrdersWindow.Orders.AddRange(orders));
					Trader.NewPortfolios += portfolios =>
					{
						// регистрирует портфели на обновление данных
						portfolios.ForEach(Trader.RegisterPortfolio);

						_portfoliosWindow.Portfolios.AddRange(portfolios);
					};
					Trader.NewPositions += positions => this.GuiAsync(() => _positionsWindow.Positions.AddRange(positions));

					// подписываемся на событие о неудачной регистрации заявок
					Trader.OrdersRegisterFailed += OrdersFailed;
					// подписываемся на событие о неудачном снятии заявок
					Trader.OrdersCancelFailed += OrdersFailed;

					// подписываемся на событие о неудачной регистрации стоп-заявок
					Trader.StopOrdersRegisterFailed += OrdersFailed;
					// подписываемся на событие о неудачном снятии стоп-заявок
					Trader.StopOrdersCancelFailed += OrdersFailed;

					ShowSecurities.IsEnabled = ShowTrades.IsEnabled =
					ShowMyTrades.IsEnabled = ShowOrders.IsEnabled = 
					ShowPortfolios.IsEnabled = ShowStopOrders.IsEnabled = true;
				}

				Trader.Connect();

                var waitHandle = new AutoResetEvent(false);

                // подписываемся на все портфели-счета
                Trader.NewPortfolios += portfolios =>
                {
                    // необходимое условие работы в SmartCOM
                    portfolios.ForEach(Trader.RegisterPortfolio);

                    if (_portfolio == null)
                    {
                        _portfolio = portfolios.FirstOrDefault(p => p.Name == account);
                    }
                };

                // подписываемся на событие появление инструментов
                Trader.NewPositions += positions =>
                {
                    if (_position == null)
                    {
                        _position = positions.FirstOrDefault();
                    }
                };
                Trader.NewSecurities += securities =>
                {
                    if (_instrument == null)
                    {
                        // находим инструмент и присваиваем ее переменной _instrument
                        _instrument = securities.FirstOrDefault(sec => sec.Code == secCode && sec.Type == SecurityTypes.Future);

                        if (_instrument != null)
                        {
                            Trader.RegisterQuotes(_instrument); // запускаем экспорт стакана
                        }
                    }
                };

                // подписываемся на событие обновления стакана
                Trader.QuotesChanged += depths =>
                {
                    if (_depth == null && _instrument != null)
                    {
                        _depth = depths.FirstOrDefault(d => d.Security == _instrument);
                    }
                };

                Trader.NewOrders += myTrades =>
						{
							foreach (var myTrade in myTrades)
							{
								var trade = myTrade;
								//Console.WriteLine("Сделка {0} по цене {1} по бумаге {2} по объему {3} в {4}.{5}", trade.Id, trade.Price, trade.Security.Code, trade.Volume, trade.Time, trade.Direction);
                                int _pos = (int)trade.Direction;
                                if (posPrice == trade.Price && pos == _pos)
                                {
                                    posId = trade.Id;
                                }
							}
						};
			}
			else
			{
				Trader.Disconnect();
			}
		}

		private void OrdersFailed(IEnumerable<OrderFail> fails)
		{
			this.GuiAsync(() =>
			{
				foreach (var fail in fails)
					MessageBox.Show(this, fail.Error.ToString(), "Ошибка регистрации заявки");
			});
		}

		private void ShowSecurities_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_securitiesWindow);
		}

		private void ShowTrades_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_tradesWindow);
		}

		private void ShowMyTrades_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_myTradesWindow);
		}

		private void ShowOrders_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_ordersWindow);
		}

		private void ShowPortfolios_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_portfoliosWindow);
			ShowOrHide(_positionsWindow);
		}

		private void ShowStopOrders_Click(object sender, RoutedEventArgs e)
		{
			ShowOrHide(_stopOrdersWindow);
		}

		private static void ShowOrHide(Window window)
		{
			if (window == null)
				throw new ArgumentNullException("window");

			if (window.Visibility == Visibility.Visible)
				window.Hide();
			else
				window.Show();
		}

        private void StrStart_Click(object sender, RoutedEventArgs e)
        {
            if (_str == false)
            {
                _strategy = new buy()
                {
                    Volume = 1,
                    Portfolio = _portfolio,
                    Security = _instrument,
                    Trader = Trader
                };
                _strategy.Start();
                _str = true;
                StrStart.Content = "Стоп";
            }
            else
            {
                _strategy.Stop();
                _str = false;
                StrStart.Content = "Старт";
            }
        }

        private void ChangeConnectStatus(bool isConnected)
		{
			_isConnected = isConnected;
			ConnectBtn.Content = isConnected ? "Отключиться" : "Подключиться";
            StrStart.IsEnabled = isConnected;
            if (isConnected == false && _str == true)
            {
                _strategy.Stop();
                StrStart.Content = "Старт";
                
            }
            if (isConnected == true)
            {
                Trader.StartExport();
            }
		}
	}
}

Спасибо большое

ak
ak

Сильно не вникал, но, вероятно, самая простая ситуация:

  1. Сработал стоп, ордер был выставлен
  2. Цена перешагнула ордер и ушла ниже
  3. Твоя заявка как висела так и висит, стратегия не завершилась, но и ничего не предпринимает - и не должна.

Один из выходов - использовать котирование в StopLoss стратегии:


var stopLoss = new StopLossStrategy(trade, StopLossUnit) { UseQuoting = true };

У меня есть открытая проблема с этим способом в Quik, http://stocksharp.com/posts/m/16132/, может в Smart'е дела обстоят лучше.

Другой - использовать свойство StopLossStrategy (точнее ProtectiveStrategy) - PriceOffset, читать тут: http://stocksharp.com/doc/html/P_StockSharp_Algo_Strategies_ProtectiveStrategy_PriceOffset.htm

Пример:


var stopLoss = new StopLossStrategy(trade, StopLossUnit) { PriceOffset = 20 };

tmt
tmt
tmt Author

т.е. это нормально, понял😒 2ой выход думаю мониторить позицию.. логичнее будет) Спасибо, что посмотрели