• Demo счет NinjaTrader, регистрируется через личный кабинет в брокерской компании NinjaTrader Brokerage . NinjaTrader™, LLC
    Ссылка на личный кабинет NinjaTrader
    Не открывается ссылка - используйте любой локальный VPN или дополнение для браузера.
    Google поиск VPN
    Яндекс поиск VPN
  • Уважаемые посетители форума!
    При регистрации на форуме отправляется письмо подтверждения на ваш почтовый ящик, если письмо не пришло, просьба проверить папку "спам" вашего почтового ящика, возможно письмо попало туда.
  • Сколько я реально плачу комиссии?
    Подробнее по ссылке

С чего начать ?

zencoder

New Member
NinjaTrader
Всем дорого времени суток. Совсем недавно я начал изучать Ninja и ее язык программирования. Имею достаточно большой опыт программирования на C# и MQL4 (metatrader). Попытался написать простейший индикатор (с учебной целью) который просто рисует разницу между ценой закрытия текущего и предыдущего баров. не получилось :((

В МТ было все просто:
объявили обычный массив - double buf[]
связали его с "линией графика" - SetIndexBuffer(0,buf)
заполнили элементы массива значениями - for(i=0;i<Bars;i++) buf=Close[i+1]-Close
и платформа сама нарисовала линию графика.

Я рассчитывал что НТ тоже сделано както похоже. Но у меня ничего не получилось. Как то по своему сделано все НТ, но как именно - нигде толком не описано.

Уважаемые знатоки программирования НТ, потратьте пожалуйста немного своего времени - напишите этот простейший учебный индикатор и объясните где и как доступится к ценовым данным и как их отобразить на графике своего индикатора. Или дайте ссылку где это описано для начинающих (кроме хелпа и сайта производителя пожалуйста - эти я и так знаю).
 

knowledgebase

Administrator
Команда форума
Помогли тебе - помоги другим!
NinjaTrader
zencoder сказал(а):
Всем дорого времени суток. Совсем недавно я начал изучать Ninja и ее язык программирования. Имею достаточно большой опыт программирования на C# и MQL4 (metatrader). Попытался написать простейший индикатор (с учебной целью) который просто рисует разницу между ценой закрытия текущего и предыдущего баров. не получилось :((

В МТ было все просто:
объявили обычный массив - double buf[]
связали его с "линией графика" - SetIndexBuffer(0,buf)
заполнили элементы массива значениями - for(i=0;i<Bars;i++) buf=Close[i+1]-Close
и платформа сама нарисовала линию графика.

Я рассчитывал что НТ тоже сделано както похоже. Но у меня ничего не получилось. Как то по своему сделано все НТ, но как именно - нигде толком не описано.

Уважаемые знатоки программирования НТ, потратьте пожалуйста немного своего времени - напишите этот простейший учебный индикатор и объясните где и как доступится к ценовым данным и как их отобразить на графике своего индикатора. Или дайте ссылку где это описано для начинающих (кроме хелпа и сайта производителя пожалуйста - эти я и так знаю).


Добрый день, а не пытались Вы открыть и посмотреть сами индикаторы в НТ? Они все открываются без проблем...и их несметное множество. Как вариант...
 

zencoder

New Member
NinjaTrader
Еще как пытался. Добросовестно пересмотрел ВСЕ индикаторы из НТ. Но они все написаны для случая когда график строится по массиву который заполняется "массовой операцией" что то вроде Value.Set(Close[0]). А мне нужно пройтись по каждому бару, обсчитать его индивидуально (с учетом значений на соседних барах) и присвоить каждой точке графика свое значение.
Есть конструкция Value.Set(BarAgo, Close[0]) но что я не пытался с ней сделать и так писал и этак.... никак на графике ничего не рисуется.

поэтому и попросил для примера/обучения такой работающий код с поэлементным присваиванием получением и присваиванием значений.
 

K0T

Member
NinjaTrader
zencoder сказал(а):
Еще как пытался. Добросовестно пересмотрел ВСЕ индикаторы из НТ. Но они все написаны для случая когда график строится по массиву который заполняется "массовой операцией" что то вроде Value.Set(Close[0]). А мне нужно пройтись по каждому бару, обсчитать его индивидуально (с учетом значений на соседних барах) и присвоить каждой точке графика свое значение.
Есть конструкция Value.Set(BarAgo, Close[0]) но что я не пытался с ней сделать и так писал и этак.... никак на графике ничего не рисуется.

поэтому и попросил для примера/обучения такой работающий код с поэлементным присваиванием получением и присваиванием значений.
с чего бы это "массовой операцией"?
есть метод OnBarUpdate, который дергается либо по закрытию бара, либо по каждому тику (если не на истории и выставлено CalculateOnBarClose = false), и из него можно обновлять все значения индюка, существующие на данный момент, Value[0] - текущий бар, Value[1] - предидущий и т.п. (т.е. в будущее штатными средствами залезть не выйдет). При этом при открытии чарта ниндзя честным образом рисует первый бар, дергает OnBarUpdate и считает значение индюка для него, потом рисует второй бар, и т.д. до текущего момента, таким образом обсчитывая все бары по очереди... И в принципе ничего не мешает из OnBarUpdate смотреть всю историю вглубь и пересчитывать значение индюка так как хочется.

как пример - @SMA.cs, @EMA.cs, @ParabolicSAR.cs, @SUM.cs
а для разницы цены между последим и предпоследним баром в OnBarUpdate достаточно прописать Value[0] = Close[0]-Close[1];
ну или Value[0] = Close[1]-Close[0];
:)

зы да, совсем забыл - чтобы обращаться к истории, нужно чтоб она была - т.е. если на первом баре попытаться смотреть Close[10], вылетишь по эксепшну
т.е. полный код OnBarUpdate для графика разницы текущего и прошлого бара будет
Код:
protected override void OnBarUpdate()
{
if (CurrentBar>0)
 {
 //считаем значения индюка со второго бара серии
 Value[0] = Close[1] - Close[0];
 }
}
 

Вложения

  • Diff01.tar.gz
    2 КБ · Просмотры: 118

knowledgebase

Administrator
Команда форума
Помогли тебе - помоги другим!
NinjaTrader
K0T сказал(а):
zencoder сказал(а):
Еще как пытался. Добросовестно пересмотрел ВСЕ индикаторы из НТ. Но они все написаны для случая когда график строится по массиву который заполняется "массовой операцией" что то вроде Value.Set(Close[0]). А мне нужно пройтись по каждому бару, обсчитать его индивидуально (с учетом значений на соседних барах) и присвоить каждой точке графика свое значение.
Есть конструкция Value.Set(BarAgo, Close[0]) но что я не пытался с ней сделать и так писал и этак.... никак на графике ничего не рисуется.

поэтому и попросил для примера/обучения такой работающий код с поэлементным присваиванием получением и присваиванием значений.
с чего бы это "массовой операцией"?
есть метод OnBarUpdate, который дергается либо по закрытию бара, либо по каждому тику (если не на истории и выставлено CalculateOnBarClose = false), и из него можно обновлять все значения индюка, существующие на данный момент, Value[0] - текущий бар, Value[1] - предидущий и т.п. (т.е. в будущее штатными средствами залезть не выйдет). При этом при открытии чарта ниндзя честным образом рисует первый бар, дергает OnBarUpdate и считает значение индюка для него, потом рисует второй бар, и т.д. до текущего момента, таким образом обсчитывая все бары по очереди... И в принципе ничего не мешает из OnBarUpdate смотреть всю историю вглубь и пересчитывать значение индюка так как хочется.

как пример - @SMA.cs, @EMA.cs, @ParabolicSAR.cs, @SUM.cs
а для разницы цены между последим и предпоследним баром в OnBarUpdate достаточно прописать Value[0] = Close[0]-Close[1];
ну или Value[0] = Close[1]-Close[0];
:)

зы да, совсем забыл - чтобы обращаться к истории, нужно чтоб она была - т.е. если на первом баре попытаться смотреть Close[10], вылетишь по эксепшну
т.е. полный код OnBarUpdate для графика разницы текущего и прошлого бара будет
Код:
protected override void OnBarUpdate()
{
if (CurrentBar>0)
 {
 //считаем значения индюка со второго бара серии
 Value[0] = Close[1] - Close[0];
 }
}

В очередной раз спасибо :-)
 

zencoder

New Member
NinjaTrader
Спасибо! МТшная "идеология" попутала :(
Я думал что Close[0] это массив цен закрытия (всех баров) с индексом ноль, а Close[1] это как бы второй буфер содержащий копию опять таки массив всех цен закрытия.
Соотвественно я думал, что если я хотел нарисовать две линии то Value[0] - это массив всех значений первой линии, а вторая линия содержит свои данные в Value[1]. И чтобы получить предыдущий элемент первого графика мне надо написать Value[0][1].
Теперь все стало на свои места.

Получается что если на графике нажимаю кнопочку F5 или первый раз присоединяю индикатор, то он для всех имеющихся баров истории поочереди дергает событие OnBarUpdate? и Close[ Bars.Count-1 ] при переходе к следующему бару станет на место Bars.Count-2 а на его месте (Bars.Count-1) будет цена открытия только что появившегося бара?
 

K0T

Member
NinjaTrader
zencoder сказал(а):
Спасибо! МТшная "идеология" попутала :(
Я думал что Close[0] это массив цен закрытия (всех баров) с индексом ноль, а Close[1] это как бы второй буфер содержащий копию опять таки массив всех цен закрытия.
Соотвественно если я хотел нарисовать две линии то Value[0] - это массив всех значений первой линии, а вторая линия содержит свои данные в Value[1]. И чтобы получить предыдущий элемент первого графика мне надо написать Value[0][1].
Теперь все стало на свои места.

Получается что если на графике нажимаю кнопочку F5 или первый раз присоединяю индикатор, то он для всех имеющихся баров истории поочереди дергает событие OnBarUpdate? и Close[ Bars.Count-1 ] при переходе к следующему бару станет на место Bars.Count-2 а на его месте (Bars.Count-1) будет цена открытия только что появившегося бара?
Почти так. Только нумерация серии идет от текущего момента назад в историю. В [0] всегда текущее значение (самый свежий по времени бар), и как только появляется новый бар, [0] становится [1], [1] - [2] и т.п. Соответственно Close[Bars.Count], он же, если я правильно помню, Close[CurrentBar]- это закрытие самого первого бара на чарте.
Да, а если нужно несколько датасерий, то первая серия это Values[0], вторая Values[1] и далее, а их элементы - Values[0][0] , Values[0][1]
 

zencoder

New Member
NinjaTrader
Спасибо. все потихоньку становится на свои места.
Проясните пожалуйста еще одни вопрос.
В МТ есть такое понятие как скрипты - это своего рода однократно выполняющиеся эксперты. Я с их помощью делаю две вещи: собственно торгую (открываю/закрываю ордера) и управляю работой обычного эксперта (сброс скрипта устанавливает значение глобальной переменной которое я могу получить и обработать в непрерывно работающем эксперте, например, изментиь параметры настройки, ММ, тот же размер торгуемого лота).

Можно ли в нинзе реализовать такое же?
Как можно в произвольное время, вручную, передать какойто "параметр" внутрь эксперта или индикатора? Как (кроме параметров эксперта) можно управлять его работой?
 

K0T

Member
NinjaTrader
zencoder сказал(а):
Спасибо. все потихоньку становится на свои места.
Проясните пожалуйста еще одни вопрос.
В МТ есть такое понятие как скрипты - это своего рода однократно выполняющиеся эксперты. Я с их помощью делаю две вещи: собственно торгую (открываю/закрываю ордера) и управляю работой обычного эксперта (сброс скрипта устанавливает значение глобальной переменной которое я могу получить и обработать в непрерывно работающем эксперте, например, изментиь параметры настройки, ММ, тот же размер торгуемого лота).

Можно ли в нинзе реализовать такое же?
Как можно в произвольное время, вручную, передать какойто "параметр" внутрь эксперта или индикатора? Как (кроме параметров эксперта) можно управлять его работой?
подергать один индюк из другого в пределах одного чарта возможно, но не тривиально.
для NT6.5 вот например так:
Код:
for (int di=0;di<ChartControl.Indicators.Length;di++){
   if (ChartControl.Indicators[di].Name=="SMA"){
    smaIndNum=di;
    Print("SMA indicator found, name="+ChartControl.Indicators[di].Name+",number="+di);
   }
}

ChartControl.Indicators[smaIndNum].ПодергатьКакойНибудьМетод();
так же можно подергать индюки в пределах одной стратегии, а вот чтобы достучаться из одного чарта в другой наверное нужно лезть в дебри C#, пайпы и т.п ...
 

zencoder

New Member
NinjaTrader
K0T сказал(а):
В [0] всегда текущее значение (самый свежий по времени бар), и как только появляется новый бар, [0] становится [1], [1] - [2] и т.п.

а в хелпе написано вот такое
CurrentBar
A number representing the current bar in a Bars object that the OnBarUpdate() method in an indicator or strategy is currently processing. For example, if a chart has 100 bars of data, the very first bar of the chart (left most bar) will be number 0 (zero) and each subsequent bar from left to right is incremented by 1.

получается вроде как наоборот?
 

K0T

Member
NinjaTrader
почему наоборот? все правильно написано. CurrentBar - это номер бара на чарте, и у него нумерация слева направо во времени. А у датасерий индюков - нумерация во времени справа налево. Нумерация вагонов начинается с хвоста поезда :D Соответственно Value[CurrentBar] - это значение индюка для самого раннего во времени бара, а Value[0] - для самого позднего (текущий бар). Нафига они так сделали- хз, по началу путает изрядно, это факт.
 

zencoder

New Member
NinjaTrader
аха. вот теперь понятен смысл бывшей ранее загадки: зачем проверять CurrentBar на равенство нулю.

Еще если можно еще пару слов: можно писать коды индикаторов и экспертов не во встроенном редакторе а в MS VS 2010 C# Express? Ну хотябы сначала сгенерить пустышку-заготовку индикатора мастером нинзи, но потом работать с ней уже в VS2010? Если да - то как их "состыковать"?
 

K0T

Member
NinjaTrader
zencoder сказал(а):
аха. вот теперь понятен смысл бывшей ранее загадки: зачем проверять CurrentBar на равенство нулю.

Еще если можно еще пару слов: можно писать коды индикаторов и экспертов не во встроенном редакторе а в MS VS 2010 C# Express? Ну хотябы сначала сгенерить пустышку-заготовку индикатора мастером нинзи, но потом работать с ней уже в VS2010? Если да - то как их "состыковать"?
смысл встроенного редактора в том, что он по ф5 индюк компилит, и результат вставляет в dll существующих индюков, ну и по ниндзевским методам предоставляет хелп. как это из другой проги сделать - хз, а редактировать - это в чем угодно, хоть в VS, хоть в фаре :) исходники живут в <мои документы>\NinjaTrader [6.5|7]\bin\Custom\Indicator
 

Vitar007

New Member
NinjaTrader
чтобы индюк или стратегия могла подергать информацию из индюка или стратегии в соседнем чарте, есть путь через запись в файл: в скрипте в соседнем окне должна быть конструкция записи в файл типа:
в
#region Variables
// Wizard generated variables
private string pathEntrySignals = @"C:\_(файл формата блокнот )______
а в
protected override void OnBarUpdate()
{
StreamWriter SW = new StreamWriter(pathEntrySignals,false);
string rrec="";
и например
if (UP) rrec = "1"; if (DN) rrec = "2"; if (!UP && !DN) rrec = "0";
SW.WriteLine(rrec); SW.Close();

Результатом будет 1 или 2 или 0 в блокноте (старые данные заменяются новыми)

а вот дальше ------ вопрос, кто знает - как считать содержимое блокнота стратегией?
или есть путь попроще?
 

Vitar007

New Member
NinjaTrader
как поймать момент смены бара? или момент первого тика нового бара...
чтобы в стратегии написать что-то вроде
if (first tick) n = n+1; // n - количество баров с момента запуска стратегии
if (n>m) //(сделать что-то); // когда накопится m баров с момента запуска, сделать что-то
 

vlil19

New Member
NinjaTrader
если мне нужно поработать на информации 2009 года. она загружена в датасерию. построен минутный график. как соответствуют бары графика данным таймсерии? почему в начале графика CurrentBar равен нулю и номера баров полученные через Bars.GetBar(time) возрастаю слева направо? получается что это не номера баров в таймсерии а просто номера баров на графике? а нахрен они вообще нужны? почему на 12-м баре я уже получаю ошибку out of range? хотя баров загружена огромная куча.
 

Привал

Well-Known Member
NinjaTrader
Vitar007 сказал(а):
как поймать момент смены бара? или момент первого тика нового бара...
чтобы в стратегии написать что-то вроде
if (first tick) n = n+1; // n - количество баров с момента запуска стратегии
if (n>m) //(сделать что-то); // когда накопится m баров с момента запуска, сделать что-то

Код:
			if (FirstTickOfBar)
    		{
				Print("Первый тик бара " + Bars.TickCount.ToString());
		}
 

Вова

New Member
NinjaTrader
K0T сказал(а):
Еще если можно еще пару слов: можно писать коды индикаторов и экспертов не во встроенном редакторе а в MS VS 2010 C# Express? Ну хотябы сначала сгенерить пустышку-заготовку индикатора мастером нинзи, но потом работать с ней уже в VS2010? Если да - то как их "состыковать"?
Здравствуйте, присоединяюсь к теме. Озадачен проблемой дружбы внешней программы (торговый робот) и NT. Если есть у кого-нибудь примеры простенькие, которые подключают внешнюю программу, написанную на C# к NT, поделитесь пожалуйста.

Нашел документацию, но без примеров сложно переварить информацию.
 
Верх Низ