• Demo счет NinjaTrader, регистрируется в брокерской компании NinjaTrader Brokerage . NinjaTrader™, LLC
    Ссылка на демо счет NinjaTrader
    Фид на соединении Continuum/CQG.
    Для справки: Continuum - это брэнд CQG.
    Обратите внимание, что в настоящее время CQG не высылает логин и пароль на электронные адреса от mail.ru, bk.ru, list.ru, inbox.ru, поэтому необходимо повторить регистрацию с электронного адреса от другого домейна (yahoo, gmail, и тд).
  • NinjaTrader с зарекомендовавшим себя брокерским сервисом предоставляет наилучшие условия для фьючерсной торговли, включая:
    • Низкие комиссии: Экономьте на торгах через низкие и понятные комиссии
    • Низкая маржа: Всего $50 для микро контрактов
    • Низкие минимумы: Откройте счет от $100
    • Бесплатная платформа: Включает весь необходимый функционал для торговли в реале
  • Уважаемые посетители форума!
    При регистрации на форуме отправляется письмо подтверждения на ваш почтовый ящик, если письмо не пришло, просьба проверить папку "спам" вашего почтового ящика, возможно письмо попало туда.
  • Сколько я реально плачу комиссии?
    Подробнее по ссылке

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 МБ · Просмотры: 30
Последнее редактирование модератором:

my-trade

New Member
NinjaTrader
Пробовал запускать на двух разных компах с разной виндой (7 и 8) и везде вот такая ошибка:

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

rare312

Active Member
NinjaTrader
Пробовал запускать на двух разных компах с разной виндой (7 и 8) и везде вот такая ошибка:

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

Alexander

Administrator
Команда форума
Помогли тебе - помоги другим!

my-trade

New Member
NinjaTrader
Уважаемый автор! Не могли б вы снизойти с вершин своего кодерского опыта до простых смертных новичков и помочь открыть ваш проект для правок.

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 фаил в нужном мне порядке и формате.
В общем, надеялся что загружу код в отладчик и пошагово посмотрю как этот код выполняется)). Но сейчас смотрю и мне кажется, что у меня с этим кодом так не получится.

Заранее спасибо за помощь!
 
Последнее редактирование:

my-trade

New Member
NinjaTrader
Пока разбираюсь с кодом, но даже такая простая строчка вызывает Exeption:

errors2.png

Не понимаю, что здесь не так).
 

NT8

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

Просто берете уже получишиеся текстовые файлы, читаете их и записываете в своем формате.
 

my-trade

New Member
NinjaTrader
да, видимо вы правы.
последний вопрос: кол-во десятимиллионных долей секунды - это звучит замудрёно).
это значит к DateTime прибавлять timespan.fromticks?
 

my-trade

New Member
NinjaTrader
Вдруг кому понадобится, т.к. бесплатного скачивания не нашел в интернете:

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 КБ · Просмотры: 11
Последнее редактирование:

my-trade

New Member
NinjaTrader
В 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
 
Последнее редактирование:

my-trade

New Member
NinjaTrader
☝️Кстати, время (timestamps) в сконвертированных файлах будет в том часовом поясе, который на локальном компьютере в момент конвертации (в обоих прогах)
 

Dejorden

New Member
NinjaTrader
Подскажите есть ли способ конвертировать данные из txt или csv в формат NRD? Цель - демо торговля в режиме Market Replay.
 

futuresishere

New Member
NinjaTrader
Привет,
Для тех, кому надо конвертировать сразу все *.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; }
    }
}
 

futuresishere

New Member
NinjaTrader
Теперь есть GitHub репозиторий NRDToCSV в виде загружаемого расширения (AddOn):

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

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

ryarom148

New Member
NinjaTrader

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

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