S#.Shell. Manual
Atom
14.10.2013
Kazai Mazai


Часть 1. Starting up


Первым делом неплохо было бы разобраться с коннекторами.

Уже есть Альфадирект и Квик. Мне бы хотелось подрубить свой кастомный для IB. Но незадача: В каркасе старая версия S#.
Это грозит проблемами в работе с гидрой и коннекторами. У меня возникли сразу, потому что коннектор был на 4.1.19.1.

Значит заодно и обновлюсь.

Удаляю все, что связано со stocksharp и Ecng из reference, и добавляю заново все свежее.
У меня вот такой список получился.

1


После обновления, ничего не заработает.

Поправил в ConnectionEngine для квика и для альфа аналогично.

2


После ребилда все должно взлететь.

Добавил, естественно, нужные Refercences, и создание коннектора по аналогии.

3

4


Настройки. Тут есть целый менеджер настроек, который отвечает за сохранение, и т.д.

Добавил в список коннекторов и нужные настройки в SettingsProperties


5

6


Ну вот и все.


7

7






Спасибо: Churchill


1 2 3  >
Kazai Mazai

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


Часть 2. Почва для удобного добавления стратегий.

В прошлый раз я немного поторопился с обновлением версии S#. Нашлись кое-какие неполадки в коннекторе и пришлось откатиться. Тем не менее, там все актуально за исключением парочки нюансов при создании новых подключений. Главное делать по аналогии, и все будет хорошо[thumbup]


Добавил базовые свойства стратегии.

Код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using StockSharp.BusinessEntities;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;

namespace Robot
{
  public class BaseStrategyProperties:INotifyPropertyChanged
	{
		private string _name = "Новая стратегия";
		private string _security = "TEST@TEST";
		private string _portfolio = "TEST_PORTFOLIO";
        private decimal _volume = 1;

        private Dictionary<long, Order> _ordersByTransactionId = new Dictionary<long, Order>();
        private Dictionary<long, Security> _securitiesByTransactionId = new Dictionary<long, Security>();
        private Dictionary<long, Portfolio> _portfoliosByTransactionId = new Dictionary<long, Portfolio>();
        private Dictionary<long, IEnumerable<Trade>> _tradesByTransactionId = new Dictionary<long, IEnumerable<Trade>>();
        private Dictionary<long, Exchange> _exchangesByTransactionId = new Dictionary<long, Exchange>();

		private bool _schedulerIsEnabled;
		private List<TimeRangeProperties> _schedule = new List<TimeRangeProperties>(10);
 

		[DisplayName(@"Название")]
		[Description(@"Название стратегии")]
		[Category(@"Основные")]
		//[CategoryOrder(0)]
		[PropertyOrder(0)]
		public string Name
		{
			get { return _name; }
			set
			{
				_name = value;
				OnPropertyChanged("Name");
			}
		}

		[DisplayName(@"Инструмент")]
		[Description(@"Код торгового инструмента")]
		[Category(@"Основные")]
		//[CategoryOrder(0)]
		[PropertyOrder(1)]
		[Editor(typeof(SecurityIdEditor), typeof(SecurityIdEditor))]
		public string Security
		{
			get { return _security; }
			set
			{
				_security = value;
				OnPropertyChanged("Security");
			}
		}

		[DisplayName(@"Портфель")]
		[Description(@"Имя портфеля")]
		[Category(@"Основные")]
		//[CategoryOrder(0)]
		[PropertyOrder(3)]
		[Editor(typeof(PortfolioNameEditor), typeof(PortfolioNameEditor))]
		public string Portfolio
		{
			get { return _portfolio; }
			set
			{
				_portfolio = value;
				OnPropertyChanged("Portfolio");
			}
		}

        [DisplayName(@"Объем")]
        [Description(@"Объем для открытия позиций")]
        [Category(@"Основные")]
        //[CategoryOrder(0)]
        [PropertyOrder(4)]
        public decimal Volume
        {
            get { return _volume; }
            set
            {
                if (value < 0)
                {
                    return;
                }

                _volume = value;
                OnPropertyChanged("Volume");
            }
        }

 
 

		[Category(@"Планировщик")]
		//[CategoryOrder(5)]
		[DisplayName(@"Включен")]
		[Description(@"Включен ли запуск по расписанию для данной стратегии.")]
		[PropertyOrder(0)]
		public bool SchedulerIsEnabled
		{
			get { return _schedulerIsEnabled; }
			set
			{
				_schedulerIsEnabled = value;
				OnPropertyChanged("SchedulerIsEnabled");
			}
		}

		[Category(@"Планировщик")]
		//[CategoryOrder(5)]
		[DisplayName(@"Время работы")]
		[Description(@"Настройка времени автоматической работы стратегии.")]
		[PropertyOrder(1)]
		[Editor(typeof(ScheduleEditor), typeof(ScheduleEditor))]
		public List<TimeRangeProperties> Schedule
		{
			get { return _schedule; }
			set
			{
				_schedule = value;
				OnPropertyChanged("Schedule");
			}
		}

        [DisplayName(@"ОрдерПоАйдиТранзакции")]
        [Description(@"ОрдерПоАйдиТранзакции")]
        [Category(@"Для работы")]
        [PropertyOrder(0)]
        public Dictionary<long, Order> OrdersByTransactionId
        {
            get { return _ordersByTransactionId; }
            set
            {
                _ordersByTransactionId = value;
                OnPropertyChanged("OrdersByTransactionId");
            }
        }

        [DisplayName(@"ИнструментПоАйдиТранзакции")]
        [Description(@"ИнструментПоАйдиТранзакции")]
        [Category(@"Для работы")]
        [PropertyOrder(0)]
        public Dictionary<long, Security> SecuritiesByTransactionId
        {
            get { return _securitiesByTransactionId; }
            set
            {
                _securitiesByTransactionId = value;
                OnPropertyChanged("SecuritiesByTransactionId");
            }
        }

        [DisplayName(@"СделкиПоАйдиТранзакции")]
        [Description(@"СделкиПоАйдиТранзакции")]
        [Category(@"Для работы")]
        [PropertyOrder(0)]
        public Dictionary<long, IEnumerable<Trade>> TradesByTransactionId
        {
            get { return _tradesByTransactionId; }
            set
            {
                _tradesByTransactionId = value;
                OnPropertyChanged("TradesByTransactionId");
            }
        }

        [DisplayName(@"ПортфелиПоАйдиТранзакции")]
        [Description(@"ПортфелиПоАйдиТранзакции")]
        [Category(@"Для работы")]
        [PropertyOrder(0)]
        public Dictionary<long, Portfolio> PortfoliosByTransactionId
        {
            get { return _portfoliosByTransactionId; }
            set
            {
                _portfoliosByTransactionId = value;
                OnPropertyChanged("PortfoliosByTransactionId");
            }
        }
        [DisplayName(@"БиржиПоАйдиТранзакции")]
        [Description(@"БиржиПоАйдиТранзакции")]
        [Category(@"Для работы")]
        [PropertyOrder(0)]
        public Dictionary<long, Exchange> ExchangesByTransactionId
        {
            get { return _exchangesByTransactionId; }
            set
            {
                _exchangesByTransactionId = value;
                OnPropertyChanged("ExchangesByTransactionId");
            }
        }

       
		public event PropertyChangedEventHandler PropertyChanged;

		public void OnPropertyChanged(string name)
		{
			var handler = PropertyChanged;
			if (handler != null)
			{
				handler(this, new PropertyChangedEventArgs(name));
			}
		}
	}
}



и базовую стратегию, восстанавливающую ордера,сделки и позиции при перезапуске.

Код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockSharp.Algo;
using StockSharp.BusinessEntities;

namespace Robot.Base
{
   public class BaseSavingStatesStrategy: BaseStrategy
    {
       public BaseStrategyProperties Params { set; get; }
       private bool _isFirstStart;

       public BaseSavingStatesStrategy()
       {
           _isFirstStart = true;

       }

       protected void SaveStateToParams()
       {

           foreach (var order in Orders)
           {
               var transactionId = order.TransactionId;
               if (Params.OrdersByTransactionId.ContainsKey(transactionId))
               {
                   Params.OrdersByTransactionId[transactionId] = order;
               }
               else
               {
                   Params.OrdersByTransactionId.Add(transactionId, order);
               }

               var myTrades = order.GetTrades();
               List<Trade> trades = new List<Trade>();
               foreach (var myTrade in myTrades)
               {
                   trades.Add(myTrade.Trade);
               }
               if (Params.TradesByTransactionId.ContainsKey(transactionId))
               {
                   Params.TradesByTransactionId[transactionId] = trades;
               }
               else
               {
                   Params.TradesByTransactionId.Add(transactionId, trades);
               }

               if (Params.SecuritiesByTransactionId.ContainsKey(transactionId))
               {
                   Params.SecuritiesByTransactionId[transactionId] = order.Security;
               } 
               else
               {
                   Params.SecuritiesByTransactionId.Add(transactionId, order.Security);
               }
               if (Params.ExchangesByTransactionId.ContainsKey(transactionId))
               {
                   Params.ExchangesByTransactionId[transactionId] = order.Security.ExchangeBoard.Exchange;
               }
               else
               {
                   Params.ExchangesByTransactionId.Add(transactionId, order.Security.ExchangeBoard.Exchange);
               }
               if (Params.PortfoliosByTransactionId.ContainsKey(transactionId))
               {
                   Params.PortfoliosByTransactionId[transactionId] = order.Portfolio;
               }
               else
               {
                   Params.PortfoliosByTransactionId.Add(transactionId, order.Portfolio);

               }
              
           }
       }

       protected void LoadStateFromParams()
       {
               foreach (var transactionId in Params.OrdersByTransactionId.Keys)
           {
               var order = Params.OrdersByTransactionId[transactionId];
               if (order != null)
               {
                   order.Trader = Trader;
                   var security = Params.SecuritiesByTransactionId[transactionId];
                   if (security != null)
                   {

                       var exchange = Params.ExchangesByTransactionId[transactionId];
                       if (exchange != null) security.ExchangeBoard.Exchange = exchange;

                       security.Trader = Trader;
                       order.Security = security;

                   }

                   var portfolio = Params.PortfoliosByTransactionId[transactionId];
                   if (portfolio != null)
                   {
                       Portfolio.Trader = Trader;
                       order.Portfolio = portfolio;
                   }

                   var myTrades = new List<MyTrade>();
                   var trades = Params.TradesByTransactionId[transactionId];

                   if (trades != null)
                       foreach (var trade in trades)
                       {
                           var myTrade = new MyTrade();
                           myTrade.Order = order;
                           myTrade.Trade = trade;
                           myTrades.Add(myTrade);

                       }
                   if (myTrades.Count > 0)
                   {
                       AttachOrder(order, myTrades);
                   }
                    
               }
           }

       }

       protected  override  void OnStarted()
       {
           base.OnStarted();

         if(_isFirstStart)
         {
             _isFirstStart = false;
             LoadStateFromParams();

         }

       }

       protected override void OnStopped()
       {
           SaveStateToParams();
           
           base.OnStopped();
       }

      
    }
}





Правильней было бы сохранять все в бд, используя EntityRegistry, но как-то с базой гидры не хотело взлетать. А так работает, ну и окей. Не так уж часто стратегии перезапускаются в самом деле.




Немного поменял добавление стратегий.
Теперь, когда нужно будет включить новую стратегию, можно просто сделать для нее команду добавления, приписать в xml и она появится в менюшке добавления. Главное - все по аналогии.[thumbup]

1







list.png 42 KB (338)
Спасибо: Bond

Kazai Mazai

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


Часть 3.1. Добавление своих стратегий.

Эта история полна нюансов.

В шелле хорошо показано, на примере одной стратегии как все работает и т.д.

Добавить свою взамен существующей тоже легко - меняем да и все. Либо по-варварски вставляем в существующую новые внутренности.

Но тут не так все гибко, чтобы наряду с существующими в два щелчка добавить новые стратегии и чтобы все прекрасно работало и сохранялось.

Можно чуть менее чем полностью переделать SettingsEngine, половину кода связанного с добавлением стратегий, и только потом добавлять какие угодно новые стратегии в два щелчка.

А можно сделать минимум изменений, прикрутив маленькие костыли и затем добавлять новые стратегии не в 2 а в 6 щелчков, о чем и пойдет речь дальше.

Я уже подготовил небольшую почву, наподобие той, про которую было во 2-ой части. Когда мне удастся подружиться с ТФС, эти изменения уже будут в шелле.

Может показаться, что кода много, но на самом деле там 90% копи паст.


Добавляем заготовку для стратегии, для параметров и параметров тестирования, которые когда-нибудь наполним содержанием.

Код


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Robot.Strategies
{
    public class HustleEveryDayStrategyProperties :BaseShellStrategyProperties
    {
        

    }

    public class  HustleEveryDayStrategyTestingProperties:BaseShellTestingProperties
    {
        

    }


   public class HustleEveryDayStrategy:BaseShellStrategy
    {


    }
}



Идем в SettingsEngine, добавляем методы для сохранения и загрузки параметров для нового типа стратегий.

Код

private const string HustleEveryDayStrategies = @"HustleEveryDayStrategies.xml";
private const string TestingHustleEveryDayStrategies = @"TestingHustleEveryDayStrategies.xml";

        public void SaveHustleEveryDayStrategiesProperties(List<HustleEveryDayStrategyProperties> properties)
        {
            this.AddInfoLog("Сохранение стратегий в {0}", HustleEveryDayStrategies);
            using (var writer = new StreamWriter(HustleEveryDayStrategies, false))
            {
                var mySerializer = new XmlSerializer(typeof(List<HustleEveryDayStrategyProperties>));
                mySerializer.Serialize(writer, properties);
            }
        }


        public List<HustleEveryDayStrategyProperties> LoadHustleEveryDayStrategiesProperties()
        {
            this.AddInfoLog("Загрузка стратегий из {0}", HustleEveryDayStrategies);

            var result = new List<HustleEveryDayStrategyProperties>();

            if (File.Exists(HustleEveryDayStrategies))
            {
                try
                {
                    using (var reader = new StreamReader(HustleEveryDayStrategies))
                    {
                        var x = new XmlSerializer(typeof(List<HustleEveryDayStrategyProperties>));
                        result = (List<HustleEveryDayStrategyProperties>)x.Deserialize(reader);
                    }
                }
                catch (Exception ex)
                {
                    this.AddErrorLog("Ошибка загрузки {0}: {1}", HustleEveryDayStrategies, ex.Message);
                }
            }

            return result;
        }

        public void SaveTestingHustleEveryDayStrategyProperties(List<HustleEveryDayStrategyTestingProperties> properties)
        {
            this.AddInfoLog("Сохранение тестовых стратегий в {0}", TestingHustleEveryDayStrategies);
            using (var writer = new StreamWriter(TestingHustleEveryDayStrategies, false))
            {
                var mySerializer = new XmlSerializer(typeof(List<HustleEveryDayStrategyTestingProperties>));
                mySerializer.Serialize(writer, properties);
            }
        }

        public List<HustleEveryDayStrategyTestingProperties> LoadTestingHustleEveryDayStrategyProperties()
        {
            this.AddInfoLog("Загрузка стратегий тестирования из {0}", TestingHustleEveryDayStrategies);

            var result = new List<HustleEveryDayStrategyTestingProperties>();

            if (File.Exists(TestingStrategiesXml))
            {
                using (var reader = new StreamReader(TestingHustleEveryDayStrategies))
                {
                    var x = new XmlSerializer(typeof(List<HustleEveryDayStrategyTestingProperties>));
                    result = (List<HustleEveryDayStrategyTestingProperties>)x.Deserialize(reader);
                }
            }

            return result;
        }




Идем в Main.

Добавляем маленький костыль.

Код
 

private List<HustleEveryDayStrategy> _hustleEveryDayStrategies = new List<HustleEveryDayStrategy>();

private List<HustleEveryDayStrategy> _hustleEveryDayTestingStrategies = new List<HustleEveryDayStrategy>();
	


И почти как под копирку методы для добавления стратегий:

Код
 
private void AddHustleEveryDayStrategy()
        {
            var properties = new HustleEveryDayStrategyProperties
            {
                // TODO: check if the stategy with same does exist
                Name = "Новая стратегия {0}".Put(_newStrategyCount++),
            };

            AddHustleEveryDayStrategy(properties);
            SaveStrategies();
        }

        private void AddHustleEveryDayStrategy(HustleEveryDayStrategyProperties properties)
		{
			var strategy = new HustleEveryDayStrategy
			{
				Params = properties,
				Trader = ConnectionEngine.Instance.Trader
			};

			_logManager.Sources.Add(strategy);

		    var doc = new LayoutDocument
		    {
                Title = strategy.Params.Name,
                Content = new StrategyDocument
				{
					Strategy = strategy
				},
		        CanClose = false
		    };

			strategy.Params.PropertyChanged += (s, a) =>
			{
				if (a.PropertyName == "Name")
				{
					doc.Title = strategy.Params.Name;
				}

				SaveStrategies();
			};

			_documents.Add(strategy, doc);
                        _hustleEveryDayStrategies.Add(strategy);

			this.AddInfoLog("Добавлена стратегия '{0}'", strategy.Name);

			StrategiesDocumentPane.Children.Add(doc);
		}

        private void AddHustleEverydayTestingStrategy()
        {
            var properties = new HustleEveryDayStrategyTestingProperties
            {
                Name = "Тестирование {0}".Put(_newTestingCount++)
            };

            AddTestingStrategy(properties);
            SaveTestingStrategies();
        }

        private void AddHustleEverydayTestingStrategy(HustleEveryDayStrategyTestingProperties properties)
        {
            var strategy = new HustleEveryDayStrategy
            {
                Params = properties,
                Trader = ConnectionEngine.Instance.Trader
            };

            var doc = new LayoutDocument()
            {
                Title = strategy.Params.Name,
                Content = new TestingDocument
                {
                    Strategy = strategy
                },
                CanClose = false
            };

            strategy.Params.PropertyChanged += (s, a) =>
            {
                if (a.PropertyName == "Name")
                {
                    doc.Title = strategy.Params.Name;
                }

                SaveTestingStrategies();
            };

            _testingDocuments.Add(strategy, doc);
            _hustleEveryDayTestingStrategies.Add(strategy);

            this.AddInfoLog("Добавлена тестовая стратегия '{0}'", strategy.Name);

            StrategiesDocumentPane.Children.Add(doc);
        }





Нужно добавить в InitializeConfiguration() - методе восстановления из настроек.

Код
var hustleProperties = SettingsEngine.Instance.LoadHustleEveryDayStrategiesProperties();

            foreach (var property in hustleProperties)
            {
                AddHustleEveryDayStrategy(property);
            }


            var testingHustleProperties = SettingsEngine.Instance.LoadTestingHustleEveryDayStrategyProperties();

            foreach (var properties in testingHustleProperties)
            {
                AddTestingStrategy(properties);
            }





Ну вот. Теперь сохранение настроек стратегий будет работать не правильно, а удаление будет удалять только из интерфейса, а при перезапуске все будет по-прежнему. И это только на первый взгляд.

Как починить это, а также о том, как добавить кнопки добавления стратегии в интерфейс, узнаем в следующей подчасти части 3.
Спасибо: Bond

Bond

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


Прям триллер какой-то! Ждем продолжения! [thumbup]
Спасибо:

Kazai Mazai

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


Переделать метод сохранения, который в MainWindow.xaml.cs можно как-нибудь в таком духе:

Код
private void SaveStrategies()
		{
			

		    SettingsEngine.Instance.SaveHustleEveryDayStrategiesProperties(
		        _hustleEveryDayStrategies.Select(s => (HustleEveryDayStrategyProperties)s.Params).ToList());

            var otherStrategies = _documents.Keys.Where( s=>! _hustleEveryDayStrategies.Any(str=> str.Params.Name==s.Params.Name)).Select(strategy => strategy.Params).ToList();
            SettingsEngine.Instance.SaveStrategies(otherStrategies);
		}



Сохранять сначала наши новые кастомные стратегии, а потом фильтровать все, например по имени.
Но по идее, если уж пилить стратегии, то для каждого вашего типа стратегий будет свой массив, который и следует сохранять по отдельности, и ничего уже потом не фильтровать.

Аналогично с сохранением свойств тестовых стратегий:

Код
  private void SaveTestingStrategies()
        {
            SettingsEngine.Instance.SaveTestingHustleEveryDayStrategyProperties(
                _hustleEveryDayTestingStrategies.Select(s => (HustleEveryDayStrategyTestingProperties)s.Params).ToList());

            var strategies = _testingDocuments.Keys.Where( s=>! _hustleEveryDayTestingStrategies.Any(str=> str.Params.Name==s.Params.Name)).Select(strategy => (BaseShellTestingProperties)strategy.Params).ToList();

            SettingsEngine.Instance.SaveTestingStrategies(strategies);
        }




В методе
Код
private void ExecutedRemoveStrategy(object sender, ExecutedRoutedEventArgs e)


Там где у нас обработка нажатого "да"

Код
if (result == MessageBoxResult.Yes)
			{
				this.AddInfoLog("Удаление стратегии '{0}'", strategy.Params.Name);

				var doc = _documents[strategy];
				_documents.Remove(strategy);

				StrategiesDocumentPane.RemoveChild(doc);
			    _hustleEveryDayStrategies.RemoveAll(s => s.Params.Name == strategy.Params.Name);
				SaveStrategies();
			}



Удаляем еще и из нашего списка стратегий с фильтрацией по имени. Лучше, конечно, что б у всех стратегий был какой-то id, и все сравнения проводить по нему.



Что бы можно было было из интерфейса добавить свежих стратегий:

Добавляем команду там же в MainWindow.xaml.cs,

Код
public static RoutedCommand AddHustleStrategyCommand = new RoutedCommand();



далее методы для команды.

Код
 private void ExecutedAddHustleStrategy(object sender, ExecutedRoutedEventArgs e)
        {
            AddHustleEveryDayStrategy();

            AllStrategies.ListViewStrategies.ItemsSource = _documents.Keys.ToList();
        }
        private void CanExecuteAddHuslteStrategy(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }




Нужно теперь подключить команду к gui. В MainWindow.xaml:


Там есть такая штука, комманд биндинг. Добавляем вот что:

Код
<CommandBinding Command="{x:Static Robot:MainWindow.AddHustleStrategyCommand}"
                    Executed="ExecutedAddHustleStrategy"
                    CanExecute="CanExecuteAddHustleStrategy" />


далее в нем же ищем "AddStrategyCommand"? находим его в контексте меню итемс, и аналогично добавляем

Код
   <MenuItem Header="Добавить хассол" Command="{x:Static Robot:MainWindow.AddHustleStrategyCommand}"/>




Ну вот, теперь все готово.





Спасибо: Bond

Kazai Mazai

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


Небольшое лирическое отступление...


Там выше в стратегии реализовывались методы для сохранения ордеров, позиций и т.д.

У меня так раньше было реализовано, не на s# shell, но все же. Возможно версия s# была другая, возможно я где-то наошибался, но недавно на s# shell уже обнаружил, что такой способ не работает. Т.е. если положить Dictionary с ордерами (то что в базовых Properties) в SettingsStorage и попытаться сериализовать, ничего не получится. Если положить SettingsStorage с ордерами в SettingsStorage, тоже не заработало, хотя раньше все прокатывало, если мне не изменяет память.

Во-вторых это, на мой взгляд, не совсем корректно, если в стратегию ордера и сделки поступают не только из Trader, но еще и напрямую из хранилища.

Может возникнуть какая-нибудь дурацкая ситуация, если после перезапуска один и тот же ордер прийдет в стратегию и шлюза и из хранилища, и бог его знает как-там оно все разбираться внутри будет.

Поэтому, в Properties стратегии лучше хранить просто список orderIDs, брать их от Trader'a и привязывать.

Если торговый терминал не передает историю ордеров, прийдется "усовершенствовать" Trader и реализовать возможность сохранения в бд.

Вот такие вот рекомендации.[smile]


Спасибо:

dij1

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


Вопрос немного не в тему. Удалось ли Вам поймать устойчивую конфигурацию работы с Plaza 2, т.е. версию, которая с плазой пашет?
Спасибо:

Kazai Mazai

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


dij1
Вопрос немного не в тему. Удалось ли Вам поймать устойчивую конфигурацию работы с Plaza 2, т.е. версию, которая с плазой пашет?


Я плазой вообще дел не имел
Спасибо:

Kazai Mazai

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


По просьбам телезрителей(как минимум одного) сделал зарисовочку для сопровождения позиции.
Открывается прямо при старте, и выходит в какое-то время, а также по стопам и нескольким ценовым тейкам, передвигая стоп в б\у.
Есть кое-какие лишние проверки, потому что кусочки взяты из стратегии на нескольких инструментах, но хуже не будет.


Код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Ecng.Common;
using StockSharp.Algo;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Logging;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;

namespace Robot.Strategies
{
    public class HustleEveryDayStrategyProperties :BaseShellStrategyProperties
    {

        private decimal _takeProfit1 = 10000000;
        [DisplayName(@"1-й тейк профит")]
        [Description(@"Цена для 1-й цели")]
        [Category(@"Параметры")]
        [PropertyOrder(0)]
        public decimal TakeProfit1
        {
            get { return _takeProfit1; }
            set
            {
                _takeProfit1 = value;
                OnPropertyChanged("TakeProfit1");
            }
        }



        private decimal _takeProfit2 = 10000000;
        [DisplayName(@"2-й тейк профит")]
        [Description(@"Цена для 2-й цели")]
        [Category(@"Параметры")]
        [PropertyOrder(0)]
        public decimal TakeProfit2
        {
            get { return _takeProfit2; }
            set
            {
                _takeProfit2 = value;
                OnPropertyChanged("TakeProfit2");
            }
        }
        private decimal _takeProfit3 = 10000000;
        [DisplayName(@"3-й тейк профит")]
        [Description(@"Цена для 3-й цели")]
        [Category(@"Параметры")]
        [PropertyOrder(0)]
        public decimal TakeProfit3
        {
            get { return _takeProfit3; }
            set
            {
                _takeProfit3 = value;
                OnPropertyChanged("TakeProfit3");
            }
        }

        private decimal _stoploss = 10000000;
        [DisplayName(@"стоп лосс")]
        [Description(@"Цена для стоп лосса")]
        [Category(@"Параметры")]
        [PropertyOrder(0)]
        public decimal Stoploss
        {
            get { return _stoploss; }
            set
            {
                _stoploss = value;
                OnPropertyChanged("Stoploss");
            }
        }
        private DateTime _closeTime = new DateTime(2000,1,1,1,1,1);
        [DisplayName(@"Время закрытия")]
        [Description(@"Время закрытия сделки")]
        [Category(@"Параметры")]
        [PropertyOrder(0)]
        public DateTime CloseTime
        {
            get { return _closeTime; }
            set
            {
                _closeTime = value;
                OnPropertyChanged("CloseTime");
            }
        }

        private OrderDirections _orderDirection = OrderDirections.Buy;
        [DisplayName(@"Направление сделки")]
        [Description(@"Направление сделки")]
        [Category(@"Параметры")]
        [PropertyOrder(0)]
        public OrderDirections OrderDirection
        {
            get { return _orderDirection; }
            set
            {
                _orderDirection = value;
                OnPropertyChanged("OrderDirection");
            }
        }


    }

    public class  HustleEveryDayStrategyTestingProperties:BaseShellTestingProperties
    {
        

    }


   public class HustleEveryDayStrategy:BaseShellStrategy
    {
       protected override void OnStarted()
       {

           base.OnStarted();

           var currentTime = Trader.GetMarketTime(Security.ExchangeBoard.Exchange);
           this.AddInfoLog("Текущее рыночное время: {0}.".Put(currentTime));

           var currentClosePositionsTime = ((HustleEveryDayStrategyProperties) Params).CloseTime;
           this.AddInfoLog("Текущее время проверки выхода по тайм-стопу: {0}.".Put(currentClosePositionsTime));
           if (currentTime > currentClosePositionsTime)
           {
               var newClosePositionsTime = new DateTime(currentTime.Year, currentTime.Month, currentTime.Day,
                                                        currentClosePositionsTime.Hour, currentClosePositionsTime.Minute,
                                                        currentClosePositionsTime.Second);
               this.AddInfoLog("Новое время проверки выхода по тайм-стопу: {0}.".Put(newClosePositionsTime));
               ((HustleEveryDayStrategyProperties) Params).CloseTime = newClosePositionsTime;
           }

           
           Security
             .WhenTimeCome(((HustleEveryDayStrategyProperties)Params).CloseTime)
             .Do(CheckForExitByTimeTargets)
             .Apply(this);

           Security
                   .WhenChanged()
                   .Do(CheckForExitByPriceTargets)
                   .Apply(this);

           SubscriptionEngine.Instance.RegisterSecurity(this, Security);

           if(((HustleEveryDayStrategyProperties)Params).OrderDirection==OrderDirections.Buy)
           {
               PlaceBuyMarketOrder(Security,Volume);

           }
           else
           {
               PlaceSellMarketOrder(Security, Volume);
           }

       }

       private  void CheckForExitByPriceTargets()
       {

         this.AddInfoLog("Проверка выхода по целям.");
       
         if( PositionManager.Positions.Any(p=> p.Security.Code==Security.Code))
         {
             var position = PositionManager.Positions.First(p => p.Security.Code == Security.Code);
             if (position.CurrentValue > 0)
             {
                 if (Security.LastTrade.Price <= ((HustleEveryDayStrategyProperties)Params).Stoploss)
                 { 
                    PlaceSellMarketOrder(position.Security, position.CurrentValue);
                    return;
                 }

                 if (Security.LastTrade.Price >= ((HustleEveryDayStrategyProperties)Params).TakeProfit3)
                 {
                     PlaceSellMarketOrder(position.Security, position.CurrentValue);
                     return;
                 }

                 if (Security.LastTrade.Price >= ((HustleEveryDayStrategyProperties)Params).TakeProfit2)
                 {
                     PlaceSellMarketOrder(position.Security,decimal.Floor(0.5m*position.CurrentValue));
                     ((HustleEveryDayStrategyProperties)Params).Stoploss =
                         ((HustleEveryDayStrategyProperties)Params).TakeProfit1;

                     return;
                 }
                 if (Security.LastTrade.Price >= ((HustleEveryDayStrategyProperties)Params).TakeProfit1)
                 {
                   
                     PlaceSellMarketOrder(position.Security, decimal.Floor(0.33m * position.CurrentValue));
                   
                     if(MyTrades.Any(t=>t.Trade.Security.Code==Security.Code))
                     {
                        var myTradesOrderedByDate = MyTrades.ToList().OrderBy(t => t.Trade.Time);
                        var trade = myTradesOrderedByDate.Last(t => t.Trade.Security.Code == Security.Code);
                        var entryPrice = trade.Trade.Price;

                         ((HustleEveryDayStrategyProperties) Params).Stoploss = entryPrice;

                     }
                     return;
                 }




             }
             else
             {
                 if (position.CurrentValue < 0)
                 {
                     if (Security.LastTrade.Price >= ((HustleEveryDayStrategyProperties)Params).Stoploss)
                     {
                         PlaceBuyMarketOrder(position.Security, position.CurrentValue);
                         return;
                     }

                     if (Security.LastTrade.Price <= ((HustleEveryDayStrategyProperties)Params).TakeProfit3)
                     {
                         PlaceBuyMarketOrder(position.Security, position.CurrentValue);
                         return;
                     }

                     if (Security.LastTrade.Price <= ((HustleEveryDayStrategyProperties)Params).TakeProfit2)
                     {
                         PlaceBuyMarketOrder(position.Security, decimal.Floor(0.5m * position.CurrentValue));
                         ((HustleEveryDayStrategyProperties)Params).Stoploss =
                             ((HustleEveryDayStrategyProperties)Params).TakeProfit1;

                         return;
                     }
                     if (Security.LastTrade.Price <= ((HustleEveryDayStrategyProperties)Params).TakeProfit1)
                     {

                         PlaceBuyMarketOrder(position.Security, decimal.Floor(0.33m * position.CurrentValue));

                         if (MyTrades.Any(t => t.Trade.Security.Code == Security.Code))
                         {
                             var myTradesOrderedByDate = MyTrades.ToList().OrderBy(t => t.Trade.Time);
                             var trade = myTradesOrderedByDate.Last(t => t.Trade.Security.Code == Security.Code);
                             var entryPrice = trade.Trade.Price;

                             ((HustleEveryDayStrategyProperties)Params).Stoploss = entryPrice;

                         }
                         return;
                     }




                 }
             }
          
              
         }
          

       }


       private  void CheckForExitByTimeTargets()
       {

           this.AddInfoLog("Выход по тайм-стопу");
       
             foreach (var position in PositionManager.Positions)
             {
                 if(position.CurrentValue>0)
                 {
                     PlaceSellMarketOrder(position.Security,position.CurrentValue);

                 }
           
                 if (position.CurrentValue < 0)
                 {
                     PlaceBuyMarketOrder(position.Security, -position.CurrentValue);


                 }
                  

             }

       }

       protected void PlaceBuyMarketOrder(Security security, decimal volume)
       {
           var order = this.BuyAtMarket(volume);
           order.Security = security;

           order
                          .WhenChanged()
                          .Do(() => this.AddInfoLog("Изменилось остояние заявки"))
                          .Once()
                          .Apply(this);



           order
               .WhenRegistered()
               .Do(() => this.AddInfoLog("Заявка успешно зарегистрирована"))
               .Once()
               .Apply(this);

           order
               .WhenRegisterFailed()
               .Do(() => this.AddInfoLog("Заявка не принята биржей"))
               .Once()
               .Apply(this);

           order
               .WhenMatched()
               .Do(() =>
               {

                   this.AddInfoLog("Заявка полностью исполнена");
               })
               .Once()
               .Apply(this);

           // регистрирация заявки

           RegisterOrder(order);

       }
       protected void PlaceSellMarketOrder(Security security, decimal volume)
       {
           var order = this.SellAtMarket(volume);
           order.Security = security;
           order
                          .WhenChanged()
                          .Do(() => this.AddInfoLog("Изменилось остояние заявки"))
                          .Once()
                          .Apply(this);



           order
               .WhenRegistered()
               .Do(() => this.AddInfoLog("Заявка успешно зарегистрирована"))
               .Once()
               .Apply(this);

           order
               .WhenRegisterFailed()
               .Do(() => this.AddInfoLog("Заявка не принята биржей"))
               .Once()
               .Apply(this);

           order
               .WhenMatched()
               .Do(() =>
               {

                   this.AddInfoLog("Заявка полностью исполнена");
               })
               .Once()
               .Apply(this);

           // регистрирация заявки

           RegisterOrder(order);

       }
   

    }
}
Спасибо: Churchill liftrade dimtrdr

liftrade

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


Интересно, это только у меня в каркасе в таблице сделки, отображается только первая сделка? Никакие последующие в нее не заносятся... Или это общий баг такой?
Спасибо:

Kazai Mazai

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


liftrade
Интересно, это только у меня в каркасе в таблице сделки, отображается только первая сделка? Никакие последующие в нее не заносятся... Или это общий баг такой?



да у меня тоже был такой баг, почему-то insert не так работает, как хотелось бы.

В StrategyDocument.xaml.cs меняем закомментированное на незакомментированное.

Код

_strategy.NewMyTrades += trades =>
				{
					foreach (var trade in trades)
					{
                                                _tradeGrid.Trades.Add(trade.Trade);
						//_tradeGrid.Trades.Insert(0, trade.Trade);
					}
				};



Спасибо: liftrade
1 2 3  >

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

loading
clippy