• Тинькофф Банк-лучшие банковские продукты еще выгоднее
    Выбирайте продукт от банка Тинькофф
  • Уважаемые форумчане, друзья и посетители!
    Поступило предложение ( ссылка на обсуждение ) на сбор средств поддержания форума в рабочем состоянии с 1 июня ( оплата хостинга, бэкап ежедневный на другой хостинг и тд), отчетность будет предоставляться ежемесячно. Пока на ЮMoney ( яндекс деньги), доступно картой перевод, далее добавлю другие способы. Сумму перевода указывайте на ваш выбор исходя из своих возможностей.
    Форум продолжает свою работу благодаря Вашим пожертвованиям.

NinjaTrader Конвертирование NT8 MarketReplay файлов в текстовый формат

NT8

Well-Known Member
NinjaTrader
Утилитка для конвертации
ps/ работает корректно под Windows 10

nrd1.png

Конвертированные файлы сохраняются в ту же папку, что и сама утилита.

Формат конвертированных файлов

Пример данных.
L2;1;20190724070002;5970000;1;0;;1.11915;26
L2;1;20190724070002;5970000;1;1;;1.1191;65
L1;0;20190724070018;660000;1.1192;35
L2;0;20190724070018;660000;1;0;;1.1192;35
L1;0;20190724070018;660000;1.1192;36
L2;0;20190724070018;660000;1;0;;1.1192;36
L1;1;20190724070018;1050000;1.11915;25

Для L1:
MarketDataType;DateTime;Int(кол-во десятимиллионных долей секунды);Price;Volume

Для L2:
MarketDataType;DateTime;Int(кол-во десятимиллионных долей секунды);Operation;Position;MarketMaker;Price;Volume

MarketDataType (0-10):
Ask,
Bid,
Last,
DailyHigh,
DailyLow,
DailyVolume,
LastClose,
Opening,
OpenInterest,
Settlement,
Unknown

Operation (0-2):
Add,
Update,
Remove

Position - номер позиции в OrderBook (стакане)

Исходники для изучения на гитхабе.
NTDeveloping/NRDConverter
 

Вложения

  • NRDConverter.zip
    3 МБ · Просмотры: 38
Последнее редактирование модератором:
Пробовал запускать на двух разных компах с разной виндой (7 и 8) и везде вот такая ошибка:

Не подскажите возможные решения или альтернативные программы, что б конвертнуть реплей в txt
спасибо)
 
Пробовал запускать на двух разных компах с разной виндой (7 и 8) и везде вот такая ошибка:

Не подскажите возможные решения или альтернативные программы, что б конвертнуть реплей в txt
спасибо)
Возможная причина Microsoft SQL Server не установлен.
 
Уважаемый автор! Не могли б вы снизойти с вершин своего кодерского опыта до простых смертных новичков и помочь открыть ваш проект для правок.

1) Есть Visual Studio 2019. Я создал в нём :
Create.png


Подключил:
NinjaTrader.Core.dll
System.Data.SqlServerCe.dll

В Form1.cs вставил ваш код. Но выскакивают ошибки:

errors.png

Я так понимаю, что у меня нет кода самой формы... может Form1.Designer.cs или хз, я в этом не разбираюсь :(((.

p.S.
Хочу создать обычное консольное приложение без всяких форм, что б оно напрямую обращалась к реплеям в папке и конвертила их в мой txt формат.
Поэтому пытался разобраться как мне обратиться к .nrd фаилу и выдрать из него нужные мне данные в переменные, которые я уже сам запишу в TXT фаил в нужном мне порядке и формате.
В общем, надеялся что загружу код в отладчик и пошагово посмотрю как этот код выполняется)). Но сейчас смотрю и мне кажется, что у меня с этим кодом так не получится.

Заранее спасибо за помощь!
 
Последнее редактирование:
Пока разбираюсь с кодом, но даже такая простая строчка вызывает Exeption:

errors2.png

Не понимаю, что здесь не так).
 
Поэтому пытался разобраться как мне обратиться к .nrd фаилу и выдрать из него нужные мне данные в переменные, которые я уже сам запишу в TXT фаил в нужном мне порядке и формате.
Не получится. В данном проекте данные записываются в формате, который определяет ниндзя.

Просто берете уже получишиеся текстовые файлы, читаете их и записываете в своем формате.
 
да, видимо вы правы.
последний вопрос: кол-во десятимиллионных долей секунды - это звучит замудрёно).
это значит к DateTime прибавлять timespan.fromticks?
 
Вдруг кому понадобится, т.к. бесплатного скачивания не нашел в интернете:

NT8 Convert Market Replay(NRD) to CSV and Import ticks format

This strategy allows you:
- convert market-replay(NRD) to CSV format (for each day separately)
- convert market-replay to NinjaTrader ticks import format (*.Last.txt, *.Ask.txt, *.Bid.txt)


How to use it:
1) Connect to Market Replay Connection
2) In strategy tab add MarketReplayDumpStrategy and select Contract you're trying to convert for example ES 09-19(make sure that you have any market replays for that contact). TimeFrame of strategy do not matter, same as DaysToLoad, but better select 1 day to load it faster.
3) Make sure folder from strategy settings exists
4) Enable the strategy and watch Output window

* Dump process can be multi-threaded, you can control that via MaxDegreeOfParallelism
* Creation of import data is single threaded since it is writing to one file
* Strategy will automatically detect life time of contact by expiration/rollover dates from NinjaTrader, and adds extra 3 days before and after
* Once conversion process is done strategy will disable itself
* When importing(Tools->Import->Historical Data) set "Time Zone of imported Data" to your NinjaTrader TimeZone(Tools->Options->General->Time Zone)
* Tested on 8.0.19.1 64-bit
 

Вложения

  • MarketReplayDumpStrategyNT8.zip
    161,7 КБ · Просмотры: 16
Последнее редактирование:
В CSV конвертирует в такой же формат, типа:
L2;1;20190724070002;5970000;1;1;;1.1191;65
L1;0;20190724070018;660000;1.1192;35

Но вот как "convert market-replay to NinjaTrader ticks import format (*.Last.txt, *.Ask.txt, *.Bid.txt)" - для меня самого загадка))). Не пойму что делать).
Возможно эта ошибка после создания CSV не просто так:

error.png
 
Последнее редактирование:
☝️Кстати, время (timestamps) в сконвертированных файлах будет в том часовом поясе, который на локальном компьютере в момент конвертации (в обоих прогах)
 
Подскажите есть ли способ конвертировать данные из txt или csv в формат NRD? Цель - демо торговля в режиме Market Replay.
 
Привет,
Для тех, кому надо конвертировать сразу все *.nrd файлы, а не прокликивать на UI каждый файл по отдельности, вот AddOn ниже.

Все что надо это открыть New/NinjaScript Editor, затем в панели справа правой клавишей мышки создать новый AddOn (New Add On) и назвать его NRDToCSV.

Потом вставить код ниже и нажать вверху окна Compile.
После компиляции в меню Tools появится пункт NRD to CSV.

Код:
#region Using declarations
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using System.Text.RegularExpressions;
#endregion

namespace NinjaTrader.Gui.NinjaScript
{
    public class NRDToCSV : AddOnBase
    {
        private NTMenuItem menuItem;
        private NTMenuItem existingMenuItemInControlCenter;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "NRDToCSV";
                Description = "*.nrd to *.csv market replay files convertion";
            }
        }

        protected override void OnWindowCreated(Window window)
        {
            ControlCenter cc = window as ControlCenter;
            if (cc == null) return;

            existingMenuItemInControlCenter = cc.FindFirst("ControlCenterMenuItemTools") as NTMenuItem;
            if (existingMenuItemInControlCenter == null) return;

            menuItem = new NTMenuItem { Header = "NRD to CSV", Style = Application.Current.TryFindResource("MainMenuItem") as Style };
            existingMenuItemInControlCenter.Items.Add(menuItem);
            menuItem.Click += OnMenuItemClick;
        }

        protected override void OnWindowDestroyed(Window window)
        {
            if (menuItem != null && window is ControlCenter)
            {
                if (existingMenuItemInControlCenter != null && existingMenuItemInControlCenter.Items.Contains(menuItem))
                    existingMenuItemInControlCenter.Items.Remove(menuItem);
                menuItem.Click -= OnMenuItemClick;
                menuItem = null;
            }
        }

        private void OnMenuItemClick(object sender, RoutedEventArgs e)
        {
            Core.Globals.RandomDispatcher.BeginInvoke(new Action(() => new NRDToCSVWindow().Show()));
        }
    }

    public class NRDToCSVWindow : NTWindow, IWorkspacePersistence
    {
        private TextBox tbNrdRootDir;
        private TextBox tbCsvRootDir;
        private Button bConvert;
        private TextBox tbOutput;
        
        public NRDToCSVWindow()
        {
            Caption = "NRD to CSV";
            Width     = 512;
            Height     = 640;
            Content = BuildContent();
            Loaded += (o, e) =>
            {
                if (WorkspaceOptions == null)
                    WorkspaceOptions = new WorkspaceOptions("NRDToCSV-" + Guid.NewGuid().ToString("N"), this);
            };
            Closing += (o, e) =>
            {
                if (bConvert != null)
                    bConvert.Click -= OnConvertButtonClick;
            };
        }
        
        private DependencyObject BuildContent()
        {
            double margin = (double) FindResource("MarginBase");
            tbNrdRootDir = new TextBox() {
                IsReadOnly = true,
                Margin = new Thickness(margin, 0, margin, margin),
                Text = Path.Combine(NinjaTrader.Core.Globals.UserDataDir, "db", "replay"),
            };
            Label lNrdRootDir = new Label() {
                Foreground = FindResource("FontLabelBrush") as Brush,
                Margin = new Thickness(margin, 0, margin, 0),
                Content = "_NRD Replays root directory:" ,
            };
            tbCsvRootDir = new TextBox() {
                Margin = new Thickness(margin, 0, margin, margin),
                Text = Path.Combine(NinjaTrader.Core.Globals.UserDataDir, "db", "replay.csv"),
            };
            Label lCsvRootDir = new Label() {
                Foreground = FindResource("FontLabelBrush") as Brush,
                Margin = new Thickness(margin, margin, margin, 0),
                Content = "Converted _CSV root directory:",
            };
            bConvert = new Button()
            {
                Margin = new Thickness(margin),
                IsDefault = true,   
                Content = "_Convert",
            };
            bConvert.Click += OnConvertButtonClick;
            tbOutput = new TextBox() {
                IsReadOnly = true,
                HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                Margin = new Thickness(margin),
            };
            Grid grid = new Grid() { Background = new SolidColorBrush(Colors.Transparent) };
            grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto } );
            grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto } );
            grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto } );
            grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto } );
            grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto } );
            grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) } );
            Grid.SetRow(lNrdRootDir, 0);
            Grid.SetRow(tbNrdRootDir, 1);
            Grid.SetRow(lCsvRootDir, 2);
            Grid.SetRow(tbCsvRootDir, 3);
            Grid.SetRow(bConvert, 4);
            Grid.SetRow(tbOutput, 5);
            grid.Children.Add(lNrdRootDir);
            grid.Children.Add(tbNrdRootDir);
            grid.Children.Add(lCsvRootDir);
            grid.Children.Add(tbCsvRootDir);
            grid.Children.Add(bConvert);
            grid.Children.Add(tbOutput);
            return grid;
        }
        
        private void OnConvertButtonClick(object sender, RoutedEventArgs e)
        {
               if (tbOutput == null) return;
            tbOutput.Clear();
            
            string nrdDir = tbNrdRootDir.Text;
            string csvDir = tbCsvRootDir.Text;
            
            if (!Directory.Exists(nrdDir)) {
                tbOutput.AppendText(string.Format("ERROR: The NRD root directory \"{0}\" not found\r\n", nrdDir));
                return;
            }
            
            if (!Directory.Exists(csvDir)) {
                try
                {
                    Directory.CreateDirectory(csvDir);
                }
                catch (Exception error)
                {
                    tbOutput.AppendText(string.Format("ERROR: Unable to create the CSV root directory \"{0}\": {1}\r\n", csvDir, error.ToString()));
                }
                return;           
            }   
            
            string[] subDirectoryEntries = Directory.GetDirectories(nrdDir);
            if (subDirectoryEntries.Length == 0) {
                tbOutput.AppendText(string.Format("ERROR: The NRD root directory \"{0}\" is empty\r\n", nrdDir));
                return;
            }               

            foreach (string subDirectory in subDirectoryEntries)
                ProcessDirectory(subDirectory, csvDir);
            
            tbOutput.AppendText("Conversion complete\r\n");
        }
        
        private void ProcessDirectory(string nrdDirectory, string csvDir)
        {
            string[] fileEntries = Directory.GetFiles(nrdDirectory, "*.nrd");
            if (fileEntries.Length == 0)
            {
                tbOutput.AppendText(string.Format("WARNING: No *.nrd files found in \"{0}\" directory. Skipped\r\n", nrdDirectory));
                return;
            }
            
            // int i = 0;
            foreach (string fileName in fileEntries)
            {
                string fullName = Path.GetFileName(Path.GetDirectoryName(fileName));
                Collection<Instrument> instruments = NinjaTrader.Cbi.InstrumentList.GetInstruments(fullName);
                
                if (instruments.Count == 0) {
                    tbOutput.AppendText(string.Format("Unable to find an instrument name \"{0}\"\r\n", fullName));
                    continue;
                } else if (instruments.Count > 1) {
                    tbOutput.AppendText(string.Format("More than one instrument was identified for name \"{0}\"\r\n", fullName));
                    continue;
                }
                
                string name = Path.GetFileNameWithoutExtension(fileName);
                DateTime date = new DateTime(
                    Convert.ToInt16(name.Substring(0, 4)),
                    Convert.ToInt16(name.Substring(4, 2)),
                    Convert.ToInt16(name.Substring(6, 2)));
                
                foreach (Cbi.Instrument instrument in instruments) {
                    string csvFileName = string.Format("{0}.csv", Path.Combine(csvDir, instrument.FullName, name));
                    string csvFileDir = Path.GetDirectoryName(csvFileName);
                    if (!Directory.Exists(csvFileDir))
                        Directory.CreateDirectory(csvFileDir);
                    tbOutput.AppendText(string.Format("Convert \"{0}\\{1}.nrd\" to \"{2}\\{3}.csv\": {4:yyyy-mm-dd}\r\n",
                        fullName, name, instrument.FullName, name, date));
                    MarketReplay.DumpMarketDepth(instrument, date.AddDays(1), date.AddDays(1), csvFileName);
                }
                // if (i++ == 1) break;
            }
        }

        public void Restore(XDocument document, XElement element) { }

        public void Save(XDocument document, XElement element) { }

        public WorkspaceOptions WorkspaceOptions { get; set; }
    }
}
 
Теперь есть GitHub репозиторий NRDToCSV в виде загружаемого расширения (AddOn):

132671281-c7f68d43-cbfa-47da-87db-3092c60ec55c.png

  • Добавлена возможность выбирать какие файлы конвертировать на базе регулярных выражений
  • Конвертация теперь не блокирует UI
 

futuresishere спасибо за addon​

Добрый день! запустил конвертацию, все работает.
Теперь вопрос. Возможно кто-то уже сталкивался с этим:
1) если взять комбинацию файлов: .Last.txt (экспорт из Ninja) и Replay.csv ( конвертация market_replay).
2) по логике они должны быть синхронизированы по времени: время из Last ( трейд) должен вызвать изменения в L2 , и bid и ask должны как-то соответствовать как в Last, так и в Replay. у меня DateTime в Last практически никогда не совпадает с DateTime в L2, то есть я не могу определить влияние трейд на order book.
Кто-то сталкивался с этой проблемой?
 
Назад
Верх Низ