Восстановление сохраненной стратегии

Восстановление сохраненной стратегии
Atom
9/25/2014
Andrii


Восстановить сохраненную стратегию можно через SettingsStorage, но туда попадают только настройки, вернуть полностью состояние не получается. То есть, если совершить сделку, сохранить, то при восстановлении сделка теряется.
Если настроить сохранение еще можно, то как восстановить сделки(Trade), по которым открыта позиция.

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

Tags:


Thanks:


< 1 2 3 
RomSunZ

Avatar
Date: 10/9/2014
Reply


devruss
RomSunZ
А что мешает взять из БД позицию/ордера/сделки по последней открытой позиции, а сохраненные данные по предыдущим сделкам/позициям/ордерам использовать для анализа работы системы?


Я не понял, как можно передать роботу позицию? AttachOrder функция есть, а как указать текущую позицию при старте?


Какой сайз и какое направление было у ордера, который через AttachOrder присоединяется к стратегии, такая поза у стратегии и будет. Если несколько ордеров, то позиция суммируется.
Thanks:

devruss

Avatar
Date: 10/9/2014
Reply


RomSunZ
Какой сайз и какое направление было у ордера, который через AttachOrder присоединяется к стратегии, такая поза у стратегии и будет. Если несколько ордеров, то позиция суммируется.


Это так, но я хочу уйти от связки "сделки - высчитываем позицию - позиция" к "записываем изменения позиции - при старте стратегии подается на вход тек. позиция".
Таким образом, мне
1. Не нужна БД. Достаточно 1 файла на стратегию с позицией
2. Быстрый старт

Если вдруг понадобится перейти от моего варианта к предложенному тобой, то этот файл с позицией можно формировать отдельно из сделок (или проверять). Таким образом мы делаем функционально независимый подход к управлению позицией
Thanks:

Andrii

Avatar
Date: 10/9/2014
Reply


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

открыли позицию - записали сделку - закрыли позицию - удалили 2 сделки

алгоритм сложный, но оставляет только сделки по открытым позициям
Thanks:

devruss

Avatar
Date: 10/9/2014
Reply


Andrii
вообще все зависит от стратегии и нужных данных, но более универсальный метод - писать только сделки открывающие позицию:

открыли позицию - записали сделку - закрыли позицию - удалили 2 сделки

алгоритм сложный, но оставляет только сделки по открытым позициям


Удалять - это сложно. А вот изменилась позиция - записали в файл, изменилась опять - опять записали, мне кажется как-то проще и fail proof
Thanks:

Marco

Avatar
Date: 10/10/2014
Reply


devruss

Удалять - это сложно. А вот изменилась позиция - записали в файл, изменилась опять - опять записали, мне кажется как-то проще и fail proof


Мы например так и делаем. При каждом изменении позиции стратегии по инструментам сохраняются в .csv файл. При старте стратегии - восстанавливаются (без сделок и ордеров).

Код:
Code


        protected List<Position> LoadPositions(string fileName)
        {
            List<Position> positions = new List<Position>();

            using (StreamReader stream = new StreamReader(fileName))
            {
                using (CsvReader reader = new CsvReader(stream))
                {
                    reader.Configuration.Delimiter = ",";
                    reader.Configuration.HasHeaderRecord = false;

                    //var records = reader.GetRecords<MyTrade>();
                    while (reader.Read())
                    {
                        try
                        {
                            string securityCode = reader.GetField<string>(0);
                            decimal value = reader.GetField<decimal>(1);
                            string portfolioName = reader.GetField<string>(2);

                            Portfolio portfolio = Connector.Portfolios.FirstOrDefault((Portfolio pf) =>
                            {
                                return pf.Name == portfolioName;
                            });
                            if (portfolio == null)
                            {
                                this.AddWarningLog("Portfolio with name {0} not found.", portfolioName);
                                continue;
                            }

                            Security security = Connector.Securities.FirstOrDefault((Security sec) =>
                            {
                                return sec.Code == securityCode;
                            });
                            if (security == null)
                            {
                                this.AddWarningLog("Security with code {0} not found.", securityCode);
                                continue;
                            }

                            Position position = new Position()
                            {
                                Portfolio = portfolio,
                                Security = security,
                                CurrentValue = value
                            };

                            positions.Add(position);
                        }
                        catch (Exception ex)
                        {
                            this.AddErrorLog("Ошибка загрузки позиции: {0}", ex.Message);
                        }
                    }
                }
            }

            return positions;
        }


        protected void LoadPositions()
        {
            if (!SavePositionsEnabled)
                return;

            string fileName = GetPersistentFileName("positions", "csv");
            this.AddInfoLog("Загрузка позиций из файла {0}", fileName);

            if (File.Exists(fileName))
            {
                List<Position> positions;

                lock (lockPositionsFile)
                {
                    positions = LoadPositions(fileName);
                }

                PositionManager.Positions = positions;
                RaiseParametersChanged("Position");
            }
            else
            {
                this.AddWarningLog("Файла с сохраненными позициями {0} не существует.", fileName);
            }
        }

        protected void SavePositions(IEnumerable<Position> positions, string fileName, bool append)
        {
            using (StreamWriter stream = new StreamWriter(fileName, append))
            {
                using (CsvWriter writer = new CsvWriter(stream))
                {
                    writer.Configuration.Delimiter = ",";
                    writer.Configuration.HasHeaderRecord = false;

                    foreach (Position position in positions)
                    {
                        try
                        {
                            writer.WriteField(position.Security.Code, true);
                            writer.WriteField(position.CurrentValue);
                            writer.WriteField(position.Portfolio.Name);
                            writer.NextRecord();
                        }
                        catch (Exception ex)
                        {
                            this.AddErrorLog("Ошибка сохранения позиции {0}: {1}", position.ToString(), ex.Message);
                        }
                    }

                    stream.Flush();
                }
            }
        }

        protected void SavePositions(IEnumerable<Position> positions)
        {
            if (!SavePositionsEnabled)
                return;

            string fileName = GetPersistentFileName("positions", "csv");
            this.AddInfoLog("Сохранение позиций в файл {0}", fileName);

            lock (lockPositionsFile)
            {
                SavePositions(PositionManager.Positions, fileName, false);
            }
        }


                PositionsChanged += (IEnumerable<Position> positions) =>
                {
                    SavePositions(positions);
                };


SavePositions() вызывается при изменении позиции и остановке стратегии. LoadPositions - в Strategy.OnStarted().

Метод спорный, но у нас работает. При этом ломается расчет PnL (мы им все равно не пользуемся, PnL стратегий считается скриптами на Python'е по сохраненным трейдам раз в день после клиринга - StockSharp все равно PnL считает неправильно...)
Thanks: devruss

Andrii

Avatar
Date: 10/10/2014
Reply


Marco


сказал а, говори б...

как вы считает PnL, полученный и нереализованный?
Thanks:

Marco

Avatar
Date: 10/10/2014
Reply


Quote:
как вы считает PnL, полученный и нереализованный?


Да просто рассчитываем вариационку отдельно по стратегиям, как это описано в спецификациях контрактов. Стратегии пишут свои трейды в CSV, после клиринга запускается пачка питоновских скриптов, которые:
- получают с биржи индикативный курс доллара на закрытие дня
- считают вариационку по стратегиям
- выгружают отчет в Excel

В течение дня PnL мы не считаем. Опять же, в чем считать PnL? Фьючерс на индекс RTS номинирован в долларах, рублевый PnL по нему в течение дня посчитать корректно вообще нельзя, т.к. курс валюты становится известен только на закрытие дня.
Thanks:
< 1 2 3 

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy