VassilSanych
|
Дата: 18.03.2012
|
|
|
|
4) При указании в настройках целевой директории присутствует выбор между целевой директорией и директорией программы. Причём последняя выбрана по-умолчанию. Не знаю фича это или косяк, но выглядит, как косяк. 5) Архитектурно программа везде вместо построчной обработки использует списки. Команда Код
Storage.GetTradeStorage(Security, SourcePath.SelectedSource)
.Load(FromDate, ToDate + TimeSpan.FromTicks(TimeSpan.TicksPerDay - 1))
вызывает волшебный метод Код
public IEnumerable<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D> Load(DateTime \u0023\u003DqjMNbSyHi2wSfqMTxwOFw5w\u003D\u003D, DateTime \u0023\u003DqLRw2isZu\u0024Gi2kSql74F4hw\u003D\u003D)
{
Func<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>> func1 = (Func<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>>) null;
Func<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, bool> func2 = (Func<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, bool>) null;
\u0023\u003DqjscC_sD__Wz1R8OrZhlzyOI5tzzg7BToUBKXwTVqZO84NhphJRI0eyRNGeGaeg0l<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqAS4sOB3tWVQahGWJQZAVyQ\u003D\u003D, \u0023\u003DqBue7tPpoVUuUSzCh\u0024R8o6w\u003D\u003D>.\u0023\u003DqwQ1\u00246I4BPH\u0024l6LQCfG2RNtCtg2ZDZArxsDUMsokwWOY\u003D zdzArxsDuMsokwWoY = new \u0023\u003DqjscC_sD__Wz1R8OrZhlzyOI5tzzg7BToUBKXwTVqZO84NhphJRI0eyRNGeGaeg0l<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqAS4sOB3tWVQahGWJQZAVyQ\u003D\u003D, \u0023\u003DqBue7tPpoVUuUSzCh\u0024R8o6w\u003D\u003D>.\u0023\u003DqwQ1\u00246I4BPH\u0024l6LQCfG2RNtCtg2ZDZArxsDUMsokwWOY\u003D();
zdzArxsDuMsokwWoY.\u0023\u003DqNggpJclGeVDD_hTLp8iTTQ\u003D\u003D = param0;
zdzArxsDuMsokwWoY.\u0023\u003Dq0tOGvj3TpUouN1ux_qLJ0g\u003D\u003D = param1;
zdzArxsDuMsokwWoY.\u0023\u003DqatTwgFVaPtUxSGplmCWi_A\u003D\u003D = this;
if (zdzArxsDuMsokwWoY.\u0023\u003DqNggpJclGeVDD_hTLp8iTTQ\u003D\u003D > zdzArxsDuMsokwWoY.\u0023\u003Dq0tOGvj3TpUouN1ux_qLJ0g\u003D\u003D)
throw new ArgumentOutOfRangeException(\u0023\u003DqiynfM61BKwvyYrVfBhgEI\u0024B5hL7s98VPGwOBoMznNsE\u003D.\u0023\u003DqZv2ypaOXYNZbZulAOMdGVg\u003D\u003D(-615884728), (object) zdzArxsDuMsokwWoY.\u0023\u003Dq0tOGvj3TpUouN1ux_qLJ0g\u003D\u003D, \u0023\u003DqiynfM61BKwvyYrVfBhgEI\u0024B5hL7s98VPGwOBoMznNsE\u003D.\u0023\u003DqZv2ypaOXYNZbZulAOMdGVg\u003D\u003D(-615888671));
List<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D> list1 = new List<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D>();
zdzArxsDuMsokwWoY.\u0023\u003DqNggpJclGeVDD_hTLp8iTTQ\u003D\u003D = MathHelper.Max(zdzArxsDuMsokwWoY.\u0023\u003DqNggpJclGeVDD_hTLp8iTTQ\u003D\u003D, this.FromDate);
if (zdzArxsDuMsokwWoY.\u0023\u003Dq0tOGvj3TpUouN1ux_qLJ0g\u003D\u003D > this.ToDate)
zdzArxsDuMsokwWoY.\u0023\u003Dq0tOGvj3TpUouN1ux_qLJ0g\u003D\u003D = this.ToDate.AddTicks(863999999999L);
for (DateTime dateTime = zdzArxsDuMsokwWoY.\u0023\u003DqNggpJclGeVDD_hTLp8iTTQ\u003D\u003D.Date; dateTime <= zdzArxsDuMsokwWoY.\u0023\u003Dq0tOGvj3TpUouN1ux_qLJ0g\u003D\u003D; dateTime = dateTime.AddDays(1.0))
{
List<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D> list2 = list1;
List<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D> list3 = this.\u0023\u003Dqku2X1xXOuql\u0024Cu2tld76CA\u003D\u003D(dateTime);
if (func1 == null)
func1 = new Func<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>>(this.\u0023\u003DqXCeEZYtkCEra\u0024qrnqe9hEw\u003D\u003D);
Func<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>> selector1 = func1;
IEnumerable<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>> source1 = Enumerable.Select<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>>((IEnumerable<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D>) list3, selector1);
if (func2 == null)
func2 = new Func<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, bool>(zdzArxsDuMsokwWoY.\u0023\u003DqLaIGTCyJSPHR2oI13wYb1A\u003D\u003D);
Func<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, bool> predicate = func2;
IEnumerable<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>> source2 = Enumerable.Where<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>>(source1, predicate);
if (\u0023\u003DqjscC_sD__Wz1R8OrZhlzyOI5tzzg7BToUBKXwTVqZO84NhphJRI0eyRNGeGaeg0l<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqAS4sOB3tWVQahGWJQZAVyQ\u003D\u003D, \u0023\u003DqBue7tPpoVUuUSzCh\u0024R8o6w\u003D\u003D>.\u0023\u003DqE9hVdSYL5I2ieTBjraxX5RotRNF07gEFMvwNoPwOkgsDM59ZsIUpRxIDaPISoXVU == null)
\u0023\u003DqjscC_sD__Wz1R8OrZhlzyOI5tzzg7BToUBKXwTVqZO84NhphJRI0eyRNGeGaeg0l<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqAS4sOB3tWVQahGWJQZAVyQ\u003D\u003D, \u0023\u003DqBue7tPpoVUuUSzCh\u0024R8o6w\u003D\u003D>.\u0023\u003DqE9hVdSYL5I2ieTBjraxX5RotRNF07gEFMvwNoPwOkgsDM59ZsIUpRxIDaPISoXVU = new Func<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, \u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D>(\u0023\u003DqjscC_sD__Wz1R8OrZhlzyOI5tzzg7BToUBKXwTVqZO84NhphJRI0eyRNGeGaeg0l<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqAS4sOB3tWVQahGWJQZAVyQ\u003D\u003D, \u0023\u003DqBue7tPpoVUuUSzCh\u0024R8o6w\u003D\u003D>.\u0023\u003Dq7aL0H77QpSgfenltCnx_VQ\u003D\u003D);
Func<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, \u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D> selector2 = \u0023\u003DqjscC_sD__Wz1R8OrZhlzyOI5tzzg7BToUBKXwTVqZO84NhphJRI0eyRNGeGaeg0l<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, \u0023\u003DqAS4sOB3tWVQahGWJQZAVyQ\u003D\u003D, \u0023\u003DqBue7tPpoVUuUSzCh\u0024R8o6w\u003D\u003D>.\u0023\u003DqE9hVdSYL5I2ieTBjraxX5RotRNF07gEFMvwNoPwOkgsDM59ZsIUpRxIDaPISoXVU;
IEnumerable<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D> collection = Enumerable.Select<\u0023\u003DqEF80Yvamo98ZmPyDgj9S83tqQZUTw9Y1GwDqtxtmj2w\u003D<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D, DateTime>, \u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D>(source2, selector2);
list2.AddRange(collection);
}
return (IEnumerable<\u0023\u003DqdDI3Y3B9NuGEyhuWEKOMQw\u003D\u003D>) list1;
}
Видно, что несмотря на интерфейс IEnumerable, вывод производится не через yield return, а обычным списком в памяти. Т.е. возможные миллионы строк утрамбовываются в оперативную память. Не очень хорошее поведение для высоконагруженной системы. Данные всего за 2 недели по фьючерсу RI отъедают при этом памяти около 4Гб.
|
|
Спасибо:
|
|
|
|
|
VassilSanych
|
Дата: 18.03.2012
|
|
|
|
6) Но это ещё не все проблемы с памятью. Небольшой участок кода Код
using (var writer = new StreamWriter(_filename))
{
var st = new StringTemplate(File.ReadAllText("txt_export_trades.st"));
st.RegisterRenderer(typeof(DateTime), new AdvancedDateTimeRenderer());
st.SetAttribute("security", Security.Id);
st.SetAttribute("from", FromDate);
st.SetAttribute("to", ToDate);
st.SetAttribute("trades", trades);
st.Write(new AutoIndentWriter(writer));
}
,который по идее должен обеспечивать потоковый вывод в файл с минимальными затратами памяти, съедает этой памяти ещё в 2 раза больше (около 5Гб), чем окунает мой компьютер в файл подкачки "по самые не хочу". 7) И это ещё не всё. После окончания экспорта и закрытия окна сделок память не очищается. Принудительная сборка мусора помогает слабо. Видимо где-то большие объёмы хранятся в статическом поле. Приходится для каждого экспорта перезапускать программу. ----------------- В результате экспортировал RIH2 гидрой в 6 приёмов за 1 час, закрыв все приложения, ибо при работе программы с файлом подкачки ничего другое не работает в принципе. После чего за 2 минуты загрузил полученные файлы в Amibroker с расходованием максимально около 100MB памяти. Как говорится, почувствуйте разницу.
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 18.03.2012
Проблема известная и уже была исправлена в дев ветке (появился IMarketDataStorage.Read). Кроме экспорта Гидры, так как сами мы из Гидры ничего не экспортируем. Можем дать доступ с учетом того, что доделаете выгрузку данных в файл через новый итерационный способ (типа yield).
|
|
Спасибо:
|
|
|
|
|
VassilSanych
|
Дата: 18.03.2012
PS Если кому надо, шаблон выгрузки в формате, который нравится Амиброкеру: Код
$trades:{$it.Security.Code$;$it.Time; format="yyyyMMdd"$;$it.Time; format="HHmmss"$;$it.Price$;$it.Volume$
}$
|
|
Спасибо:
|
|
|
|
|
VassilSanych
|
Дата: 18.03.2012
Mikhail Sukhov Можем дать доступ с учетом того, что доделаете выгрузку данных в файл через новый итерационный способ (типа yield). Если доступ к данным позволяет (не всё сверху до низу списками), сделаю.
|
|
Спасибо:
|
|
|
|
|
VassilSanych
|
Дата: 18.03.2012
Если методы используются где-то ещё, то всё равно надо будет тестировать. У провайдера SQLite есть один большой косяк: он очень не любит конкурентные запросы на запись: несколько запросов на чтение возможны и в параллельных потоках, а вот при наличии запроса на запись, запрос на чтение может отвалиться даже если запущен просто сразу после запроса на запись (транзакция не успевает отработать). Итерационный способ повышает риски такой ситуации. MSSQL в этом отношении работает намного стабильнее.
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 18.03.2012
1. При экспорте данных БД не используется. 2. Дайте свой логин на коде плексе, чтобы я вас к проекту подключил. 3. Насчет верха и низа не понял, что это вообще такое.
|
|
Спасибо:
|
|
|
|
|
VassilSanych
|
Дата: 20.03.2012
4.1 не выгружает данные, загруженные версией 4.0.22. Метод Load работает так, как будто данных в папке нет. На первый взгляд поведение в доступном коде не отличается.
|
|
Спасибо:
|
|
|
|
|
Mikhail Sukhov
|
Дата: 20.03.2012
VassilSanych 4.1 не выгружает данные, загруженные версией 4.0.22. Метод Load работает так, как будто данных в папке нет. На первый взгляд поведение в доступном коде не отличается. http://stocksharp.com/posts/m/17173/
|
|
Спасибо:
|
|
|
|
|
Alexander
|
Дата: 22.03.2012
Куда пост делся про метод Read? :) Что-то изменилось?
|
|
Спасибо:
|
|
|
|