• Demo счет NinjaTrader, регистрируется в брокерской компании NinjaTrader Brokerage . NinjaTrader™, LLC
    Ссылка на демо счет NinjaTrader
    Фид на соединении Continuum/CQG.
    Для справки: Continuum - это брэнд CQG, и ни чем они не отличаются друг от друга.
  • Сколько я реально плачу комиссии?
    Подробнее по ссылке

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

zencoder

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

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

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

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

broker_mirus

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

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

K0T

Member
NinjaTrader
#4
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];
 }
}
 

Вложения

broker_mirus

Administrator
Команда форума
Помогли тебе - помоги другим!
NinjaTrader
#5
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
#6
Спасибо! МТшная "идеология" попутала :(
Я думал что 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
#7
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
#8
Спасибо. все потихоньку становится на свои места.
Проясните пожалуйста еще одни вопрос.
В МТ есть такое понятие как скрипты - это своего рода однократно выполняющиеся эксперты. Я с их помощью делаю две вещи: собственно торгую (открываю/закрываю ордера) и управляю работой обычного эксперта (сброс скрипта устанавливает значение глобальной переменной которое я могу получить и обработать в непрерывно работающем эксперте, например, изментиь параметры настройки, ММ, тот же размер торгуемого лота).

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

K0T

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

zencoder

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

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

K0T

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

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

Vitar007

New Member
NinjaTrader
#14
чтобы индюк или стратегия могла подергать информацию из индюка или стратегии в соседнем чарте, есть путь через запись в файл: в скрипте в соседнем окне должна быть конструкция записи в файл типа:
в
#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
#15
как поймать момент смены бара? или момент первого тика нового бара...
чтобы в стратегии написать что-то вроде
if (first tick) n = n+1; // n - количество баров с момента запуска стратегии
if (n>m) //(сделать что-то); // когда накопится m баров с момента запуска, сделать что-то
 

vlil19

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

Привал

Well-Known Member
NinjaTrader
#17
Vitar007 сказал(а):
как поймать момент смены бара? или момент первого тика нового бара...
чтобы в стратегии написать что-то вроде
if (first tick) n = n+1; // n - количество баров с момента запуска стратегии
if (n>m) //(сделать что-то); // когда накопится m баров с момента запуска, сделать что-то
Код:
			if (FirstTickOfBar)
    		{
				Print("Первый тик бара " + Bars.TickCount.ToString());
		}
 

Вова

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

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