devruss:
Удалять - это сложно. А вот изменилась позиция - записали в файл, изменилась опять - опять записали, мне кажется как-то проще и fail proof
Мы например так и делаем. При каждом изменении позиции стратегии по инструментам сохраняются в .csv файл. При старте стратегии - восстанавливаются (без сделок и ордеров).
Код:
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 считает неправильно...)