takeprofit & stoploss
Atom Ответить
11.01.2012


tmt

Фотография
BigGrin я наверное уже замучал))
Вот из этого примера https://www.stocksharp.co...27-985a-1654e8d9cfc1.htm не понятно мне, сл и тп для общей позиции устанавливается? (просто когда ставим там сл и тп, мы нигде не упоминаем longPos)
И есть ли где рабочий пример, так проще понять.

Теги:


Спасибо:




41 Ответов
< 1 2 
tmt

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


BigBen Перейти
Не знаю, как в последней версии программы, но по тексту в https://stocksharp.ru/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

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


Почитай про событийную модель, там и пример есть
https://stocksharp.ru/do...e0-aba8-0d4b93dea60e.htm
Спасибо:

fau

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


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

tmt

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


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

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

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

tmt

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


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

Код
            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

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


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

как выяснилось все правильно
сначала создается правило, а работать оно будет после регистрации заявки
Спасибо:

tmt

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


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

как выяснилось все правильно
сначала создается правило, а работать оно будет после регистрации заявки

а по поводу ошибки которая сейчас, не знаете как помочь?
Автор топика
Спасибо:

fau

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


похоже не передали в стратегию инструмент
попробуйте что-то вроде
Strategy _strategy = new buy()
{
Volume = 1,
Portfolio = portfolio,
Security = security,
Trader = _trader
};
Спасибо: tmt

tmt

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


fau Перейти
похоже не передали в стратегию инструмент
попробуйте что-то вроде
Strategy _strategy = new buy()
{
Volume = 1,
Portfolio = portfolio,
Security = security,
Trader = _trader
};

Спасибо огромное! вроде как заработало BigGrin завтра протестирую
Автор топика
Спасибо:

tmt

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


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

Код
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

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


Вновь хочу вернуться к этой теме, т.к. у меня СЛ не срабатывает! (заявка то выставляется, но цена уже уша от нее.. и позиция может уйти далеко в минус!) В чем может быть ошибка? на форуме где то читал, что у кого то закрывало минус 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

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


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

tmt

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


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

tmt

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



Вот в общем какая позиция у меняMellow У стратегии снова стоп в 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

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


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

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


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

Код

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


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

Другой - использовать свойство StopLossStrategy (точнее ProtectiveStrategy) - PriceOffset, читать тут:
https://stocksharp.ru/do...Strategy_PriceOffset.htm

Пример:
Код

var stopLoss = new StopLossStrategy(trade, StopLossUnit) { PriceOffset = 20 };
Спасибо: tmt

tmt

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


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

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

loading
clippy