Вы находитесь на странице: 1из 635

Ninja Script

Изменения, нарушающие код

Следующий документ представляет собой общий обзор изменений NinjaScript, которые вы


можете ожидать между NinjaTrader 7 и NinjaTrader 8. Для получения конкретной информации о
конкретном методе или свойстве вы можете обратиться к динамически отформатированной
таблице взлома кода внизу этой страницы. . Мы рекомендуем использовать встроенные в
таблицу функции фильтрации и сортировки, а также проверять столбец «Сводка» и расширять
раздел «Подробности» каждой записи для получения общей информации. Ссылаясь на удобно
связанную документацию NinjaTrader 8 и NinjaTrader 7, вы получите конкретную информацию о
синтаксисе, использовании и примерах любой новой реализации или названий элементов.

Примечание. Информация на этой странице сосредоточена на поддерживаемых


(задокументированных) методах и свойствах NinjaTrader, общих для разных версий. В
NinjaTrader 8 наблюдается значительный рост поддерживаемого кода NinjaTrader, однако, если
вы использовали ранее недокументированные методы или свойства NinjaTrader 7, они НЕ
будут рассматриваться в этой теме. Вы можете найти дополнительную информацию о ранее
недокументированных методах и свойствах в Справочном руководстве по NinjaTrader 8, или
наши сотрудники службы поддержки также будут рады лично указать вам в правильном
направлении.
Критично: если в вашем продукте используются неподдерживаемые (недокументированные)
элементы, мы настоятельно рекомендуем вам тщательно протестировать свои скрипты, чтобы
убедиться, что они по-прежнему работают должным образом. НЕТ гарантии, что ранее
недокументированное поведение метода или свойства не изменилось в новой версии
NinjaTrader 8.
Следующий документ представляет собой общий обзор изменений NinjaScript, которые вы
можете ожидать между NinjaTrader 7 и NinjaTrader 8. Для получения конкретной информации о
конкретном методе или свойстве вы можете обратиться к динамически отформатированной
таблице взлома кода внизу этой страницы. . Мы рекомендуем использовать встроенные в
таблицу функции фильтрации и сортировки, а также проверять столбец «Сводка» и расширять
раздел «Подробности» каждой записи для получения общей информации. Ссылаясь на удобно
связанную документацию NinjaTrader 8 и NinjaTrader 7, вы получите конкретную информацию о
синтаксисе, использовании и примерах любой новой реализации или названий элементов.
Примечание. Информация на этой странице сосредоточена на поддерживаемых
(задокументированных) методах и свойствах NinjaTrader, общих для разных версий. В
NinjaTrader 8 наблюдается значительный рост поддерживаемого кода NinjaTrader, однако, если
вы использовали ранее недокументированные методы или свойства NinjaTrader 7, они НЕ
будут рассматриваться в этой теме. Вы можете найти дополнительную информацию о ранее
недокументированных методах и свойствах в Справочном руководстве по NinjaTrader 8, или
наши сотрудники службы поддержки также будут рады лично указать вам в правильном
направлении.
Критично: если в вашем продукте используются неподдерживаемые (недокументированные)
элементы, мы настоятельно рекомендуем вам тщательно протестировать свои скрипты, чтобы
убедиться, что они по-прежнему работают должным образом. НЕТ гарантии, что ранее
недокументированное поведение метода или свойства не изменилось в новой версии
NinjaTrader 8.

Initialize(), OnStartUp(), OnTermination()


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

Например, передача настроек в пользовательский интерфейс или установка начальных


значений для общедоступных свойств теперь может быть выполнена с помощью
OnStateChange (), когда состояние достигло State.SetDefaults:

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// set the default properties
Name = "My Indicator";
Fast = 10;
Slow = 25;
IsOverlay = true;
IsAutoScale = true;
}
}

Если у вас есть пользовательские ресурсы, которые необходимо настроить до того, как объект
NinjaTrader станет активным и обрабатывает данные, вместо использования метода Initialize ()
теперь вы можете настроить это, как только метод OnStateChange () достигнет состояния
State.Configure:

protected override void OnStateChange()


{
if (State == State.Configure)
{
// Add a 5 minute Bars object to the strategy
AddDataSeries(Data.BarsPeriodType.Minute, 5);
// setup a custom data series
spread = new Series<double>(this);
// setup a 20-period EMA indicator
ema = EMA(20);
// add indicator to strategy for visual purposes
AddChartIndicator(ema);

}
}

В NinjaTrader 7 не было концепции, позволяющей определить, когда ваш объект NinjaTrader


переходит от обработки исторических данных к обработке данных в реальном времени. Теперь
с NinjaTrader 8 метод OnStateChange () предоставляет состояние State.Transition, которое
уведомит вас, когда это изменение вот-вот произойдет. Если ваши индикаторы или стратегии
NinjaTrader 7 использовали пользовательские методы для обнаружения этого перехода, ваши
пользовательские методы могут быть отредактированы в этом новом состоянии:

protected override void OnStateChange()


{
if (State == State.Transition)
{
Print("We're going to real-time data...");
// setup your real-time data resources here
}
}

Когда ваш объект NinjaTrader завершает работу и вам нужно очистить все пользовательские
ресурсы устройства, вместо использования OnTermination () теперь вы должны очистить эти
ресурсы, как только метод OnStateChange () достигнет состояния State.Terminated:

protected override void OnStateChange()


{
if (State == State.Terminated)
{
// release any device resources
if(myTimer != null)
myTimer = null;
}
}

NinjaTrader ранее использовал свойство Historical bool для уведомления, когда индикатор или
панель стратегии обрабатывались в историческом или реальном времени. Подход NinjaTrader 8
OnStateChange () теперь представил переменную State уровня класса, в которой вы можете
проверить State.Historical или State.Realtime в любом из других методов событий, которые
позволят вам действовать в зависимости от желаемого состояния:

protected override void OnBarUpdate()


{
// only process on real-time data
if (State == State.Historical)
return;

else if (State >= State.Realtime)


// rest of logic
}

Стратегии, заказы и счета


Был предоставлен доступ на низком уровне, чтобы обеспечить большую гибкость при
использовании информации, относящейся к торговым данным
• Интерфейсы IOrders, IExecution и IPosition были заменены непосредственно на
соответствующий объект
• Сигнатуры связанных событий NinjaScript изменены, чтобы соответствовать внутренним
событиям обновления NinjaTrader
• Методы теперь возвращаются и обновляются с помощью созданного экземпляра объекта
вместо ранее использовавшегося интерфейса.
Совет: поскольку NinjaTrader 8 теперь предоставляет прямой объект ордера, а не интерфейс
IOrder, можно получить ошибки ссылки на пустой объект, если вы попытаетесь получить доступ
к объекту ордера до того, как метод ордера входа или выхода вернется. Чтобы предотвратить
такие ситуации, рекомендуется назначать переменные Order ваших стратегий в методе
OnOrderUpdate () и сопоставлять их по имени сигнала (order.Name). См. Пример,
начинающийся в строке №22 ниже, для демонстрации присвоения объектов заказа частным
переменным.

Order myOrder = null;

protected override void OnBarUpdate()


{
if (Position.MarketPosition == MarketPosition.Flat && myOrder == null)
EnterLongLimit(Low[0], "Entry");

if (myOrder != null)
{
Print(myOrder.OrderState);

if (myOrder.OrderState == OrderState.Cancelled || myOrder.OrderState == OrderState.Filled)


myOrder = null;
}
}

protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice,


int quantity, int filled, double averageFillPrice,
Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string comment)
{
// compare the order object created via EnterLongLimit by the signal name
if (myOrder == null && order.Name == "Entry")
{
// assign myOrder to matching order update
myOrder = order;
}
}
Серия данных

Раньше существовали реализации Data Series для конкретных типов (например, IntSeries,
TimeSeries, BoolSeries и т. Д.). Теперь есть только шаблонный класс Series <T>, который можно
использовать в общих чертах и даже позволяет поддерживать дополнительные типы:

Series<double> mySeries = new Series<double>(this);


Series<DateTime> myTimeSeries = new Series<DateTime>(this);

Метод DataSeries.Set (), используемый для присвоения значений Data Series или Plot, был
удален, и теперь значения можно сохранять с помощью одного оператора присваивания:

protected override void OnBarUpdate()


{
// set public plotting data series close value of current bar
MyPlot[0] = Close[0];
// set custom Series<DateTime> to time value of current bar
myTimeSeries[0] = Time[0];
}

Рисунок
DrawObjects, используемые в NinjaTrader, претерпели ряд изменений:
• Все объекты DrawObject перемещены в отдельное пространство имен NinjaScript.DrawingTools
и правильно известны как DrawingTools.
• Методы рисования, вызываемые из индикаторов или стратегий, были перемещены в новый
статический частичный класс рисования.
• Все методы рисования получили изменение подписи, которое требует, чтобы вы указали
владельца (объект), который нарисовал объект DrawingTool.
• Методы рисования больше не возвращают интерфейс, а скорее экземпляр самого объекта
DrawingTool.
• В методах рисования теперь используется класс System.Windows.Media.Brushes вместо
структуры System.Drawing.Color.
Совет: DrawingTools теперь полностью незащищены, и вы можете просмотреть их исходный
код из папки DrawingTools меню проводника редактора NinjaScript.

// example syntax
Draw.Line(NinjaScriptBase owner, string tag, int startBarsAgo, double startY, int endBarsAgo, double
endY, Brush brush)

// example usage
Draw.Line(this, "tag1", true, 10, Low[0], 0, Brushes.Red);

Приведение члена коллекции DrawObjects [] должно выполняться безопасно с использованием


ключевого слова as, в противном случае вы можете получить исключения во время
выполнения, если другой экземпляр объекта (например, соответствующий тег) существует от
другого владельца:

NinjaScript.DrawingTools.Line myLine = DrawObjects["tag1"] as DrawingTools.Line;

Поля привязки DrawingTools, такие как «Время» или «Цена» и т. Д., Были перемещены в объект
ChartAnchor, принадлежащий инструменту рисования, а не в прямое поле в интерфейсе
графического объекта. Пожалуйста, обратитесь к документации NinjaTrader 8 за конкретными
изменениями для каждого инструмента рисования:

double linePrice = myLine.StartAnchor.Price;

Объекты, которые ранее использовали System.Drawing.Font, теперь используют новый класс


NinjaTrader.Gui.Tools.SimpleFont:

Gui.Tools.SimpleFont myFont = new Gui.Tools.SimpleFont("Arial", 12);

Свойства и другие методы / объекты, которые ранее были структурой System.Drawing.Color,


теперь используют класс System.Windows.Media.Brushes:

BackBrush = Brushes.Blue;

Примечание. Для пользовательских объектов Brush важно .Freeze () Brush из-за многопоточной
архитектуры NinjaTrader 8. Обязательно ознакомьтесь с новой информацией об использовании
кистей.
Пространства имен NinjaTrader 7 NinjaTrader.Indicator и NinjaTrader.Strategy были
переименованы и перемещены в единое пространство имен NinjaTrader.NinjaScript.

//This namespace holds indicators in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Indicators
{
public class MyCustomIndicator : Indicator
{
}
}

//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class MyCustomStrategy : Strategy
{
}
}

Частичные классы (методы и свойства переноса из UserDefinedMethods.cs)


NinjaTrader 7 использовал класс UserDefinedMethods для определения методов, которые будут
использоваться в нескольких индикаторах или стратегиях NinjaScript. В NinjaTrader 8 эти
предварительно созданные частичные классы были удалены, чтобы уменьшить количество
проблем, которые могут возникнуть в результате совместного использования пользователями
файлов UserDefinedMethods.cs или перезаписи существующих файлов копиями от нового
поставщика. Теперь частичные классы лучше всего создавать вручную и сохранять в папке C: \
Users \ <user> \ Documents \ NinjaTrader 8 \ bin \ Custom \ AddOns.

Предупреждение: если частичный класс сохранен в одной из папок, используемых для


определенных объектов NinjaScript, отличных от надстроек (например, папка индикаторов),
автоматически сгенерированный код NinjaScript может быть добавлен в конец класса
редактором NinjaScript при компиляции, что вызовет ошибку компиляции. Сохранение этих
файлов в папке AddOns гарантирует, что они по-прежнему доступны, и не будет генерировать
код, который может вызвать конфликты.

Вы можете использовать приведенный ниже шаблон в качестве отправной точки для создания
вашего частичного класса. Если вашему частичному классу необходимо наследовать от
родительского класса, вы можете добавить имя желаемого родительского класса после «:»,
чтобы изменить наследование.

Примечание. Методы в ваших частичных классах должны использовать модификатор «public».

namespace NinjaTrader.NinjaScript.Indicators
{
public partial class MyMethods // : parent class to inherit from
{
//Sample method which calculates the delta of two prices
public double calculateDelta(double firstPrice, double secondPrice)
{
return Math.Abs(firstPrice - secondPrice);
}
//Sample method which prints Position information
public void printPositionInfo(Position position)
{
Print(String.Format("{0}: {1} {2} at {3}", position.Instrument, position.Quantity,
position.MarketPosition, position.AveragePrice));
}

}
}

Ниже приведен пример использования одного из методов этого частичного класса в


индикаторе:

protected override void OnBarUpdate()


{
if (CurrentBar < 1) return;

// Use the static calculateDelta method to calculate the difference between the close of each bar
double delta = MyMethods.calculateDelta(Close[0], Close[1]);

Print(delta);
}

Совет: на момент реализации бета-версии редактор NinjaScript НЕ включает мастер генератора


частичных классов, как он есть для основных типов NinjaScript, таких как инструменты
рисования, столбцы анализатора рынка или стратегии. Однако в настоящее время мы
отслеживаем предложение реализовать мастер для частичных классов под ID # SFT-341. Если
вы хотите проголосовать за это усовершенствование, напишите нам по адресу
platformsupport@ninjatrader.com.

Предотвращение избыточной загрузки данных


В NinjaTrader 7 в сценарий можно добавить несколько серий данных, например индикатор, и
затем этот сценарий может быть размещен в другом сценарии, например стратегии. Хотя это
все еще возможно в NinjaTrader 8, существует новая защита для предотвращения избыточной
загрузки данных как в сценарии хостинга, так и в размещенном индикаторе.
При размещении индикатора, который программно добавляет серии данных, сценарий
размещения должен включать те же вызовы метода AddDataSeries (), что и размещенный
сценарий. Без этого произойдет ошибка, которая гласит: «Размещенный индикатор попытался
загрузить дополнительные данные. Все данные должны быть сначала загружены хостом
NinjaScript в его состоянии настройки». Без этого safegaurd можно было бы одновременно
загружать излишне большие объемы данных, как это было бы в случае прямого вызова метода
индикатора для каждого OnBarUpdate (). Добавляя вызовы AddDataSeries () к сценарию
размещения, вы можете гарантировать, что данные загружаются при необходимости. Кроме
того, когда это делается в сценарии размещения, все идентичные вызовы AddDataSeries () в
размещенном сценарии будут игнорироваться, поскольку данные уже доступны.

Примеры ниже показывают это в действии:


Hosted Indicator Loads Additional Data
public class MyCustomIndicator : Indicator
{
protected override void OnStateChange()
{
if (State == State.Configure)
{
AddDataSeries("AAPL", BarsPeriodType.Day, 1);
AddDataSeries("EURUSD", BarsPeriodType.Minute, 15);
}
}
}

Hosting Strategy Mirrors AddDataSeries() calls


public class MyCustomStrategy : Strategy
{
// Define a MyCustomIndicator
MyCustomIndicator myIndicator;

protected override void OnStateChange()


{
if (State == State.Configure)
{
// Instantiate the MyCustomIndicator and add it to the chart
myIndicator = MyCustomIndicator();
AddChartIndicator(myIndicator);

// These calls to AddDataSeries() mirror the calls in the hosted indicator


AddDataSeries("AAPL", BarsPeriodType.Day, 1);
AddDataSeries("EURUSD", BarsPeriodType.Minute, 15);
}
}
}

Бары с 0 объемом
В предыдущих версиях ядро NinjaTrader было разработано для замены тика с объемом 0 на
объем 1. В результате все тики имели значение объема не менее 1. NinjaTrader 8 удалил эту
политику проектирования и теперь разрешает тики с объемом 0 для обработки. Это изменение
политики может потребовать изменения логики любых настраиваемых типов столбцов,
индикаторов или стратегий, которые ранее могли предполагать, что объем всегда будет
больше 0.
Шаблоны по умолчанию для нескольких серий "Торговые часы"
Поведение по умолчанию в NinjaTrader 8 гарантирует, что серия баров, добавленная в скрипт с
помощью AddDataSeries (), будет использовать тот же шаблон «TradingHours», что и основная
серия, настроенная пользователем. Напротив, поведение NinjaTrader 7 сильно зависело от
ряда переменных. Мы обновили это поведение, чтобы помочь с проблемами согласованности и
синхронизации между несколькими сериями; однако, если ваш скрипт использует два
временных интервала с использованием разных шаблонов торговых часов, вы можете
рассмотреть возможность использования одной из новых перегруженных строк tradingHours,
используемых в AddDataSeries ():

protected override void OnStateChange()


{
if (State == State.Configure)
{
// adds a 1 minute AAPL bars with a default 24/7 session tempalte.
AddDataSeries("AAPL", new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 1
}, "Default 24 x 7");
}
}

Разнообразный
Все эталонные образцы NinjaTrader 7, размещенные на нашем форуме поддержки, были
обновлены, чтобы продемонстрировать функциональность NinjaTrader 8. Обязательно
ознакомьтесь с разделом справочного образца, чтобы увидеть другие недокументированные
функции и концепции, которые, возможно, не были рассмотрены в справочном руководстве:

Официальные образцы справочного кода NinjaScript

Есть несколько других изменений в реализации, которые подробно не рассматриваются в этом


обзоре. См. Таблицу изменений кода внизу этой страницы, в которой сравниваются изменения
реализации в обеих версиях.

Подпись

Большое количество методов NinjaTrader, которые были доступны в NinjaTrader 7, в основном


остались прежними и не должны приводить к ошибкам при компиляции. Однако есть несколько
существующих сигнатур методов, которые были обновлены в NinjaTrader 8, чтобы
соответствовать новой структуре, о которой вам необходимо знать, чтобы перенести эти
функции с NinjaTrader 7 на NinjaTrader 8. В большинстве случаев фундаментальные Тип
аргумента был реструктурирован, что может привести к ошибкам компиляции в зависимости от
типа объекта, который используется в сигнатуре методов.
Совет: методы теперь могут иметь дополнительные сигнатуры, которые добавляют функции,
которые ранее не были доступны. Обязательно ознакомьтесь с документацией NinjaTrader 8,
которая охватывает все доступные подписи.

Переименован
В процессе разработки NinjaTrader 8 одна из наших целей - убедиться, что наша основная
структура соответствует различным стандартам кодирования, установленным в отрасли. В
результате соответствия этим стандартам кодирования многие методы и свойства NinjaTrader
пришлось переименовать. Хотя функциональные возможности этих методов и свойств
остались прежними, мы решили переименовать эти переменные, чтобы следовать соглашению
об именах, зависящему от семантического контекста, которое, как правило, согласовано для
удобства чтения. Мы считаем, что переименование этих свойств и методов более подробно
описывает предполагаемую функцию для разработчика, который может проверять код.
Наибольшее количество изменений произошло в ответ на соглашение об именах для bools, где
теперь они следуют более строгой структуре глагол-прилагательное или глагол-
существительное.

Например:

• Свойство FirstTickOfBar могло быть трудным для точного определения того, что оно
представляет, без необходимости искать документацию. В NinjaTrader 8 это свойство было
переименовано в IsFirstTickOfBar, которое теперь дает этому свойству более удобочитаемое
имя идентификатора, когда вы читаете эту строку кода, как «истинен ли первый тик бара?»
• Другим примером является случай BarsSinceEntry (), который был переименован в
BarsSinceEntryExecution (), который теперь указывает, что этот метод ищет выполнение записи.
• В NinjaTrader 7 иногда были методы или свойства, которые имели общие имена, но ссылались
на разные данные или действия. Например, Add () можно было использовать для ссылки на
добавление DataSeries в сценарий, добавление графика или добавление линии. Чтобы быть
более конкретным, NinjaTrader 8 переименовал их в AddDataSeries (), AddPlot () и AddLine ()
соответственно.
• Могут быть случаи, когда имя свойства или метода изменилось просто потому, что изменился
тип данных, с которыми он взаимодействовал. (например, BarColor против BarBrush)
• Бывают и другие случаи, когда свойства могли использовать излишнюю краткость и были
переименованы для удобства чтения (например, AvgPrice vs AveragePrice).
Это всего лишь несколько примеров многих изменений названий, обнаруженных в NinjaTrader
8, и некоторые из рациональных причин количества этих изменений. Для простоты вы найдете
список всех переименованных свойств в таблице внизу этого документа путем фильтрации по
ключевому слову «Renamed».

Таблица взлома кода


Ниже вы найдете справочную таблицу между всеми поддерживаемыми изменениями
NinjaScript между NinjaTrader 7 и NinjaTrader 8.

Стратегия GetAccountValue () Account.Get () Доступ к


реализации значениям
Account был
открыт
напрямую

Переименованная Add () AddChartIndicator () переименова


стратегия н, чтобы
быть более
конкретным.

Реализация General Add () метод Data был


AddDataSeries () переименова
н, чтобы
быть более
конкретным,
получил ряд
улучшений.

Подпись Общее AddKagi () AddKagi () Получено


несколько
изменений
подписи

Переименованный Add () Метод Line AddLine () переименова


индикатор н, чтобы
быть более
конкретным

Подпись Общее AddLineBreak () AddLineBreak () Получено


несколько
изменений
подписи

Переименованный Add () Метод построения переименова


индикатор графика AddPlot () н, чтобы
быть более
конкретным

Подпись Общие AddPointAndFigure () AddPointAndFigure () Получено


несколько
изменений
подписи

Подпись Общие AddRenko () AddRenko () Получено


несколько
изменений
подписи

Подпись General Alert () Alert () Цвет больше


не
используется
, используйте
кисти;
soundLocatio
n теперь
требует
абсолютного
пути к файлу

Чертеж реализации IAndrewsPitchfork AndrewsPitchfork IDrawingObje


cts были
заменены

Реализация Чертеж IArc Arc IDrawingObjects IDrawingObje


заменены cts заменены

Переименованные Настраиваемые линии. Настраиваемое переименова


индикаторные линии. свойство, нные в
соответствии
с
соглашениям
и об именах.

Переименованные Настраиваемые графики ArePlots Настраиваемое переименова


графики индикаторов свойство но в
соответствии
с
соглашениям
и об именах

Реализация Чертеж IArrowDown ArrowDown Заменены


IDrawingObje
cts

Реализация Чертеж IArrowLine ArrowLine IDrawingObje


cts заменены

Реализация Чертеж IArrowUp ArrowUp IDrawingObje


заменены cts

Реализация Общие DataSeries.Set () Оператор заменен


присваивания (=)
Метод .Set ()

Стратегия AtmStrategyCreate () AtmStrategyCreate () Добавлен


реализации параметр
подписи
обратного
вызова

Переименованная AvgBarsInTrade AverageBarsInTrade Свойство


стратегия переименова
но для
удобства
чтения

Продолжение переименований в англо мануале

Рекомендации по NinjaScript

При разработке классов NinjaScript следует помнить о некоторых передовых методах. В


следующих таблицах представлен неполный список соображений, которые следует учитывать
при разработке и реализации кода.
Примечание: NinjaTrader является многопоточным и управляемым событиями. Всегда
предполагайте, что любой из методов, которые вы реализуете в NinjaScript, можно вызвать из
другого потока.
tog_minus Практика государственного управления
Управление ресурсами
Метод OnStateChange () вызывается каждый раз при изменении состояния и может
использоваться для помощи в настройке, управлении и уничтожении нескольких типов
ресурсов. Установка этих значений во многом зависит от типа используемого вами ресурса. В
следующем разделе рассказывается, как управлять различными ресурсами в разных штатах.
Установка значений сетки свойств пользовательского интерфейса по умолчанию
Зарезервируйте State.SetDefaults для установки по умолчанию любых общедоступных свойств,
которые вы хотите отобразить в сетке свойств пользовательского интерфейса. Вы также
должны использовать это состояние для установки по умолчанию желаемого поведения
свойства NinjaScript, которое можно переопределить из сетки свойств (например, Calculate,
IsOverlay и т. Д.). Для графиков и линий, которые вы хотите настроить, AddPlot (), AddLine ()
также должны иметь значения по умолчанию, установленные во время этого состояния.
Зачем? Общедоступные значения объекта NinjaScript в SetDefaults помещаются в сетку свойств
пользовательского интерфейса, чтобы можно было изменить настройки вашего объекта.

Best practice
protected override void OnStateChange()
{
// these are the values that show up as default on the UI
if (State == State.SetDefaults)
{
Calculate = Calculate.OnPriceChange;
IsOverlay = false;

Period = 50;

AddPlot(Brushes.Blue, "Plot Value");


AddLine(Brushes.Gray, 100, "Threshold");
}
}
Для общедоступных свойств, которые вы НЕ хотите отображать в сетке свойств
пользовательского интерфейса, установите для атрибута Browsable значение false:

Best practice
[Browsable(false)] // prevents from showing up on the UI property grid
public int Communicator { get; set; }

Для индикаторов, свойств, которые вы хотите установить из других объектов, установите


атрибут NinjaScript PropertyAttribute:

Best practice
[NinjaScriptProperty] // can now call MyIndicator(20) from another object
public int Period { get; set; }

Поведение по умолчанию - сериализовать любые общедоступные свойства и поля в файл


рабочей области или шаблона при сохранении. Однако не все объекты можно сериализовать -
или вы можете исключить свойство из сохранения и восстановления. Для этих сценариев
установите атрибут XMLIgnore для свойства:

Best practice
[XmlIgnore] // removes from serialization
public Brush DownBrush
{ get; set; }

Также рекомендуется, чтобы ваш NinjaScript не имел каких-либо общедоступных полей,


поскольку они также будут сериализованы, что означает, что их состояние будет сохраняться,
что, в свою очередь, может привести к неожиданным результатам.
Совет: См. Раздел Работа с кистями в Справочном руководстве для получения информации о
правильной сериализации кистей.
Расчет значений объекта времени выполнения
Не пытайтесь выполнять расширенные вычисления или пытаться получить доступ к ссылкам на
объекты в State.SetDefaults. Это состояние должно быть как можно более скудным, и любая
логика вычислений должна быть отложена, по крайней мере, до состояния.
Почему: ваш объект будет вызываться в неожиданных ситуациях. Вы можете узнать больше об
этой теме в разделе «Понимание жизненного цикла ваших объектов NinjaScript».

Practice to avoid
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
// logic could take longer than desired as the list of indicator names is populated
for (int i = 0; i <= array.length; i ++)
DoWork(i);

// possible null reference exception since TickSize is not set yet


Period = 5 * TickSize;
}
}

Best practice
protected override void OnStateChange()
{
// Complex operations should be delayed to >= State.Configure
if (State == State.Configure)
{
for (int i = 0; i < = array.length; i ++)
DoWork(i);
}

// information related to market data is not available until at least State.DataLoaded


else if (State == State.DataLoaded)
{
Period = 5 * TickSize;
}
}

Установка числового уровня класса


Не устанавливайте переменные на уровне класса, если они не являются постоянными. Вам
следует отложить установку или сброс до тех пор, пока состояние не достигнет State.Configure.
Вы можете использовать значения слова const, чтобы отличаться, которые не изменяются, от
переменных, которые изменяются.
Почему: ожидание и определения ресурсов тех пор гарантирует, пока объект не будет
настроен, что значения не будут установлены и объявлены преждевременно.

Best practice
// value is always 5, it can be made constant and declared at the class level
private const int multiplier = 5;

// these values can change, may be better to delay setting until State.Configure
private int counter;
private List<int> myList;

protected override void OnStateChange()


{
if (State == State.Configure)
{
counter = 0;
myList = new List<int>();
}
}
Сброс переменных уровня класса для оптимизации в Strategy Analyzer

Чтобы воспользоваться преимуществами оптимизации производительности, разработчикам


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

Почему: при оптимизации стратегии экземпляры могут или не могут быть переработаны в
зависимости от параметра IsInstantiatedOnEachOptimizationIteration стратегии.

Best practice
// examples of fields which need to be reset
private double myDouble;
private bool myBool;
private DateTime myDateTime;
private Order myOrderObject;
private Brush myBrushObject;
private Array myIntArray;
private List<object> myList;
private SMA mySMAIndicator;
private Series<double> mySeries;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// disabled to take advantage of performance gains
// However any strategy state that would be mutable after State.SetDefaults needed to be reset
for the next run.
IsInstantiatedOnEachOptimizationIteration = false;
}
else if (State == State.Configure)
{
// Since these values are not dependent on bars, they can be reset as early as State.Configure
myDouble = double.MinValue;
myBool = false;
myDateTime = DateTime.MinValue;
myOrderObject = null;
myBrushObject = null;

if (myIntArray != null)
Array.Clear(myIntArray, 0, myIntArray.Length);
else
myIntArray = new int[20];

if (myList != null)
myList.Clear();
else
myList = new List<object>();
}

else if (State == State.DataLoaded)


{
// Since these values do are dependent on bars, they should only reset during
State.DataLoaded
mySMAIndicator = SMA(14);
mySeries = new Series<double>(this);
}
}

Доступ к свойствам, связанным с рыночными данными


Не пытайтесь получить доступ к объектам, связанным с рыночными данными инструмента,
пока состояние не достигнет State.DataLoaded

Зачем: Ожидание доступа к объектам, зависящим от рыночных данных, до тех пор, пока
DataLoaded не предотвратит ошибки доступа во всех сценариях

Best practice
protected override void OnStateChange()
{
if (State == State.DataLoaded)
{
// these objects and their related members are not available until State.DataLoaded
Print(Bars.Count);
Print(Instrument.FullName);
Print(BarsPeriod.BarsPeriodType);
Print(TradingHours.TimeZone);
Print(Input);
}
}

Примечание. Все дополнительные серии данных должны быть добавлены в State.Configure


(включая серии, которые потенциально могут понадобиться любому размещенному сценарию -
дополнительная информация). Поскольку такие объекты, как Instrument, BarsPeriod,
TradingHours и т. Д., НЕ гарантированно доступны до State.DataLoaded, вы не можете надежно
использовать основные свойства инструмента в качестве аргументов в AddDataSeries ().
Попытка динамического добавления серии данных НЕ гарантируется, и поэтому ее следует
избегать. В некоторых случаях вы можете использовать BarsRequest () для получения
рыночных данных для других инструментов и интервалов.

Настройка ресурсов, полагающихся на рыночные данные


Для объектов, зависящих от рыночных данных, отложите их строительство до тех пор, пока
состояние не достигнет State.DataLoaded
Зачем? Ожидание создания объектов, зависящих от рыночных данных, до тех пор, пока
DataLoaded не гарантирует, что их базовые входные данные содержат важные значения во
всех сценариях.

Best practice
// these resources depend on bars, wait until State.DataLoaded to instantiated
private EMA myEMA;
private Series<double> mySeries;
private SessionIterator mySessionIterator;

protected override void OnStateChange()


{
if (State == State.DataLoaded)
{
myEMA = EMA(20);
mySeries = new Series<double>(this);
mySessionIterator = new SessionIterator(Bars);
}
}

Доступ к элементу в пользовательском интерфейсе


Для объектов, которые существуют в пользовательском интерфейсе (например, ChartControl,
ChartPanel, ChartBars, NTWindow и т. Д.), Подождите, пока State не достигнет State.Historical.
Эта практика верна как для свойств чтения, так и для добавления настраиваемых элементов в
существующий пользовательский интерфейс.

Почему: Доступность объектов, связанных с пользовательским интерфейсом NinjaTrader, не


гарантируется, пока не начнется обработка исторических данных.

Best practice
protected override void OnStateChange()
{
// wait until at least State.Historical
if (State == State.Historical)
{
// and double check UI object is not null before accessing
if (ChartControl != null)
{
Print(ChartControl.Properties.ChartBackground);
}
}
}

Перевод ссылок на порядок из истории в режим реального времени


При работе с заказами на основе стратегии, которые перешли из истории в режим реального
времени, вам необходимо убедиться, что ссылки на локально сохраненные заказы также
обновляются.

Зачем? По мере обновления основного объекта ордера у NinjaTrader нет специального способа
обновить ваши локально сохраненные ссылки на ордера. Вы можете узнать больше об этом в
теме Advanced Order Handling: переход от исторических ссылок к текущим.

Best practice
protected override void OnStateChange()
{
// one time only, as we transition from historical to real-time
if (State == State.Realtime)
{
// convert any old historical order object references
// to the new live order submitted to the real-time account
if (myOrder != null)
myOrder = GetRealtimeOrder(myOrder);
}
}

Завершение настраиваемых ресурсов


Используйте флаг, чтобы отслеживать, когда ресурсы были правильно настроены, прежде чем
пытаться их уничтожить.
Зачем: проверка того, что объект настроен, гарантирует, что значения не будут уничтожены
преждевременно. Вы можете узнать больше об этой теме в разделе «Понимание жизненного
цикла ваших объектов NinjaScript».

Best practice
protected override void OnStateChange()
{
if (State == State.Configure)
{
myObject = new object();
// set a flag to indicator object has been configured
configured = true;
}

else if (State == State.Terminated)


{
// only dispose of object if it has been configured
if (configured)
{
myObject.Dispose();
}
}
}

Безопасный доступ к ссылочным объектам


Хотя существуют задокументированные состояния, в которых объекты доступны, реализация
может измениться. Если вы обращаетесь к ссылочному объекту, сделайте это, сначала
проверив, что объект не равен нулю.

Best practice
// checking to ensure chart control is available in all situations
// will help to ensure this logic below does not generate errors at a later time
if(ChartControl != null)
{
myBackgroundBrush = ChartControl.Properties.ChartBackground;
}

Доступ к объектам, которые завершаются


Чтобы защитить себя от состояний гонки и ошибок доступа, вы должны временно проверять
наличие ошибок ссылок каждый раз, когда вы пытаетесь что-то сделать с объектом.
Почему: OnStateChange () выполняется асинхронно с другими событиями NinjaScript. Вы
можете столкнуться со сценариями, в которых логика State.Terminated вызывается в середине
OnBarUpdate (), OnRender () и т. Д.

Best practice
protected override void OnStateChange()
{
// this logic runs asynchronously to other events
if (State == State.Terminated)
{
myObject = null;
}
}
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
if (myObject == null)
return;

// for safety, always check for null references before attempting to access an object
// even if you have once checked for null references earlier run-time
if (myObject != null)
myObject.DoSomething();
}

Инструкции по доказыванию свойств, отличных от ninjascript


Не пытайтесь изменить существующие «Свойства» пользовательского интерфейса в
соответствии с вашими конкретными потребностями. Эти функции доступны для того, чтобы вы
могли читать состояние среды и принимать решения по изменению того, как выполняется ваш
код, но не следует полагаться на изменение настроек от имени пользователя. Хотя эти объекты
из этих классов имеют сеттеры по техническим причинам, вам не следует пытаться изменять
значения с помощью кода. Вместо этого вы должны выдавать предупреждения или
регистрировать ошибки, предлагая пользователям изменить настройки, когда это необходимо:

Почему: NinjaTrader не гарантирует, что запрошенные изменения вступят в силу, а


пользовательские настройки всегда имеют приоритет. Сюда входят определенные
пользователем ChartControl.Properties, ChartBars.Properties и ChartPanel.Properties. Кроме того,
могут быть установлены два разных пользовательских скрипта, которые также пытаются
изменить свойства, на которые вы полагаетесь, что может вызвать конфликты.

Best practice
if (State == State.Historical)
{
if (ChartControl.Properties.EquidistantBarSpacing == true)
{
Draw.TextFixed(this, "error", "This indicator works best with Equidistant BarSpacing set to
false.", TextPosition.BottomRight);
}
}

Изменение элементов пользовательского интерфейса и многопоточность


При взаимодействии с объектами пользовательского интерфейса, например при получении
информации пользовательского интерфейса или изменении существующего макета, всегда
используйте Dispatcher NinjaScript асинхронно.

Критично: неправильная обработка потока из объекта NinjaScript - частая причина


взаимоблокировок приложений. Обязательно прочтите дополнительную информацию о
рассмотрении многопоточности для NinjaScript.

Best practice
// using a Dispatcher will ensure that the corresponding action executes on the associated thread
this.Dispatcher.InvokeAsync(() =>
{
UserControlCollection.Add(new System.Windows.Controls.TextBlock
{
Text = "\nAdded by the ChartControl Dispatcher."
});
});

Правильная реализация блоков try / catch


Если вы специально не отлаживаете метод, использование блока try-catch должно быть
ограничено определенной областью логики. НЕ пытайтесь обрабатывать всю свою логику
выполнения в одном гигантском блоке try-catch.

Почему: блоки try-catch большего размера могут не только усложнять отладку, но и могут
вызывать проблемы с производительностью во время выполнения.

Practice to avoid
protected override void OnBarUpdate()
{
try
{
// encapsulates entire OnBarUpdate logic
}
catch (Exception ex)
{
// attempt to handle all errors in one catch
}
}
Использование кистей WPF
Если возможно, попробуйте использовать заранее заданную статическую кисть. Если вам
нужно настроить новый объект кисти, обязательно .Freeze () кисть перед ее использованием.

Зачем? Предварительно определенные кисти являются потокобезопасными и не требуют


особого обращения. С другой стороны, пользовательские кисти НЕ являются
потокобезопасными и должны быть заморожены, иначе могут возникнуть исключения между
потоками.

Лучшая практика

// предопределенная кисть
BackBrush = Кисти. Синий;

// если вы используете специальную кисть, например, для изменения непрозрачности


SolidColorBrush opaqueBlue = new SolidColorBrush(Colors.Blue) {Opacity = .25f};

// или просто использовать нестандартный цвет, недоступный в предопределенном классе


кистей
coolGreen = new SolidColorBrush(Color.FromRgb(30, 255, 128));

// вы должны заморозить эти кисти после их создания!


opaqueBlue.Freeze ();
coolGreen.Freeze ();

Индексатор barsAgo по сравнению с индексом абсолютного бара


Как вы, наверное, знаете, вы можете быстро найти значение бара на графике, вызвав
индексатор PriceSeries <T> barsAgo, например, Close [0].
Однако внутренний индексатор и указатели на значение barsAgo гарантированно будут
правильно синхронизироваться и обновляться только во время события рыночных данных. В
результате вам следует отдавать предпочтение использованию абсолютных методов
GetValueAt () во время событий, которые не зависят от цены.
Зачем? Попытка вызвать индексатор barsAgo в методе событий, который не зависит от
рыночных данных, может привести к неожиданным результатам.

Best practice
// OnRender is not a market data event; barsAgo pointers are not guaranteed to be in sync
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
Print(mySMA.GetValueAt(CurrentBar));
}

// same is true for you custom events


private void myCustomClickHandler(object sender, MouseButtonEventArgs e)
{
Print(Close.GetValueAt(CurrentBar));
}

Совет: Если у вас есть требования к программированию, основанные на индексаторе


PriceSeries, вы можете использовать делегат TriggerCustomEvent (), который обновит
внутренние указатели и индексы перед выполнением указанной вами логики.
Кастинг безопасно
По возможности избегайте приведения типов и преобразования типов. Приведение из
смешанной коллекции типов также подвержено исключениям, особенно в ситуациях, которые
могут не возникнуть при первоначальном тестировании кода.
Зачем: Практика, позволяющая избежать кода, приведенного ниже, может работать в
некоторых сценариях, но приведет к ошибкам, если в эту коллекцию будут добавлены другие
типы, которых вы не ожидали.

Practice to avoid
// This would run without errors if there were _ONLY_ type HoriztonalLine on the chart
// But you risk a likely 'System.InvalidCastException' when other draw types are in that collection
foreach (HorizontalLine hLine in DrawObjects)
{

Если вы должны выполнить приведение, делайте это осторожно и избегайте неявного


приведения к типам, успешное выполнение которых не может быть гарантировано.

Best practice
// Use the base IDrawingTool type and then cast to the desired type within the for loop
foreach (IDrawingTool hLine in DrawObjects)
{
// Note: to prevent further errors, your type casting should be done using the "as" keyword
// Opposed to a direct cast:
// HorizontalLine myLine = (HorizontalLine) hLine;

HorizontalLine myLine = hLine as HorizontalLine;

// This will allow you to ensure the cast actually occurred


if (myLine != null)
{
Print(myLine.StartAnchor.Price);
}
}
обработка ошибок

Безопасный доступ к ссылочным объектам


Хотя существуют задокументированные состояния, в которых объекты доступны, реализация
может измениться. Если вы обращаетесь к ссылочному объекту, сделайте это, сначала
проверив, что объект не равен нулю.

Best practice
// checking to ensure chart control is available in all situations
// will help to ensure this logic below does not generate errors at a later time
if(ChartControl != null)
{
myBackgroundBrush = ChartControl.Properties.ChartBackground;
}

Доступ к объектам, которые завершаются


Чтобы защитить себя от состояний гонки и ошибок доступа, вы должны временно проверять
наличие ошибок ссылок каждый раз, когда вы пытаетесь что-то сделать с объектом.
Почему: OnStateChange () выполняется асинхронно с другими событиями NinjaScript. Вы
можете столкнуться со сценариями, в которых логика State.Terminated вызывается в середине
OnBarUpdate (), OnRender () и т. Д.

Best practice
protected override void OnStateChange()
{
// this logic runs asynchronously to other events
if (State == State.Terminated)
{
myObject = null;
}
}
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
if (myObject == null)
return;

// for safety, always check for null references before attempting to access an object
// even if you have once checked for null references earlier run-time
if (myObject != null)
myObject.DoSomething();
}
Инструкции по доказыванию свойств, отличных от ninjascript
Не пытайтесь изменить существующие «Свойства» пользовательского интерфейса в
соответствии с вашими конкретными потребностями. Эти функции доступны для того, чтобы вы
могли читать состояние среды и принимать решения по изменению того, как выполняется ваш
код, но не следует полагаться на изменение настроек от имени пользователя. Хотя эти объекты
из этих классов имеют сеттеры по техническим причинам, вам не следует пытаться изменять
значения с помощью кода. Вместо этого вы должны выдавать предупреждения или
регистрировать ошибки, предлагая пользователям изменить настройки, когда это необходимо:
Почему: NinjaTrader не гарантирует, что запрошенные изменения вступят в силу, а
пользовательские настройки всегда имеют приоритет. Сюда входят определенные
пользователем ChartControl.Properties, ChartBars.Properties и ChartPanel.Properties. Кроме того,
могут быть установлены два разных пользовательских скрипта, которые также пытаются
изменить свойства, на которые вы полагаетесь, что может вызвать конфликты.

Best practice
if (State == State.Historical)
{
if (ChartControl.Properties.EquidistantBarSpacing == true)
{
Draw.TextFixed(this, "error", "This indicator works best with Equidistant BarSpacing set to
false.", TextPosition.BottomRight);
}
}

Изменение элементов пользовательского интерфейса и многопоточность


При взаимодействии с объектами пользовательского интерфейса, например при получении
информации пользовательского интерфейса или изменении существующего макета, всегда
используйте Dispatcher NinjaScript асинхронно.

Критично: неправильная обработка потока из объекта NinjaScript - частая причина


взаимоблокировок приложений. Обязательно прочтите дополнительную информацию о
рассмотрении многопоточности для NinjaScript.

Best practice
// using a Dispatcher will ensure that the corresponding action executes on the associated thread
this.Dispatcher.InvokeAsync(() =>
{
UserControlCollection.Add(new System.Windows.Controls.TextBlock
{
Text = "\nAdded by the ChartControl Dispatcher."
});
});
Правильная реализация блоков try / catch
Если вы специально не отлаживаете метод, использование блока try-catch должно быть
ограничено определенной областью логики. НЕ пытайтесь обрабатывать всю свою логику
выполнения в одном гигантском блоке try-catch.
Почему: блоки try-catch большего размера могут не только усложнять отладку, но и могут
вызывать проблемы с производительностью во время выполнения.

Practice to avoid
protected override void OnBarUpdate()
{
try
{
// encapsulates entire OnBarUpdate logic
}
catch (Exception ex)
{
// attempt to handle all errors in one catch
}
}

Использование кистей WPF


Если возможно, попробуйте использовать заранее заданную статическую кисть. Если вам
нужно настроить новый объект кисти, обязательно .Freeze () кисть перед ее использованием.
Зачем? Предварительно определенные кисти являются потокобезопасными и не требуют
особого обращения. С другой стороны, пользовательские кисти НЕ являются
потокобезопасными и должны быть заморожены, иначе могут возникнуть исключения между
потоками.

Best practice
// predefined brush
BackBrush = Brushes.Blue;

// if you are using a custom brush to e.g., modify the opacity


SolidColorBrush opaqueBlue = new SolidColorBrush(Colors.Blue) {Opacity = .25f};

// or just using at custom color not available in pre-defined brushes class


SolidColorBrush coolGreen = new SolidColorBrush(Color.FromRgb(30, 255, 128));

// you must freeze these brushes after they are constructed!


opaqueBlue.Freeze();
coolGreen.Freeze();
Индексатор barsAgo по сравнению с индексом абсолютного бара
Как вы, наверное, знаете, вы можете быстро найти значение бара на графике, вызвав
индексатор PriceSeries <T> barsAgo, например, Close [0].

Однако внутренний индексатор и указатели на значение barsAgo гарантированно будут


правильно синхронизироваться и обновляться только во время события рыночных данных. В
результате вам следует отдавать предпочтение использованию абсолютных методов
GetValueAt () во время событий, которые не зависят от цены.

Зачем? Попытка вызвать индексатор barsAgo в методе событий, который не зависит от


рыночных данных, может привести к неожиданным результатам.

Best practice
// OnRender is not a market data event; barsAgo pointers are not guaranteed to be in sync
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
Print(mySMA.GetValueAt(CurrentBar));
}

// same is true for you custom events


private void myCustomClickHandler(object sender, MouseButtonEventArgs e)
{
Print(Close.GetValueAt(CurrentBar));
}

Совет: Если у вас есть требования к программированию, основанные на индексаторе


PriceSeries, вы можете использовать делегат TriggerCustomEvent (), который обновит
внутренние указатели и индексы перед выполнением указанной вами логики.

Кастинг безопасно
По возможности избегайте приведения типов и преобразования типов. Приведение из
смешанной коллекции типов также подвержено исключениям, особенно в ситуациях, которые
могут не возникнуть при первоначальном тестировании кода.

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


некоторых сценариях, но приведет к ошибкам, если в эту коллекцию будут добавлены другие
типы, которых вы не ожидали.
Practice to avoid
// This would run without errors if there were _ONLY_ type HoriztonalLine on the chart
// But you risk a likely 'System.InvalidCastException' when other draw types are in that collection
foreach (HorizontalLine hLine in DrawObjects)
{

Если вы должны выполнить приведение, делайте это осторожно и избегайте неявного


приведения к типам, успешное выполнение которых не может быть гарантировано.

Best practice
// Use the base IDrawingTool type and then cast to the desired type within the for loop
foreach (IDrawingTool hLine in DrawObjects)
{
// Note: to prevent further errors, your type casting should be done using the "as" keyword
// Opposed to a direct cast:
// HorizontalLine myLine = (HorizontalLine) hLine;

HorizontalLine myLine = hLine as HorizontalLine;

// This will allow you to ensure the cast actually occurred


if (myLine != null)
{
Print(myLine.StartAnchor.Price);
}
}

Ссылки на методы индикатора


Как правило, при вызове метода возврата индикатора существует некоторое внутреннее
кэширование, которое выполняется специально для снижения потребления памяти.

Зачем? Хотя разработанное кэширование индикаторов улучшает общую производительность


памяти, фактический поиск кэшированного индикатора требует дополнительных затрат.

Practice to avoid
// each time you call the SMA() return method there is a small performance cost
// implied from the time it takes to look up the cached instance
if (Close[0] > SMA(20)[0])
{
Print(SMA(20)[0]);
EnterLongLimit(SMA(20)[0]);
Draw.Dot(this, Time[0].ToString(), false, 0, SMA(20)[0], Brushes.DarkGreen);
}

Примечание. Кеширование индикатора происходит ТОЛЬКО, когда индикатор вызывается с


такими же ТОЧНЫМИ параметрами и вводом из ОДНОГО вызывающего скрипта. (т.е. когда
ранее вызванный индикатор вызывается во второй раз с новыми параметрами в том же
скрипте, будет создан / кеширован второй экземпляр)
Если вы повторно используете индикатор несколько раз в своем коде (особенно индикаторы со
многими параметрами), вы можете предпринять дальнейшие шаги для улучшения
производительности, сохранив ссылку на экземпляр индикатора самостоятельно (хотя это ни в
коем случае не является обязательным требованием, и это предложение действительно не
нужно строго соблюдать)

Best practice
private SMA mySma;

protected override void OnStateChange()


{
// when the indicator begins processing
// save an instance of the SMA indicator with the desired input
if (State == State.Historical)
{
mySma = SMA(20);
}
}

protected override void OnBarUpdate()


{
// use the referenced mySMA throughout the lifetime of the script
if (Close[0] > mySma[0])
{
Print(mySma[0]);
EnterLongLimit(mySma[0]);
Draw.Dot(this, Time[0].ToString(), false, 0, mySma[0], Brushes.DarkGreen);
}
}
Пометка ссылок на объекты для сборки мусора
Хотя не всегда необходимо устанавливать для объектов значение null, это приведет к более
ранней пометке их для сборки мусора и поможет предотвратить использование ненужных
ресурсов памяти.

Зачем: В общем, вы должны усердно устанавливать для сохраненных объектов памяти


значение null, когда вы закончили их использовать, особенно в ситуациях, когда объект
NinjaScript может работать в течение длительного периода.

Best practice
protected override void OnBarUpdate()
{
// saving "myDot" creates an additional reference in memory
Dot myDot = Draw.Dot(this, "myDot" + CurrentBar, false, Time[0], Close[0], Brushes.Blue);

if (conditionToRemove)
{
// remove draw object will remove the object from the chart
RemoveDrawObject("myDot");

// but your local object "myDot" is still stored in memory.


// Explicitly setting to null will ensure object is marked for garbage collection
myDot = null;
}
}

Примечание. В приведенном выше примере демонстрируется использование объекта


рисования, но эту практику можно распространить на любой объект, который вы храните в
памяти (например, заказы, кисти, настраиваемые объекты и т. Д.).

Удаление пользовательских ресурсов


Удалите объекты, унаследованные от IDisposable или помещенные в оператор Using.

Почему: NinjaTrader не гарантирует избавление от предметов за вас. Чтобы избежать


ненужного потребления памяти, всегда управляйте своими ресурсами, создавая переменную и
удаляя объект.

Best practice
// example of object instantiated which need to be disposed
StreamWriter writer = new StreamWriter("some_file.txt");

// use the object


writer.WriteLine("Some text");

// implements IDisposbile, make sure to call .Dispose() when finished


writer.Dispose();

// or put in "using" statement which implicitly calls .Dispose() when finished


using (StreamWriter writer2 = new StreamWriter("some_file.txt"))
{
writer2.WriteLine("Some text");
}

Совет: это обычно применимо при использовании ресурсов SharpDX для настраиваемого
рендеринга. Обязательно ознакомьтесь с информацией о лучших методах работы с ресурсами
SharpDX.

Избегайте дублирования вычислений


Помните, где и когда ваши потенциально сложные вычисления будут пересчитаны и, таким
образом, возникнет риск того, что они будут вычислены повторно. Например, у вас может быть
логика, которая должна рассчитывать только один раз на экземпляр, один раз на сеанс, один
раз на бар и т. Д.

Best practice
// get GetPreviousTradingDayEnd() is expensive to look up
// but value only needs to be looked up once a day -> only calcualte on first bar of session
if (Bars.IsFirstBarOfSession)
{
TradingHours.GetPreviousTradingDayEnd(Time[0]);
}

Те же соображения будут применяться к переменным или вызовам функций, которые не


изменят свое выходное значение для текущего обрабатываемого бара на Calculate.OnEachTick
или .OnPriceChange, поэтому нет необходимости обрабатывать их вне IsFirstTickOfBar.

Best practice
// dedicated logic to cache the prior sum on each tick of bar
// While it is a good practice, this can cause problems for bar types which may remove last bar
(see below)
if (IsFirstTickOfBar)
priorSum = sum;

sum = priorSum + Input[0] - (CurrentBar >= Period ? Input[Period] : 0);


Value[0] = sum / (CurrentBar < Period ? CurrentBar + 1 : Period);

Кеширование значений на барах, удаляющих последний столбец


Основываясь на предыдущем примере, будьте осторожны при кэшировании значений на
первом тике бара, если используете типы столбцов, которые являются
IsRemoveLastBarSupported. Чтобы узнать, как лучше всего справиться с этими ситуациями,
взгляните на индикатор SMA по умолчанию, который имеет дополнительную логическую ветвь,
которая отключает кеширование для этих типов полос:

Best practice
// logic below disables first tick of bar caching only on bar types which remove last bar
if (BarsArray[0].BarsType.IsRemoveLastBarSupported)
{
if (CurrentBar == 0)
Value[0] = Input[0];
else
{
double last = Value[1] * Math.Min(CurrentBar, Period);

if (CurrentBar >= Period)


Value[0] = (last + Input[0] - Input[Period]) / Math.Min(CurrentBar, Period);
else
Value[0] = ((last + Input[0]) / (Math.Min(CurrentBar, Period) + 1));
}
}

Предварительное вычисление значений вместо вычисления в OnRender ()


Чтобы сохранить хорошую производительность, всегда проявляйте осторожность, если вы
используете OnRender для какой-либо логики расчета.

Почему: OnRender () вызывается часто, когда вы взаимодействуете с графиком, что может


привести к тому, что вычисления будут происходить намного чаще, чем соответствующие
события рыночных данных, и может вызвать ненужные всплески потребления ЦП.
Practice to avoid
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
// continually recalling the same value methods is unnecessary in this situation
double myValue = Bars.GetClose(CurrentBar) + Bars.GetOpen(CurrentBar);

// render myValue
}

Best practice
private double myValue;

protected override void OnBarUpdate()


{
// myValue only needs to update when OnBarUpdate() is called
// and then can be passed to OnRender() for chart rendering purposes
myValue = Close[0] + Open[0];
}

protected override void OnRender(ChartControl chartControl, ChartScale chartScale)


{
// if needed, you can always check that myValue has actually been set
if (myValue > double.MinValue)
{
// render myValue
}
}

Ограничение вычислений OnRender () видимыми панелями диаграмм


Используйте ChartBars.FromIndex и ChartBars.ToIndex, чтобы ограничить вычисления только
тем, что видно на диаграмме.

Зачем? Рендеринг следует зарезервировать для визуализации того, что видно на диаграмме.
Выполнение расчетов с индексом бара, который не отображается, может вызвать случайные
всплески потребления ЦП.

Best practice
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
// restricting this loop to only the ChartBars.From/ToIndex limits the loop to only what is visible on
the chart
for (int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
{
Print(ChartControl.GetSlotIndexByX(barIndex));
}
}

Использование DrawObjects и пользовательской графики в OnRender ()


При использовании методов Draw создается новый экземпляр объекта Draw, включая его
настраиваемую логику рендеринга и вычислений. Эти методы удобны во многих ситуациях, но
при чрезмерном использовании могут быстро вызвать проблемы с производительностью. В
некоторых ситуациях вы можете увидеть лучшую производительность для рендеринга с
помощью SharpDX в OnRender ().

Почему: каждый экземпляр рисованного объекта будет видеть свой собственный OnRender (),
вызываемый для визуализации значений. Если вместо этого вы реализуете пользовательский
рендеринг в своем объекте, вы увидите только один вызов OnRender () для созданной вами
специально созданной графики.

Practice to avoid
protected override void OnBarUpdate()
{
// this would draw a dot on every bar on the chart
// each instance would need to call its own OnRender() method
// not a very efficient use a draw method
Draw.Dot(this, "everyDot" + CurrentBar, false, 0, Close[0], Brushes.Blue);

С помощью небольшого дополнительного кода (намного меньше, чем в методах Draw)


настраиваемый рендеринг SharpDX значительно снижает потребление ЦП и памяти.

Убедитесь, что фабрика Direct2D1 будет создана только из OnRender () или


OnRenderTargetChanged () (которые выполняются в потоке пользовательского интерфейса),
поскольку доступ из других потоков вне этих методов может вызвать снижение
производительности.

Best practice
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
// achieves the same effect of drawing a dot on every bar
// but only needs to call your object's OnRender()
for (int index = ChartBars.FromIndex; index <= ChartBars.ToIndex; index++)
{
float price = chartScale.GetYByValue(Close.GetValueAt(index));
float bar = chartControl.GetXByBarIndex(ChartBars, index);
float radius = (float) chartControl.BarWidth;

SharpDX.Direct2D1.Ellipse dot = new SharpDX.Direct2D1.Ellipse(new SharpDX.Vector2(bar,


price), radius, radius);

using (SharpDX.Direct2D1.SolidColorBrush brush = new


SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Blue))
{
RenderTarget.FillEllipse(dot, brush);
}
}
}

Совет: Одним из преимуществ использования Draw.Method является то, что возвращаемые


объекты Draw содержат метаданные, которые могут быть использованы позже (например, для
получения индекса столбца или значения цены точки позже). Если вы будете использовать эти
метаданные позже, использование метода Draw будет в ваших интересах. Однако, если вы
хотите только отображать цифры на диаграмме, предпочтение пользовательским методам
SharpDX может значительно повысить производительность.

Реагирование на пользовательские события


НЕ используйте OnRender () для других целей, кроме рендеринга. Если вам нужны события для
взаимодействия с пользователем, подумайте о добавлении собственного обработчика
событий. В приведенном ниже примере показана регистрация события ChartPanel MouseDown и
регистрация настраиваемого элемента управления WPF.

Почему: OnRender () может вызывать более или менее часто, чем вы ожидали. Использование
ваших собственных обработчиков событий позволяет вам контролировать и изолировать логику
пользовательских событий, которую вы хотите зафиксировать.

Best practice
protected override void OnStateChange()
{
if (State == State.Historical)
{
// subscribe to chart panel mouse down event
if (ChartPanel != null) ChartPanel.MouseDown += DoUserClickedChartPanelEvent;

// subscribe to a custom UI element mouse down event


if (myWPFControl != null) myWPFControl.MouseDown += DoCustomWPFControlClickEvent;
}

else if (State == State.Terminated)


{
// remember to unsubscribe when finished
if (ChartPanel != null) ChartPanel.MouseDown -= DoUserClickedChartPanelEvent;
if (myWPFControl != null) myWPFControl.MouseDown -= DoCustomWPFControlClickEvent;
}
}

private void DoUserClickedChartPanelEvent(object sender, MouseButtonEventArgs e)


{
Print("User clicked on the ChartPanel, executing custom mouse down logic...");
}

private void DoCustomWPFControlClickEvent(object sender, MouseButtonEventArgs e)


{
Print("User clicked on my button, executing button logic...");
}

Логика задержки на определенный временной интервал


НЕ вызывайте Thread.Sleep (), поскольку он заблокирует поток инструмента, выполняющий ваш
объект NinjaScript.

Зачем? События рыночных данных, представленные NinjaScript, выполняются в базовом пуле


потоков инструментов, совместно используемом всеми инструментами. Засыпание
нижележащего потока вашего объекта приведет к засыпанию всего потока инструмента, что
отрицательно повлияет на другие функции, использующие тот же инструмент.

Practice to avoid
protected override void OnBarUpdate()
{
if (IsFirstTickOfBar && State == State.Realtime)
{
Print("Run some logic before:: " + DateTime.Now);
Thread.Sleep(5000); // sleeping the Instrument thread will have adverse effects on elements
outside of your script!
Print("Run some logic after: " + DateTime.Now);
}
}

Вместо этого попробуйте использовать объект Timer, если вам нужно отложить выполнение
логики.

Best practice
protected override void OnBarUpdate()
{
if (IsFirstTickOfBar && State == State.Realtime)
{
// Instead of Thread.Sleep for, create a timer that runs at the desired interval
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer {Interval = 5000};

// queue the "after" logic to run when the timer elapses


timer.Tick += delegate
{
timer.Stop(); // make sure to stop the timer to only fire ones (if desired)
Print("Run some logic after: " + DateTime.Now);
timer.Dispose(); // make sure to dispose of the timer
};

Print("Run some logic before: " + DateTime.Now);

timer.Start(); // start the timer immediately following the "before" logic


}
}

Сравнение с плавающей точкой


Помните о проблемах точности с плавающей запятой. Иногда может быть более надежным
проверить с определенной степенью допуска, например TickSize.
Почему: вы можете узнать больше об арифметике с плавающей запятой в применении к
NinjaTrader на нашем форуме поддержки.

Practice to avoid
// depending on how Value[0] was calculated, it could be off by a degree of floating points
// where this logic below would never be true
// e.g., 2050.2499999 vs 2050.50
if (Value[0] == Close[0])
{
// do something
}

Best practice
// you can avoid these precision issues by rewriting the comparison to evaluate within a certain
tolerance.
if (Math.Abs(Value[0] - Close[0]) < TickSize)
{
// do something
}

// You will also see NinjaTrader developed objects use a custom Extension Method
// double.ApproxCompare() which Returns an int based on a Epsilon value:
if (Close[0].ApproxCompare(Value[0]) == 0)
{
// do something
}

Создание определяемых пользователем типов параметров / перечислений


При создании перечислений для объектов NinjaScript настоятельно рекомендуется определять
их вне класса и в настраиваемом пространстве имен. Эталонный образец, содержащий все
подробности, можно найти здесь.

Эффективная отладка
Чрезвычайно широкое использование методов Log () и Print () может снизить
производительность вашего ПК, поскольку для обработки каждого из этих вызовов методов
требуется память и время. При запуске пользовательского NinjaScript, особенно при
использовании Calculate = Calculate.OnEachTick, помните, как часто обрабатываются методы
Log () и Print (), поскольку они могут быстро потреблять ресурсы ПК.
• Метод Log () не следует использовать, за исключением критических сообщений, поскольку
каждая запись журнала попадает в журнал Центра управления, который остается активным до
конца дня. Чрезмерное ведение журнала может привести к тому, что огромное количество
памяти будет выделено только для отображения всех сообщений журнала, что означает
меньше памяти для NinjaTrader для выполнения других задач.

• Метод Print () можно использовать более широко, чем метод Log (), но он все же может
снизить производительность, если используется с очень высокой частотой. Рассмотрите
возможность уменьшения печати из вашего скрипта, если вы испытываете замедление при
запуске скрипта.

Режим отладки
Режим отладки следует использовать только в том случае, если вы активно отлаживаете
сценарий и подключены к отладчику.

Зачем? В режиме отладки все файлы в пользовательском проекте будут компилироваться как
«отладочная» сборка, в которой отсутствуют некоторые оптимизации, которые происходят в
процессе компиляции C #. Более эффективно использовать ваши настраиваемые объекты в
сборке «Release» по умолчанию, если вы используете свои сценарии во время производства.

Чтобы отключить режим отладки:

• Щелкните правой кнопкой мыши в любом редакторе NinjaScript.

• Убедитесь, что в пункте меню «Режим отладки» не установлен флажок.

• Нажмите F5, чтобы перекомпилировать ваши скрипты.

• Ваши скрипты будут перекомпонованы в режиме «Release».

Известные ограничения NinjaScript Wrappers

• Редактор NinjaScript обнаруживает изменения кода во внешних редакторах и будет


компилировать изменения кода, однако код будет автоматически сгенерирован редактором
NinjaScript, только если он редактируется в самом редакторе NinjaScript (или Visual Studio).

• Оболочки не могут быть сгенерированы автоматически для частичных и абстрактных классов.

• Код в области свойств объекта NinjaScript не может быть закомментирован с помощью


комментария стиля / * * /, так как это вызовет проблемы с генерацией оболочки. Код должен
быть закомментирован в стиле //.

• Создание подклассов не позволяет создавать оболочки


Рекомендации для скомпилированных сборок
Использование скомпилированных сборок
Скомпилированные сборки (DLL) позволяют объединять ваши скрипты в формат, который
скрывает ваш частный код вместе с любыми вспомогательными ресурсами. Скомпилированные
сборки обеспечивают явные преимущества, особенно для коммерчески распространяемого
кода, но следует помнить о нескольких моментах. К приведению типов и встраиванию файлов
ресурсов (звуков, изображений и т. Д.) В ваши сборки нужно подходить по-разному, чтобы
гарантировать чистую упаковку DLL без ошибок.

Использование настраиваемых свойств перечисления


При создании настраиваемых свойств перечисления рекомендуется создавать перечисление
вне вашего класса NinjaScript и назначать его в собственном полностью определенном
пространстве имен. Пример см. Здесь. При использовании перечисления в коде используйте
полностью определенное пространство имен вместо использования директивы using для
сокращения выражения.

Типы приведения в DLL (использование динамических типов)


Иногда вам может потребоваться преобразовать свои объекты в типы NinjaScript, например,
при итерации по коллекции DrawObjects для получения ссылки на конкретный объект
рисования на диаграмме. При запуске кода C #, который не был скомпилирован в сборку,
приведение типов можно выполнить обычным образом, как в примере ниже:

ypecasting in code outside of a compiled assembly


protected override void OnBarUpdate()
{
foreach(HorizontalLine line in DrawObjects)
{
// Print the tag of each Horizontal Line on the chart
Print(String.Format("Horizontal Line {0} found.", line.Tag));
}
}

При традиционном приведении типов в скомпилированной сборке возникает препятствие,


поскольку тип NinjaScript, который вы пытаетесь преобразовать, будет присутствовать как в
вашей DLL, так и в сборке Custom.dll NinjaTrader. Если вы планируете скомпилировать свой код
в DLL, вам нужно будет использовать динамический тип, чтобы избежать этого конфликта,
динамически назначая тип во время выполнения, используя следующие рекомендации:

1.Просмотрите свою коллекцию, используя тип интерфейса


2. С помощью ToString () проверьте полное пространство имен объекта в цикле.

3. преобразовать объект в динамический и ссылаться на свойства этого объекта, предполагая,


что это ожидаемый тип.

Dynamic variables as an alternative to typecasting inside of a compiled assembly


foreach (IDrawingTool line in DrawObjects.ToList())
{
// Use ToString().Equals() to detect the object's Type
if (line.ToString().Equals("NinjaTrader.NinjaScript.DrawingTools.HorizontalLine"))
{
// Cast line as dynamic and access the object by assuming that it is the Type we expect
Print(String.Format("Horizontal Line {0} detected!", (line as dynamic).Tag));
}
}

The above dynamic approach will work for primitive types. For instantiating more complex
types / classes though, such as adding a new PriceLevel programmatically to an existing
drawing tool, Reflection would need to used.

Instantiating more complex types such as the PriceLevels class inside of a compiled
assembly
foreach (dynamic dt in DrawObjects.ToList())
{
if(dt.ToString().Equals("NinjaTrader.NinjaScript.DrawingTools.FibonacciRetracements"))
{
Type type = dt.PriceLevels.GetType().GetGenericArguments()[0];
Assembly assembly = type.Assembly;
var pl = assembly.CreateInstance(type.FullName, false, BindingFlags.CreateInstance, null,
new object[] { 55.5, Brushes.Red, 2 }, new System.Globalization.CultureInfo("en-US"), new
object[] {});
dt.PriceLevels.GetType().GetMethod("Add").Invoke(dt.PriceLevels, new object[] { pl } );
this.ForceRefresh();
}
}

Работа с динамическим типом


Использование динамических переменных в описанной выше технике требует особого
внимания к надлежащему доступу к членам, и поэтому его следует избегать, если вы
не собираетесь использовать или распространять скомпилированные сборки.
• Нет Intelliprompt: поскольку компилятор не может знать, какой тип вы предполагаете
для динамической переменной, Intelliprompt не будет отображаться, чтобы облегчить
поиск по членам типа. То же самое относится к Visual Studio Intellisense или
аналогичным утилитам.

• Нет ошибок компиляции: по той же причине компилятор не может знать, используете


ли вы переменную способом, не поддерживаемым ее ожидаемым типом, пытаетесь ли
вы получить доступ к элементам, отсутствующим в этом типе, или другими
связанными ошибками. Таким образом, любые такие ошибки, которые могут быть
обнаружены компилятором при приведении типов, будут пропущены и вместо этого
приведут к ошибкам времени выполнения. Если должна была быть вызвана ошибка
времени выполнения, ее будет труднее интерпретировать.

o Пример: если вы попытаетесь получить доступ к "line.tag" (неправильное


использование заглавных букв) в приведенных выше примерах, вы получите
следующие ошибки:

▪Ошибка приведения типов / компиляции:


«NinjaTrader.NinjaScript.DrawingTools.HorizontalLine» не содержит определения для
«тега», и не может быть найден метод расширения, принимающий первый аргумент
типа «NinjaTrader.NinjaScript.DrawingTools.HorizontalLine» (а вы? отсутствует директива
using или ссылка на сборку?) "

▪dynamic / Ошибка выполнения: «Ошибка при вызове метода OnBarUpdate на баре 0:«
NinjaTrader.NinjaScript.DrawingTools.DrawingTool.tag »недоступен из-за уровня защиты»

Добавление XAML и других файлов в DLL


При экспорте скомпилированной сборки через NinjaTrader нельзя добавлять
дополнительные файлы ресурсов. Есть два способа обойти это. Первый -
экспортировать DLL из NinjaTrader, затем открыть экспортированный файл .zip,
добавить любые дополнительные файлы и повторно заархивировать архив, но это
приведет к тому, что ваши файлы ресурсов будут полностью доступны для конечных
пользователей. Второй и рекомендуемый подход - использовать
полнофункциональную среду IDE, такую как Visual Studio, для создания ваших DLL.

Дополнительные сведения о том, как сделать это с помощью Visual Studio, см. В
разделе «Среда разработки надстроек» на странице «Обзор разработки надстроек».
Хотя страница посвящена разработке надстроек, предоставленный на ней пример
проекта можно использовать также для разработки других типов NinjaScript.
Экспорт пользовательских инструментов рисования как сборок / DLL
Планируя распространять свои собственные инструменты рисования через сборки,
пожалуйста, поймите, что первостепенное значение имеет реализация собственного
Draw. , чтобы разрешить программному вызову инструмента рисования другими
объектами NinjaScript.

Инструменты рисования по умолчанию NinjaTrader будут реализовывать это через


частичный класс, например, вы увидите -

Default NinjaTrader drawing tool Draw. method handling


public static partial class Draw
{

}
Однако, поскольку частичные классы не могут охватывать две сборки, поэтому
настраиваемый не частичный Draw. для вашего инструмента рисования NinjaScript.

Custom drawing tool Draw. method handling


public static class MyDrawCustom
{

}
Экспорт может быть несовместимым с предыдущими версиями.
Экспорт NinjaScript может быть несовместим с предыдущими версиями NinjaTrader.

Известно, что это происходит каждый раз, когда вводится новый тип (например, Enum),
поскольку новые введенные типы не известны предыдущим выпускам NinjaTrader.

Обычно появляется следующее сообщение об ошибке:

«Ошибка при вызове метода SetState: не удалось загрузить тип


NinjaTrader.NinjaScript.Indicators.CumulativeDeltaType из сборки NinjaTrader.Vendor,
Version = 8.0.12.0, Culture = нейтральный, PublicKeyToken = null».
Импортировать

Предыдущая страница Вернуться к обзору главы Следующая страница


Вам следует импортировать только файлы архива NinjaScript (.zip), которые вы
получили из надежного источника.

Импортировать:

1. В окне Центра управления выберите меню Инструменты> Импорт> NinjaScript ...,


чтобы открыть диалоговое окно «Импорт».

2. Выберите файл, который хотите импортировать.

3. Нажмите кнопку «Импорт».

Экспорт

Предыдущая страница Вернуться к обзору главы Следующая страница


Вы можете экспортировать NinjaScript для импорта в нескольких форматах:

• Исходные файлы - исходные файлы NinjaScript, которые могут быть импортированы


и отредактированы другими.

• Сборки - скомпилированная сборка (DLL) NinjaScript, которая «скрывает» ваш


исходный код. Это может быть дополнительно защищено SecureTeam Agile.NET для
предотвращения кражи вашей интеллектуальной собственности.

Вы можете предоставить другим пользователям NinjaTrader исходные файлы вашего


NinjaScript в формате, в котором они смогут их просматривать и редактировать.

Экспорт NinjaScript как исходных файлов

1. В окне Центра управления выберите меню Инструменты> Экспорт> NinjaScript ...,


чтобы открыть диалоговое окно «Экспорт NinjaScript».

2. Нажимаем «добавить»
3. Используйте раскрывающийся список «Тип», чтобы отфильтровать доступные типы
NinjaScript.

4. Выберите все файлы, которые хотите экспортировать, и нажмите кнопку «ОК».

5. Будет показан список всех файлов, которые будут экспортированы.

6. Нажмите кнопку «Экспорт», чтобы экспортировать выбранные файлы.

7. Откроется диалоговое окно с файлом, в котором вы можете выбрать место, в


котором будет создан файл для экспорта zip-архива. По умолчанию файл архива
NinjaScript (.zip) будет создан в папке «Мои документы \ <NinjaTrader Folder> \ bin \
Custom \ ExportNinjaScript». .

8.Файл может быть импортирован другим приложением NinjaTrader на другом ПК.

Примечание. Архивный файл NinjaScript (.zip), созданный с помощью этого процесса,


совместим как с 32-битными, так и с 64-битными версиями NinjaTrader.
Экспорт ninjascript как сборки

Вы можете предоставить другим пользователям NinjaTrader доступ к вашим собственным


индикаторам или стратегиям в безопасном формате, чтобы они не могли видеть ваш
собственный исходный код. Вы можете сделать это, экспортировав индикаторы NinjaScript в
виде скомпилированного файла сборки Microsoft .NET (DLL).

• Это отличный вариант распространения, если ваши проприетарные файлы индикаторов или
стратегий не ссылаются на внешние библиотеки DLL.

• Если ваш собственный индикатор или стратегия ссылается на внешние библиотеки DLL,
рекомендуется создать свой собственный установщик.

1. В окне Центра управления выберите меню Инструменты> Экспорт> NinjaScript ..., чтобы
открыть диалоговое окно «Экспорт NinjaScript».

2. Выберите вариант «Экспортировать как скомпилированную сборку».

3. При желании вы можете выбрать «Защитить скомпилированную сборку» (информацию о


защите см. На странице «Защита / Безопасность DLL).

4. Нажимаем «добавить»

5. Используйте раскрывающийся список «Тип», чтобы отфильтровать доступные типы


NinjaScript.

6. Выберите все файлы, которые хотите экспортировать, и нажмите кнопку «ОК».

7. Будет показан список всех файлов, которые будут экспортированы.


8. При желании введите информацию, описывающую сборку, в поля «Продукт» и «Версия».

9. Нажмите кнопку «Экспорт», чтобы экспортировать выбранные файлы.

10. Откроется диалоговое окно с файлом, в котором вы можете выбрать место, в котором будет
создан файл для экспорта zip-архива. По умолчанию файл архива NinjaScript (.zip) будет
создан в папке «Мои документы \ <NinjaTrader Folder> \ bin \ Custom \ ExportNinjaScript». .

11.Файл может быть импортирован другим приложением NinjaTrader на другом ПК.

Примечание. При экспорте защищенной сборки сгенерированный файл .zip совместим как с 32-
битной, так и с 64-битной версиями NinjaTrader.

Удалить сборку NinjaScript

Это позволит вам удалить установленные файлы сборки NinjaScript.

Чтобы удалить сборку NinjaScript:

1. В окне Центра управления выберите меню Инструменты> Удалить сборку NinjaScript.

2. Выберите файл (ы), который вы хотите удалить (MultiSelect можно будет использовать,
удерживая нажатой клавишу Shift при выборе файлов для удаления).

3. Нажмите кнопку «Удалить сборку NinjaScript».


Примечание. Удаление сборки NinjaScript не выгружает существующие сборки до перезапуска,
это означает, что вам не следует импортировать те же сборки снова, пока вы не перезапустите
NinjaTrader.

Проблемы с экспортом
Если у вас возникают трудности с экспортом NinjaScript, это может быть связано с одной из
следующих причин:

Если вы получите указанную выше ошибку, вам нужно будет скомпилировать ваш NinjaScript
без ошибок, прежде чем вы сможете экспортировать. Чтобы проверить, не содержит ли ваш
файл NinjaScript ошибок, откройте редактор NinjaScript («Инструмент»> «Редактировать
NinjaScript») и нажмите F5 для компиляции. Если вы пытаетесь проверить стратегию
NinjaScript, созданную с помощью мастера стратегии, вы можете сделать то же самое,
завершив работу мастера и посмотрев, получите ли вы сообщение «Стратегия успешно
сгенерирована».

Если вы получите какие-либо ошибки при компиляции, вам необходимо устранить их перед
экспортом.

Если вы можете скомпилировать без ошибок и по-прежнему испытываете трудности с


экспортом, подобные описанной выше, проверьте, не появляется ли в журналах Центра
управления сообщение об ошибке, подобное этой:

"3/6/2014 9:25:30 AM | 2 | 4 | Ошибка компиляции экспортной сборки: C: \ Users \ NinjaTrader \


Documents \ NinjaTrader 8 \ bin \ Custom \ Indicator \ MyCustomIndicator.cs (42,18): ошибка
CS0118: NinjaTrader.Indicator.SMA - это тип, но используется как переменная "
Примечание. Эта ошибка может иметь другой код ошибки и сообщение в зависимости от того,
какой вариант .NET вы установили. Сообщение об ошибке, указывающее на эту проблему,
будет включать имя индикатора без кавычек.

Если вы столкнулись с этой ошибкой, выполните следующую процедуру:

1. Обратите внимание на индикатор, на который указывает ошибка. В приведенном выше


примере это SMA

2. Перейдите в утилиту экспорта NinjaScript. (Инструменты> Экспорт> NinjaScript ...)

3. После нажатия «добавить» выберите «Системные индикаторы» в раскрывающемся списке


«Тип».

4. Добавьте индикатор, на который есть ссылка в ошибке, в список экспорта вместе с вашим
собственным кодом NinjaScript, нажав кнопку>.
5. Нажмите кнопку «Экспорт», чтобы создать файл архива NinjaScript. Если вы снова получите
ту же ошибку, повторяйте эту процедуру, пока вы не добавите все указанные системные
индикаторы и не сможете успешно экспортировать свой собственный NinjaScript.

Примечание. Если индикатор, упомянутый в ошибке, является другим пользовательским


индикатором, вам нужно будет выполнить ту же процедуру, чтобы добавить пользовательский
индикатор.

Защита / Безопасность DLL

Хотя файлы .NET DLL скомпилированы, что не позволяет пользователям видеть ваш частный
исходный код, они по-прежнему подвергаются попыткам декомпиляции и обратного
проектирования. Если вам нужен более высокий уровень безопасности, вы можете выбрать
опцию «Защитить скомпилированные сборки», которая добавляет дополнительный уровень
защиты. Этот дополнительный уровень защиты обеспечивается продуктом SecureTeam
Agile.NET, который был лицензирован NinjaTrader и доступен по сниженной цене для защиты
сборок NinjaTrader. Этот продукт заявляет, что полностью останавливает разборку и
декомпиляцию MSIL. Мы сами им пользуемся и очень им довольны.
Если вы хотите использовать Agile.NET для защиты ваших сборок NinjaScript, вам сначала
нужно перейти сюда, чтобы загрузить и приобрести продукт. После установки запустите
автономный продукт Agile.NET один раз, чтобы ввести лицензионную информацию, которую вы
должны были получить при его загрузке. После этого, когда вы используете утилиту NinjaTrader
Export NinjaScript и выбираете опцию «Защитить скомпилированные сборки» для экспорта, она
автоматически защищает вашу сборку NinjaScript с помощью Agile.NET.

Обратите внимание, что эта версия Agile.NET будет работать только для защиты сборок
NinjaScript в NinjaTrader. Если вы хотите защитить другие файлы вне NinjaTrader, рассмотрите
возможность приобретения полной версии Agile.NET у SecureTeam прямо здесь «Защита кода
Agile.NET 6.0». Сборки NinjaScript, защищенные полной версией Agile.NET, также будут
работать в NinjaTrader.

Лицензирование / аутентификация пользователя

NinjaTrader предоставляет бесплатную службу управления лицензиями поставщиков для


аутентификации пользователей для квалифицированных сторонних разработчиков.

Услуга включает в себя следующие функции:

• Один вызов метода в вашем индикаторе NinjaScript или конструкторе стратегии включит
процесс аутентификации.

• Надстройка NinjaScript, предназначенная для управления лицензиями (управление лицензией,


бесплатные пробные версии)
• Лицензии привязаны исключительно к комбинации определяемого пользователем префикса +
значение идентификатора компьютера, что гарантирует невозможность совместного
использования лицензий.

• Управляйте всеми своими отдельными продуктами или группируйте продукты вместе для
лицензирования.

• Срок действия лицензий истекает в зависимости от времени / даты.

• Создавайте бесплатные пробные периоды

За дополнительной информацией обращайтесь по адресу sales@ninjatrader.com или к вашему


представителю по развитию бизнеса NinjaTrader. После утверждения вы получите уникальный
идентификатор поставщика, используемый для управления вашими пользовательскими
лицензиями, Справочное руководство по лицензированию поставщика, содержащее
информацию, образцы и ресурсы, которые помогут вам в процессе управления
лицензированием.

Лучшие практики распространения

Ниже приведены рекомендации по распространению.

Не развертывайте исходные файлы NinjaScript


Если вы являетесь коммерческим поставщиком, вам никогда не следует распространять файлы
исходного кода NinjaScript .cs, даже если ваш IP-адрес содержится в сборке или проприетарной
DLL. Файлы с исходным кодом доступны для редактирования пользователями и могут вызвать
ненужные проблемы со службой поддержки.

Соглашения об именах
Пожалуйста, используйте согласованное соглашение об именах для ваших индикаторов и
стратегий. Предлагаем добавить префикс к названию индикатора. Если название вашей
компании - «Hyper», вы можете назвать свои индикаторы, например, «HyperTrend» или
«HyperOscillator».

В случае, если вы предоставите архивы экспорта NinjaScript (zip-файлы) в качестве средства


распространения, NinjaTrader автоматически заблокирует импорт несовместимых скриптов,
поэтому у пользователя не будет путаницы относительно того, устанавливают ли они скрипты
Версии 7 или 8 на свой NinjaTrader. монтаж. Рекомендуется включать номер версии NinjaTrader
в экспортный архив, что снизит потенциальную нагрузку на поддержку. Например, вы можете
назвать свои индикаторы «MyIndicator_7.zip» и «MyIndicator_8.zip».
Очистите свои ресурсы
Всегда освобождайте ресурсы, такие как внешние библиотеки DLL Windows или ресурсы,
связанные с управлением лицензиями. Ресурсы должны быть освобождены в методе
OnStateChange () в State.Terminate. NinjaTrader вызывает этот метод в момент, когда скрипт
больше не используется.

Триггер аутентификации пользователя


Если вы используете проприетарный процесс аутентификации пользователя, убедитесь, что он
запускается в методе OnStateChange () в State.SetDefaults. Это гарантирует, что пользователи
не будут вынуждены терпеть ненужные задержки при запуске NinjaTrader или диалоговых
окнах, которые отображают доступные индикаторы и стратегии по мере загрузки окон.
NinjaTrader, LLC предоставляет бесплатные услуги лицензирования для квалифицированных
сторонних разработчиков. Для получения дополнительной информации об этой бесплатной
услуге свяжитесь с вашим представителем по развитию бизнеса NinjaTrader.

Состояние проверки аутентификации пользователя


Проверка лицензии должна выполняться только один раз и поддерживать ее состояние
проверки.

Истекло время аутентификации пользователя


Проверка лицензии должна иметь тайм-аут в случае проблем с Интернетом, чтобы повысить
производительность в этом случае.

Пользовательский установщик
Если вы предоставляете собственный установщик, он не должен перезаписывать какие-либо
файлы, развернутые NinjaTrader, и вы должны предоставить возможность удаления, которая
удаляет все установленные файлы.

Также желательно, чтобы вы предоставили один установщик, который предоставляет


пользователю возможность установить версию вашего продукта (ов), совместимую с версией 7
или 8. Убедитесь, что вы копируете только правильные файлы в правильные установочные
папки NinjaTrader, поскольку, если вы этого не сделаете, это может вызвать проблемы с
компиляцией для клиента, и всем участникам будет чрезвычайно сложно изолировать причину.

Это следующие имена папок:

• Документы \ NinjaTrader 7 \ bin \ Custom


• Документы \ NinjaTrader 8 \ bin \ Custom

Тест на устаревших операционных системах


Некоторые клиенты NinjaTrader работают в более старых операционных системах (например,
Windows 7), и вам следует убедиться, что ваши индикаторы, пользовательские установщики и
внешние библиотеки DLL (если таковые используются) должным образом работают в этих
устаревших операционных системах.

Выставить состояния индикатора


Если ваш собственный индикатор работает как состояние тренда (зеленые полосы - бычий,
красный - медвежий), рекомендуется раскрыть состояние индикаторов, чтобы потребители
ваших индикаторов могли использовать их в своем собственном индикаторе или стратегии.

Порядок распространения
NinjaTrader упрощает распространение полных пакетов для ваших клиентов. Вы можете не
только распространять свои индикаторы и стратегии, но также можете легко развертывать свои
собственные пользовательские сборки, собственные библиотеки DLL, шаблоны диаграмм и
шаблоны Market Analyzer для своих клиентов.

Создание дистрибутива

Добавление пользовательских сборок или собственных библиотек DLL

Чтобы создать пакет распространения, выполните шаги, показанные здесь, для создания
файла экспорта, содержащего ваши индикаторы NinjaScript и / или стратегии.

Настоятельно рекомендуется экспортировать сценарии как сборку и использовать Agile.NET от


SecureTeam. Только этот процесс обеспечит вам максимально возможный уровень
безопасности для защиты вашей интеллектуальной собственности. Дополнительные сведения
об использовании Agile.NET от SecureTeam см. В разделе «Защита / Безопасность DLL».

После завершения использования утилиты экспорта вы найдете дистрибутив в виде файла .zip
в папке «Мои документы \ NinjaTrader 8 \ bin \ Custom \ ExportNinjaScript». Если вы хотите только
распространять свои файлы NinjaScript, то предоставив своим клиентам этот .zip и заставив их
пройти через процесс импорта, он будет установлен на их машинах. Если вы хотите добавить
дополнительные файлы в свой дистрибутив, см. Разделы ниже.
Критично: важно сообщить вашим клиентам, что индикаторы и стратегии NinjaTrader 8 НЕ
обязательно совместимы с NinjaTrader версии 7.

1. Найдите базовый дистрибутив .zip.

2. Откройте .zip.

3. Добавьте в файл .zip свои сборки и / или файлы DLL в корневой каталог .zip. Эти файлы не
могут находиться за какими-либо дополнительными структурами каталогов и должны
находиться непосредственно в корне архива .zip.

Для пользовательских сборок вам также потребуется добавить в корень архива .zip файл .txt с
именем AdditionalReferences.txt.

1. вызовите меню Пуск Windows.

2. Перейдите в поле «Выполнить», введите «блокнот» без кавычек и нажмите Enter.

3. В Блокноте введите имя вашей пользовательской сборки, а затем сохраните файл как
текстовый файл с именем «AdditionalReferences».

Пример: Если имя вашей пользовательской сборки было MyCustomAssembly.dll и


MyCustomAssembly.cs, в файле AdditionalReferences.txt вы должны ввести
«MyCustomAssembly» без кавычек.

Примечание. Если у вас есть несколько пользовательских сборок для добавления, вы можете
добавить каждое из имен сборок в один и тот же файл AdditionalReferences.txt на новых
строках.

Добавление шаблонов

Если вы распространяете пакет индикаторов, вы также можете захотеть распространить


предварительно созданный шаблон диаграммы, который ваши клиенты могут использовать для
быстрого вызова предпочтительных настроек для настройки вашей диаграммы. Те же
инструкции здесь будут работать и для всех других шаблонов, то есть MarketAnalyzer,
DrawingTools - при условии, что соответствующая папка в шаблонах правильно настроена для
категории шаблонов, с которой вы работаете. Следующие ниже шаги проходят через процесс
для шаблонов диаграмм.

1. Найдите базовый дистрибутив .zip.

2. Откройте .zip.

3. Создайте новый каталог под названием "шаблоны" без кавычек.


4. Перейдите в каталог «шаблоны» и создайте еще один новый каталог под названием
«Диаграмма».

5. Перейдите в каталог «Диаграмма». Скопируйте шаблоны диаграмм .xml, которые вы хотите


распространить, из My Documents \ NinjaTrader 8 \ templates \ Chart в этот каталог в .zip.

Добавление рабочих пространств

Если вы распространяете пакет индикаторов, вы также можете захотеть распространить


предварительно созданное рабочее пространство, которое ваши клиенты могут использовать
для быстрого вызова предпочтительных настроек для вашего рабочего пространства.
Следующие ниже шаги проходят через процесс для рабочих областей.

1. Найдите базовый дистрибутив .zip.

2. Откройте .zip.

3. Создайте новый каталог под названием "рабочие области" без кавычек.

4. Перейдите в каталог «рабочие области». Скопируйте рабочее пространство .xml, которое вы


хотите распространить, из My Documents \ NinjaTrader 8 \ workspaces в этот каталог в .zip

Добавление пользовательских файлов ресурсов

Вы можете столкнуться с необходимостью распространять другие пользовательские файлы,


такие как изображения кнопок, для использования с вашим продуктом. Это может быть
достигнуто с помощью того же подхода, что и для шаблонов, если папка ресурсов находится в
родительском каталоге шаблонов.

1. Найдите базовый дистрибутив .zip.

2. Откройте .zip.

3. Создайте новый каталог под названием "шаблоны" без кавычек.

4. Перейдите в каталог «шаблоны» и создайте еще один новый каталог, например


«MyResources».

5. Перейдите в каталог, в котором хранятся ваши файлы. Скопируйте файлы ресурсов, которые
вы хотите распространить, из этого каталога в свой собственный каталог с шага 4 в .zip

Примечание. При изменении архивов .zip, если в вашем приложении-утилите zip есть опция
для сохранения или воссоздания относительных путей, обязательно отключите это, поскольку
это вызовет проблемы при импорте архива в NinjaTrader.
Редактор

Обзор редактора NinjaScript

Редактор NinjaScript - это мощный редактор сценариев, который позволяет эффективно


создавать собственные индикаторы и стратегии. Редактор NinjaScript включает мощные
средства помощи при написании кода и расширенные инструменты отладки, которые помогут
вам создать собственный индикатор, стратегию или любой другой поддерживаемый тип
NinjaScript.

Компоненты редактора NinjaScript

Обзор
Редактор NinjaScript - это мощный редактор сценариев, который позволяет создавать
собственные индикаторы, стратегии и любые другие настраиваемые типы NinjaScript,
используемые для улучшения платформы NinjaTrader. Редактор NinjaScript можно открыть,
выбрав меню «Создать» в Центре управления NinjaTrader. Затем щелкните левой кнопкой
мыши по пункту меню «Редактор NinjaScript».

1. NinjaScript Explorer - отображает файлы, папки и позволяет дополнительно управлять


файлами.

2. Панель инструментов. Наведите указатель мыши на каждый значок, чтобы отобразить


функцию кнопки со значком.

3. Номера строк

4. Маркировка модификации строки - желтые флажки указывают на несохраненные изменения


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

5. Вкладки для создания новых сценариев с помощью мастера NinjaScript и работы с


несколькими сценариями.
Контекстные меню
Контекстные меню можно открыть, щелкнув правой кнопкой мыши в редакторе NinjaScript.
Пункты контекстного меню

Save Сохраняет ожидающие изменения в текущий


открытый NinjaScript

Save As Создает копию сценария и пытается


переименовать имя класса, чтобы новый
сценарий был уникальным.

Insert Code Snippet Вставляет фрагмент кода (дополнительные


сведения см. В разделе фрагменты кода)

Go To Line... Перемещает курсор на указанную строку кода

Undo Отменить

Отменяет последнюю модификацию

Copy Копировать

Копирует выделенный текст в буфер обмена


Paste Вставить

Вставляет текст, сохраненный в буфере


обмена

Remove Удалять

Удаляет выделенный текст

Select All Выбрать все

Выбирает весь текст в редакторе кода

Debug Mode Режим отладки

Устанавливает, должна ли создаваться


отладочная dll при компиляции
(дополнительные сведения см. В разделе
«Отладка Visual Studio»).

References... Рекомендации...

Открывает список ссылок на DLL,


используемых NinjaTrader. Сюда входят
библиотеки DLL, используемые NinjaTrader, и
библиотеки DLL, установленные с
пользовательскими надстройками.

Show Warnings Показать предупреждения

Позволяет видеть предупреждающие


сообщения вместе с ошибками компиляции

Always On Top Всегда на вершине

Устанавливает редактор NinjaScript для


просмотра поверх других окон

Print Распечатать

Позволяет распечатать содержимое этого


окна (дополнительные сведения см. В
разделе «Печать содержимого»).

Share доля

Позволяет поделиться содержимым этого


окна (см. Раздел «Совместное
использование содержимого» для получения
дополнительной информации).
Properties Характеристики

Открывает меню "Свойства" (см. Ниже).

Свойства и определения

Общий

Auto hide NinjaScript explorer(Автоматически Устанавливает, должен ли проводник


скрывать проводник NinjaScript) NinjaScript свертываться по умолчанию

Debug mode(Режим отладки) Устанавливает, должна ли создаваться


отладочная dll при компиляции
(дополнительные сведения см. В разделе
«Отладка Visual Studio»).

Inline syntax checking(Встроенная Устанавливает, должны ли обнаруживаться


проверка синтаксиса) ошибки и предупреждения при написании
кода (без необходимости компиляции)

Auto bracket completion(Автозавершение Устанавливает, должны ли открывающие


брекетинга) символы автоматически вставлять
добавляемые закрывающие символы.
Подходит для (круглые скобки), [скобки],
{фигурные скобки}, <угловые скобки>
Show indentation lines(Показать линии Отображает вертикальные линии для
отступа) форматирования кода

Show Warnings(Показать предупреждения) Устанавливает, должны ли отображаться


предупреждения кода при компиляции.

Font(Шрифт) Sets the font options

Window

Always on top(Всегда на вершине) Устанавливает, будет ли окно всегда поверх


других окон.

Обозреватель NinjaScript

NinjaScript Explorer обеспечивает просмотр папок всех поддерживаемых категорий NinjaScript,


которые могут быть разработаны в NinjaTrader.

Понимание дисплея NinjaScript Explorer

Отображение папок
NinjaScript Explorer упорядочит каждый сценарий, установленный в вашей системе, по типу
объекта NinjaScript (индикатор, стратегия, столбец SuperDOM и т. Д.). В каждой папке будут
отображаться следующие сценарии в каждой категории:

1. Locked scripts( Заблокированные Предварительно созданные системные


скрипты) скрипты, которые поставляются с NinjaTrader,
которые можно просматривать как доступные
только для чтения и которые требуются для
компиляции (конечно, вы можете сохранить
их собственную копию для изменения)

2. Custom scripts(Пользовательские Любой импортированный или


скрипты) разрабатываемый скрипт, который можно
изменить.

3. Ignored custom scripts(Игнорируемые Пользовательские сценарии, которые были


пользовательские скрипты.) исключены из компиляции (дополнительную
информацию см. В разделе «Исключение
сценария из компиляции» ниже)
Закрепление проводника NinjaScript
1. По умолчанию проводник NinjaScript будет «прикреплен» к правой стороне редактора
NinjaScript, однако его можно скрыть из поля зрения, нажав значок булавки NS_Editor_14,
расположенный в правом верхнем углу окна проводника.
2. Когда NinjaScript Explorer свернут, вы можете быстро вернуть его в поле зрения, просто
выбрав вкладку NinjaTrader Explorer, расположенную справа. Повторный выбор значка булавки
NS_Editor_15 повторно закрепит проводник NinjaScript в редакторе NinjaScript.

Меню правого клика


Щелчок правой кнопкой мыши по отдельной папке или сценарию откроет вам ряд различных
пунктов меню, которые помогут в управлении вашими пользовательскими сценариями.
New(Новый) Открывает мастер NinjaScript для
соответствующего типа объекта.

Open(Открыть) Открывает выбранный скрипт в новой


вкладке в текущем окне редактора
NinjaScript.

Open In New NinjaScript Editor(Открыть в Открывает выбранные скрипты в новом окне


новом редакторе NinjaScript) редактора NinjaScript.

Exclude From Compilation(Исключить из Предотвращает компиляцию выбранных


компиляции) сценариев (дополнительные сведения см. В
разделе «Исключение сценария из
компиляции» ниже)

Remove(Удалять) Удаляет текущий файл или папку из системы

New Folder(Новая папка) Создает новую настраиваемую папку для


организации ваших скриптов

Rename(Переименовать) Переименовывает текущий выбранный файл


или папку

Управление скриптами и папками

Открытие существующего скрипта


Открыть скрипт можно двумя способами:

1. Дважды щелкните левой кнопкой мыши по сценарию, который вы хотите просмотреть или
отредактировать в текущем окне.

2. Щелкните сценарий правой кнопкой мыши и выберите «Открыть», чтобы просмотреть или
отредактировать сценарий в виде вкладки в текущем окне, или выберите «Открыть в редакторе
NinjaScript», чтобы открыть сценарий в виде вкладки в новом окне.

Создание новых скриптов


Щелчок правой кнопкой мыши по категории NinjaScript и выбор «Создать ...» откроют мастер
NinjaScript, позволяющий создавать новые пользовательские сценарии.
Дополнительные сведения см. В разделе справки мастера NinjaScript.

Создание собственных папок


NinjaScript Explorer дает вам возможность перемещать и систематизировать ваши
пользовательские сценарии в нескольких пользовательских папках.

• Чтобы создать новую папку, просто щелкните правой кнопкой мыши категорию папок
NinjaScript, которую вы хотите упорядочить, выберите «Новая папка» и с помощью клавиатуры
введите определенное пользователем имя для идентификации папки.

Создав новую папку, с помощью мыши вы можете перетащить любые пользовательские


сценарии из этой категории в эту папку.

Заметки:

1. Вы не можете переместить заблокированный системный скрипт.

2. Вы можете переместить пользовательский скрипт только в том случае, если он закрыт из


редактора NinjaScript.
3. Вы можете переместить скрипт только в папку в его собственной категории папок (т.е.
пользовательские стратегии могут быть размещены только в папке стратегии, было бы
невозможно переместить его в папку индикаторов)

4.Если вы перемещаете дочерний сценарий, который вызывается родителем, обязательно


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

Переименование скриптов и папок


Есть два метода переименования пользовательских скриптов:

1. Щелкните правой кнопкой мыши сценарий в проводнике NinjaScript и выберите


«Переименовать».

2. Выберите нужный сценарий и нажмите клавишу F2 на клавиатуре.

Переименование сценария автоматически переименует все соответствующие имена классов и


все другие необходимые компоненты.

Заметки:

1. Вы не можете переименовать заблокированный системный скрипт или папку.

2. Вы можете переименовать настраиваемый сценарий, только когда он закрыт.

3. Переименовать папку можно только в том случае, если все содержащиеся в ней сценарии
закрыты.

Удаление скриптов и папок


Есть два метода удаления пользовательских скриптов из вашей системы.

1. Щелкните правой кнопкой мыши сценарий в проводнике NinjaScript и выберите «Удалить».

2. Выберите нужный сценарий и нажмите клавишу DEL на клавиатуре.

Удаление сценария полностью удалит сценарий из вашей системы. Это действие не может
быть отменено.
Заметки:

1. Вы не можете удалить заблокированный системный скрипт или папку.

2. При удалении настраиваемой папки будут удалены все сценарии, содержащиеся в ней.

Общие сведения о папках в редакторе NinjaScript и файловой системе


Когда вы создаете папку в редакторе NinjaScript, она также будет создана в файловой системе
на вашем ПК. Например, если вы должны создать подпапку с именем «MyScripts» в
существующей папке «Indicators», подпапка также будет создана в папке Documents \
NinjaTrader 8 \ bin \ Custom \ Indicators. После создания подпапки в нее можно создавать или
перемещать сценарии, используя те же процессы, которые описаны выше.

Предупреждение: изменения подпапок напрямую через файловую систему НЕ будут отражены


в редакторе NinjaScript. Создание и редактирование папок должно выполняться в редакторе
NinjaScript.

Исключение скрипта из компиляции

Игнорирование сценария

Могут возникнуть ситуации, когда в вашей системе установлен специальный сценарий, который
препятствует компиляции других сценариев из-за ошибок. Причина этого в том, что NinjaTrader
будет компилировать ВСЕ пользовательские файлы NinjaScript в одну DLL для повышения
производительности. Если вы обнаружите, что установили сценарий, который выдает ошибки,
которые вы не можете устранить, или вы в настоящее время находитесь в процессе разработки
сценария, который не может быть скомпилирован, вы можете легко проигнорировать эти
файлы из компилятора из редактора NinjaScript.

• Чтобы проигнорировать сценарий, щелкните правой кнопкой мыши имя сценария и выберите
«Исключить из компиляции».

Когда скрипт игнорируется, он будет скрыт в проводнике NinjaScript, чтобы указать, что он не
будет скомпилирован.
Чтобы включить этот сценарий для следующей компиляции, просто щелкните сценарий правой
кнопкой мыши в проводнике NinjaScript и снимите флажок «Исключить из компиляции».
Примечание. Вы не можете исключить заблокированный системный скрипт или папку.
Совет: вы также найдете возможность исключить скрипты из компиляции, щелкнув правой
кнопкой мыши список ошибок, сгенерированных в нижней части редактора NinjaScript.
• Выбор «Исключить из компиляции» игнорирует только выбранный файл NinjaScript.
• Выбор «Исключить все из компиляции» исключает все файлы NinjaScript, в которых в
настоящее время есть ошибки.

Мастер NinjaScript

Мастер NinjaScript используется для создания минимального количества кода, необходимого


для начала программирования любого поддерживаемого типа NinjaScript. Этот мастер позволит
вам определить любые свойства по умолчанию, добавить настраиваемые входные параметры,
добавить дополнительные серии данных и добавить любые соответствующие методы событий.
В мастере NinjaScript доступен ряд различных свойств и параметров в зависимости от типа
создаваемого объекта NinjaScript.
Информация на этой странице должна использоваться в качестве стандартного обзора
различных компонентов мастера NinjaScript. Дополнительную информацию о методах и
свойствах NinjaScript см. В разделе «Справочник по языку NinjaScript» нашего Справочного
руководства.

Открытие мастера NinjaScript

Создание нового файла NinjaScript


Мастер NinjaScript можно открыть из редактора NinjaScript, выбрав символ + в строке вкладки, а
затем выбрав тип объекта NinjaScript, который вы хотите разработать.

Вы также можете щелкнуть правой кнопкой мыши любую из категорий NinjaScript,


перечисленных в проводнике NinjaScript, и выбрать «Создать ...»
Понятие об отображении мастера NinjaScript

Обзор дисплея

1. Wizard Navigation Menu(Меню Используется для перехода к различным


навигации мастера) страницам мастера. Вы можете в любой
момент перейти к любой странице мастера
или вернуться к ней.

2. Wizard Screen(Экран мастера) Отображает соответствующую информацию,


относящуюся к шагу мастера, к которому вы
перешли, и предоставляет инструкции,
которые помогут вам определить свой
сценарий на различных этапах.

3. Wizard Controls( Мастер управления) Buttons used to perform various actions


pertaining to the script that is being created.
Selecting Generate at any time will exit the
wizard and open your script in the
NinjaScript Code Editor (Note: You cannot
return back to the NinjaScript Wizard once
the code is generated).

Понимание экранов мастера


Дополнительные страницы
В мастере NinjaScript Wizard доступно несколько различных страниц, которые используются
для определения различных шагов вашего пользовательского скрипта. Обратите внимание, что
в таблице ниже описаны ВСЕ страницы, доступные в мастере, но не подразумевается, что эти
шаги будут доступны для сценария, который вы в настоящее время создаете.

Welcome(Добро пожаловать) Первый шаг мастера, используемый для


определения типа создаваемого объекта.

General(Общий) Используется для определения имени и


описания для идентификации файла
NinjaScript

Default Properties(Свойства по Устанавливает различные свойства и


умолчанию) поведение при запуске для создаваемого
скрипта.

Additional Data(Дополнительная Используется для необязательного


информация) добавления дополнительных рядов данных,
таких как минуты, тики и т. Д., Или даже
пользовательских рядов, которые вы можете
планировать программно.

Additional Event Methods(Дополнительные При желании добавьте в свой собственный


методы событий) сценарий дополнительные методы событий,
такие как OnMarketData, OnMarketDepth и т.
Д.

Input Parameters(Входные параметры) Используется для определения любых


общедоступных свойств, которые могут
использоваться в вашем скрипте.

Plots and Lines(Сюжеты и линии) При желании добавьте в сценарий


визуальные графики или линии для
построения графиков.

Finish(Конец) Последняя страница мастера дает вам


возможность вернуться и просмотреть
каждую страницу при желании перед
завершением создания сценария.

Фрагменты кода

Фрагменты кода могут предоставить вам полезные шаблоны кода для ускорения процесса
написания кода.

Понимание сочетаний клавиш для фрагментов кода

Вы можете быстро добавить часто используемые методы и структуры кода через


• Короткие символы

• Щелкнув правой кнопкой мыши и выбрав название меню «Вставить фрагмент кода».

• Нажатие клавиши F2 на клавиатуре.

Как использовать горячие клавиши фрагмента кода с клавиатуры

Использование клавиатуры
Введите текст в левом столбце и нажмите клавишу «Tab» в редакторе NinjaScript.

Текущие значения бара

cb CurrentBar

o Open[0]

h High[0]

l Low[0]

v Volume[0]

i Input[0]

Предыдущие значения бара

c1 Close[1]

o1 Open[1]

h1 High[1]

l1 Low[1]

v1 Volume[1]
i1 Input[1]

Индикаторный график

line(линия) AddLine(new Stroke(Brushes.Blue, 1), 0, "Line");

plot(участок) AddPlot(new Stroke(Brushes.Blue, 1),


PlotStyle.Line, "Plot");

Арифметика

abs Math.Abs(value)

min Math.Min(value1, value2)

max Math.Max(value1, value2)

Методы обратного вызова обработчика событий

account(учетная запись) protected override void


OnAccountItemUpdate(Account account,
AccountItem accountItem, double value)
{

trade(торговля) protected override void OnAddTrade(Cbi.Trade


trade)
{

barschange(смена бара) public override void OnBarsChanged()


{

minmax(мин макс) public override void OnCalculateMinMax()


{
// Важно установить MinValue и MaxValue на
минимальные / максимальные значения Y,
используемые вашим инструментом рисования,
если вы хотите, чтобы он поддерживал
автоматическое масштабирование
}

calcperf protected override void


OnCalculatePerformanceValue(StrategyBase
strategy)
{

}
connection(связь) protected override void
OnConnectionStatusUpdate(ConnectionStatus
orderStatus, ConnectionStatus priceStatus)
{

datapoint(точка данных) protected override void OnDataPoint(Bars bars,


double open, double high,
double low, double close, DateTime time,
long volume, bool isBar, double bid, double
ask)
{

execution(исполнение) protected override void


OnExecutionUpdate(Execution execution, string
executionId, double price,
int quantity, MarketPosition marketPosition,
string orderId, DateTime time)
{

fundamental(фундаментальный) protected override void


OnFundamentalData(FundamentalDataEventArgs
fundamentalDataUpdate)
{

data(данные) protected override void


OnMarketData(MarketDataEventArgs
marketDataUpdate)
{

depth(глубина) protected override void


OnMarketDepth(MarketDepthEventArgs
marketDepthUpdate)
{

mergeperf protected override void


OnMergePerformanceMetric(PerformanceMetricBas
e merge)
{

moused(мышка) public override void OnMouseDown(ChartControl


chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{

mousem(мышь) public override void OnMouseMove(ChartControl


chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{

mouseu public override void OnMouseUp(ChartControl


chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{

optimize(оптимизировать) protected override void OnOptimize()


{

ordert(заказ) protected override void OnOrderTrace(DateTime


timestamp, string message)
{

orderu(заказ) protected override void OnOrderUpdate(Order


order, double limitPrice, double stopPrice,
int quantity, int filled, double
averageFillPrice,
OrderState orderState, DateTime
time, ErrorCode error,
string nativeError)
{

position(позиция) rotected override void OnPositionUpdate(Position


position, double averagePrice, int quantity,
MarketPosition marketPosition)
{

render(оказывать) protected override void OnRender(ChartControl


chartControl, ChartScale chartScale)
{

windowc(окна) protected override void


OnWindowCreated(Window window)
{

windowd protected override void


OnWindowDestroyed(Window window)
{

Контрольные отчеты

if if (expression)
{

}
else
{

for for (int index = 0; index < count; index++)


{

switch switch (expression)


{
case value1:

break;
case value2:

break;
default:

break;
}

Рисунок
сокращенно метод

dap Draw.AndrewsPitchfork(this,
"MyAndrewsPitchfork", false, 10, Close[10], 5,
High[5], 0, Low[5], Brushes.Blue,
DashStyleHelper.Solid, 1);

da Draw.Arc(this, "MyDrawArc", false, 10,


Close[10], 0,
Close[0], Brushes.LimeGreen,
DashStyleHelper.Dot, 2);

dd Draw.ArrowDown(this, "MyArrowDown", false, 0,


High[0], Brushes.Red);

du Draw.ArrowUp(this, "MyArrowUp", false, 0,


Low[0], Brushes.Red);

ddi Draw.Diamond(this, "MyDiamond", false, 0,


High[0] + 2 * TickSize, Brushes.Blue);

dt Draw.Dot(this, "MyDot", false, 0, High[0] + 2 *


TickSize, Brushes.Blue);

de Draw.Ellipse(this, "MyEllipse", 10, Low[10], 0,


High[0], Brushes.Blue);

di Draw.ExtendedLine(this, "MyExtendedLine", 10,


Close[10], 0, Close[0], Brushes.Blue);

dfc Draw.FibonacciCircle(this, "MyFibonacciCircle",


true, 10, Close[10], 0, Close[0]);

dfe Draw.FibonacciExtensions(this,
"MyFibonacciExtensions", true, 15, Close[15],
10, Close[10], 5, Close[5]);

dfr Draw.FibonacciRetracements(this,
"MyFibonacciRetracements", false, 10,
Close[10], 0, Close[0]);

dft Draw.FibonacciTimeExtensions(this,
"MyFibonacciTimeExtensions", false, 10,
Close[10], 0, Close[0]);

dg Draw.GannFan(this, "MyGannFan", true, 10,


Close[10]);

dh Draw.HorizontalLine(this, "MyHorizontalLine",
Close[0], Brushes.Blue);
dl Draw.Line(this, "MyLine", 10, Close[10], 0,
Close[0], Brushes.Blue);

dy Draw.Ray(this, "MyRay", 10, Close[10], 0,


Close[0], Brushes.Blue);

dr Draw.Rectangle(this, "MyRectangle", 10,


Low[10], 0, High[0], Brushes.Blue);

dre Draw.Region(this, "MyRegion", CurrentBar, 0,


Bollinger(2, 14).Upper,
Bollinger(2, 14).Lower, Brushes.Green,
Brushes.Blue, 50);

drx Draw.RegionHighlightX(this,
"MyRegionHighlightX", 10, 0, Brushes.Blue);

dry Draw.RegionHighlightY(this,
"MyRegionHighlightY", High[0], Low[0],
Brushes.Blue, Brushes.Green, 20);

drr Draw.RiskReward(this, "MyRiskReward", false,


0, High[0], 10, Low[0], 2, true);

dru Draw.Ruler(this, "tag1", true, 4, Low[4], 3,


High[3], 1, Low[1]);

ds Draw.Square(this, "MySquare", false, 0, High[0]


+ 2 * TickSize, Brushes.Blue);

dx Draw.Text(this, "MyText", "Sample text ", 0,


High[0] + 2 * TickSize, Brushes.Blue);

dxf Draw.TextFixed(this, "MyTextFixed", "Text to


draw", TextPosition.TopRight);

dtc Draw.TrendChannel(this, "TrendChannel", true,


10, Low[10], 0, High[0], 10, High[10] + 5 *
TickSize);

dtd Draw.TriangleDown(this, "MyTriangleDown",


false, 0, High[0] + 2 * TickSize, Brushes.Red);

dtu Draw.TriangleUp(this, "MyTriangleUp", false, 0,


Low[0] - 2 * TickSize, Brushes.Blue);

dv Draw.VerticalLine(this, "MyVerticalLine", 0,
Brushes.Blue);

Как вставлять фрагменты кода с помощью мыши или клавиши F2

С помощью мыши или нажатия клавиши F2


1. Щелкните правой кнопкой мыши в редакторе NinjaScript и выберите название меню
«Вставить фрагмент кода».

2. В меню отобразятся все доступные фрагменты кода.

Ошибки компиляции

При компиляции пользовательского индикатора или стратегии возможно и вероятно


возникновение ошибок компиляции.
• NinjaTrader скомпилирует ВСЕ файлы NinjaScript, а НЕ только файл, с которым вы работаете.

• Список ошибок компиляции для всех файлов будет отображаться в нижней части редактора
NinjaScript.

• Дважды щелкните ошибку, чтобы загрузить проблемный файл и выделить проблемную


область.

• Щелкните код ошибки, чтобы открыть справочную документацию по конкретной ошибке.


• Щелкните правой кнопкой мыши по ошибке, чтобы исключить проблемный файл из
компиляции (дополнительные сведения см. В разделе «Исключение сценария из компиляции»).

На изображении ниже показана ошибка компиляции.


1. Раздел, в котором отображаются ошибки компиляции. Ошибки в текущем загруженном
файле обозначаются светлым цветом, а ошибки в других файлах - более темным цветом.

2. Файл, содержащий ошибку.

3. Описание ошибки.

4. Ссылка на код ошибки, которая откроет Справочное руководство с любой соответствующей


информацией о коде ошибки.

5. Номер строки и номер столбца ошибки.

6. Ошибка подчеркнута красной волнистой линией.

Ошибка, выделенная значком (6) ниже, показывает, что выражение не закрывается точкой с
запятой. Выражение должно быть:

double myValue = SMA (20) [0];

Intelliprompt

Что такое Intelliprompt?


Intelliprompt - это форма автоматического автозаполнения, популяризированная
интегрированной средой разработки Microsoft Visual Studio. Он также служит в качестве
документации и устранения неоднозначности для имен переменных, функций и методов.
Intelliprompt встроен в редактор NinjaScript, что создает эффективную среду для кодирования
ваших пользовательских индикаторов и стратегий.

How to access the Intelliprompt list box

В редакторе NinjaScript вы можете ввести «это». , чтобы открыть список Intelliprompt. Список
содержит все доступные для использования методы (функции) и свойства. Вы можете выбрать
метод или свойство, просто выбрав их с помощью мыши или прокручивая их с помощью
клавиши со стрелкой вверх или вниз. При нажатии клавиши «Tab» или «Enter» код
автоматически вставляется в редактор NinjaScript. Находясь в поле списка, вы можете нажать
любую буквенную клавишу, чтобы быстро перейти к следующему свойству или методу, начиная
с буквы нажатой клавиши.

На изображении ниже:
1. Свойства

2. Метод

Если вы знаете, что хотите получить доступ к методу индикатора Simple Moving Average,
который называется SMA (), и думаете, что он начинается с «SM», введите «SM» и нажмите
CTRL-пробел, чтобы отобразить поле со списком Intelliprompt ниже.
Нажатие CTRL + пробел после любого текста всегда будет
• Вызовите список Intelliprompt со связанными методами и свойствами.

• Автоматически вставлять код, если текст может однозначно идентифицировать метод или
свойство

• По этой ссылке можно просмотреть другие сочетания клавиш.

Понимание описания метода и подписей

При выборе метода


1. Введите "(", чтобы отобразить описание метода и подпись.
2. Появится светло-желтая рамка с описанием метода и доступными сигнатурами.

3. На изображении ниже вы увидите «1 из 3», что означает, что мы смотрим на первую из трех
доступных сигнатур методов. Вы можете просмотреть все доступные подписи, нажимая
клавиши со стрелками вверх и вниз.

Что такое подпись метода?


Подпись метода - это общий термин, используемый в объектно-ориентированном
программировании для уникальной идентификации метода. Обычно сюда входит имя метода,
количество и тип его параметров, а также тип возвращаемого значения.

На изображении выше метод DMI () представляет индикатор Dynamic Momentum Index,


имеющий две сигнатуры метода:

DMI (период int)


DMI (IDataSeries inputData, период int)

Окно вывода

Вывод NinjaScript - это мощный инструмент отладки, который можно использовать для
дальнейшего анализа ценной информации, созданной вашими файлами NinjaScript. Окно
вывода будет отображать данные только в том случае, если другие методы отладки, такие как
Print () или TraceOrders (для стратегий), были настроены в настраиваемом сценарии.

Вы можете открыть окно вывода NinjaScript, перейдя в меню «Создать» и выбрав «Вывод
NinjaScript».

Общие сведения об отображении окна вывода


Обзор дисплея

1. Output table(Выходная таблица) Главный компонент окна вывода будет


отображать любое сообщение печати или
информационное сообщение, отправленное
из сценария.

2. Scrollbar(Полоса прокрутки) Используется для перемещения вверх / вниз


в окне вывода

3. Output tabs( Вкладки вывода) Доступны две вкладки, позволяющие


разделить информацию о печати для
отдельных сценариев.

4. Line highlight(Выделение строки) Щелчок левой кнопкой мыши по строке


выделит конкретную достопримечательность
и останется выделенной при обновлении
окна вывода или при его прокрутке вверх и
вниз.
Right click menu

Clear(очистить) Очищает текущее содержимое выбранной


вкладки окна вывода.

Find…(найти) Ищет термин в окне вывода

Save As...*(Сохранить как) Сохраняет текущее содержимое окна вывода


в текстовый файл

Always On Top(Всегда на вершине) Устанавливает окно всегда поверх других


окон

Dual View(Двойной просмотр) Включает / отключает разделение вкладок


вывода между окнами, позволяя
просматривать обе вкладки одновременно.

Synchronize Vertical Если этот параметр включен, обе вкладки


Scrolling(Синхронизировать вертикальную будут прокручиваться вверх / вниз
прокрутку) одновременно и в темпе.
NinjaScript Utilization Monitor(Монитор Открывает окно монитора использования
использования NinjaScript) NinjaScript.

Print Отображает параметры для печати текущего


содержимого окна на вашем принтере

Share Отображает параметры общего доступа

Properties(характеристики) Устанавливает свойства окна вывода

Понимание режима двойной вкладки


Двойной обзор
При желании вы можете разделить вкладку окна вывода на двойное представление, что
позволит вам одновременно просматривать оба окна вывода. Чтобы включить эту функцию,
просто щелкните правой кнопкой мыши в окне «Вывод» и выберите «Двойной просмотр».

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


выходные данные двух отдельных индикаторов. MyCustomIndicator запрограммирован для
печати на вкладке «Вывод 1», а MyCustomIndicator1 запрограммирован для печати на вкладке
«Вывод 2». (См. Статью Справочного руководства о методе PrintTo () для получения
дополнительной информации о программировании пользовательского сценария для печати на
второй вкладке вывода)
Синхронизированная прокрутка
Пока окно вывода находится в режиме двойного просмотра, каждое окно вывода будет иметь
независимую полосу прокрутки, которая позволяет вам перемещаться по каждой вкладке
вывода отдельно. Однако при желании вы можете синхронизировать вертикальную прокрутку
между этими двумя окнами, что позволит вам легко сравнивать вывод двух разностных
скриптов, где обе вкладки будут прокручиваться вверх / вниз одинаково одновременно.

Чтобы включить эту функцию, щелкните правой кнопкой мыши в окне «Вывод» и выберите
пункт меню «Синхронизированная вертикальная прокрутка».

Поиск и выделение
Использование инструмента поиска
Если вы хотите найти определенное значение или текст, отображаемый в окне вывода, вы
можете использовать инструмент «Найти» для выделения и навигации по любым терминам,
которые соответствуют вашему поиску.

Чтобы вызвать меню «Найти», щелкните правой кнопкой мыши в окне «Вывод» и выберите
«Найти» (или используйте сочетание клавиш CTRL + F).

Чтобы найти конкретный термин:

1. Введите текст / значение, которое вы хотите найти.

2. Укажите, на какой вкладке вывода вы хотите выполнить поиск.

3. При желании установите флажок Учитывать регистр, чтобы искать только те термины,
которые содержат точный текстовый регистр вашего термина (т. Е. Close не будет таким же, как
close).

4. Нажмите кнопку «Найти», чтобы перейти к следующему совпадающему термину и выделить


его (обозначено зеленой стрелкой на изображении ниже).

5. Поиск также выделит любые другие совпадения в окне вывода, которые соответствуют
поиску.

При повторном нажатии кнопки «Найти» поиск в окне «Вывод» будет продолжен, и следующее
совпадение будет выделено.
Совет: Без инструмента поиска вы также можете выделить термины, просто дважды щелкнув
текст в окне вывода. Это приведет к автоматическому поиску выделенного термина и
выделению всех результатов.

Очистка и сохранение выходной информации

Очистка выходной информации


Через некоторое время вы можете почувствовать необходимость стереть всю текущую
информацию на текущей вкладке вывода. Для этого просто щелкните правой кнопкой мыши
текущую вкладку вывода и выберите «Очистить».

Совет: вы также можете использовать метод ClearOutputWindow () непосредственно в своем


скрипте, чтобы автоматически очищать выходной контент при определенном событии или
интервале.

Сохранение выходной информации


Если вы хотите сохранить текущие результаты вашего вывода, вы можете щелкнуть правой
кнопкой мыши на нужной вкладке вывода и выбрать «Сохранить как». Откроется диалоговое
окно «Сохранить как», которое позволит вам сохранить вывод в текстовом файле (.txt) в любом
месте на вашем компьютере.
Output window properties
The following properties are available for configuration within the NinjaScript Output properties
window:

Window

Always on top Устанавливает окно вывода поверх других


окон

Dual view Включает / отключает разделение вкладок


вывода между окнами, позволяя
просматривать обе вкладки одновременно.

Font - Output 1 Устанавливает отображение шрифта для


вкладки Выход 1

Font - Output 2 Устанавливает отображение шрифта для


вкладки Выход 2

Synchronize vertical scrolling Включает / отключает, когда обе вкладки


будут прокручиваться вверх / вниз
одновременно и в одинаковом темпе

Монитор использования NinjaScript

The NinjaScript Utilization monitor is opened via a right click in the NinjaScript Output window and will
be mainly used as a diagnostic tool for performance issues.
It will track any NinjaScript objects total resource time from the moment the window was opened:

•NinjaScript Utilization monitor window will not be saved in any workspace file
•NinjaScript Utilization monitor window works across all workspaces using a single window instance
•NinjaScript Utilization monitor window will work even if hidden / non-visible

When using it as debugging aid, it's recommended to focus on the top resource using NinjaScript's,
while absolute total time is negligible.

Also it's important to understand that a resource heavy NinjaScript could be meaning:

a) the NinjaScript may not be coded as efficiently as possible and would be worthwhile to review if
everything has been done to achieve optimal performance
b) it could be doing intense / steady calculations by design and a higher than average resource use
therefore could likely not be avoided.

It should be thought of a gauge to see where likely performance / code optimization time is likely most
wisely spend if the overall performance footprint is to be reduced.

Our support team is trained with this process and is available to assist.
Отладка Visual Studio
Вы можете отлаживать свои объекты NinjaScript с помощью Microsoft Visual Studio. Объекты
NinjaScript компилируются в одну DLL с именем «NinjaTrader.Custom.dll». При отладке для
временного использования создается специальная отладочная DLL с тем же именем, что и
версия выпуска.

Заметки:

• Использование DLL отладки может повлиять на производительность во время выполнения,


поэтому рекомендуется отключить отладку Visual Studio и перекомпилировать сценарии по
завершении. Это заменит DLL отладки на версию выпуска.

• Он будет работать с Visual Studio 2015, 2017 или 2019 - если установлено несколько версий,
будет использоваться самая высокая из них.

Использование отладки Visual Studio


1. В редакторе NinjaScript включите «Режим отладки» с помощью контекстного меню, как
показано на изображении ниже. После этого скомпилируйте свои сценарии для создания DLL
отладки.
2. В редакторе NinjaScript щелкните значок Visual Studio NS_Editor_6 на панели инструментов,
при этом будет автоматически загружен проект NinjaTrader.Custom с установленной вами
версией Visual Studio.

3. В Visual Studio выберите «Отладка», затем выберите «Присоединить к процессу».


4. Выберите NinjaTrader из списка процессов, затем выберите «Присоединить». Убедитесь, что
в поле «Присоединить к» установлено значение «Автоматически: управляемый код» или
«Управляемый код».
4. Откройте исходный файл NinjaScript в Microsoft Visual Studio и установите точки останова.

5. Запустите свой объект NinjaScript в NinjaTrader, и он должен остановиться в точках останова,


и все инструменты отладки и информация должны быть доступны для проверки текущего
состояния кода.
Совет: вы также можете использовать Visual Studio в качестве редактора для файлов
NinjaScript - для этого откройте проект, как на шаге 2 выше, а затем используйте Visual Studio
для редактирования и после завершения сохраните файл (не запускайте и не создавайте
решение тогда в Visual Studio), желательно с открытым одновременно редактором NinjaScript,
поэтому изменения будут автоматически скомпилированы.

Сочетания клавиш редактора


Редактор NinjaScript включает ряд сочетаний клавиш, недоступных в других частях платформы.
Ниже приведен список доступных ярлыков и выполняемых ими действий:

Ctrl + C, Ctrl + Insert Скопировать в буфер обмена

Ctrl + X, Shift + Delete Вырезать в буфер обмена

Ctrl + L Вырезать линию в буфер обмена

Ctrl + V, Shift + Insert Вставить из буфера обмена

Ctrl + Y, Ctrl + Shift + Z Повторить действие

Ctrl + Z Undo action

Ctrl + Backspace Возврат к предыдущему слову

Ctrl + Shift + L Удалить строку

Ctrl + Delete Удалить до следующего слова

Ctrl + Enter Открытая линия выше

Ctrl + Shift + Enter Открытая строка ниже

Ctrl + Space Автозаполнение Intelliprompt

Ctrl + Shift + Space Intelliprompt показать параметры

Ctrl + T Транспонировать символы

Ctrl + Shift + T Транспонировать слова

Shift + Alt + T Транспонировать строки

Ctrl + Shift + U Сделать прописными

Shift + Tab Убрать отступ табуляции

Alt + Up Переместить выделенные строки вверх

Alt + Down Переместить выделенные строки вниз


Ctrl + Left Перейти к предыдущему слову

Ctrl + Right Перейти к следующему слову

Ctrl + Home Перейти к началу документа

Ctrl + End Перейти в конец документа

Ctrl + PageUp Перейти к видимой верхней части документа

Ctrl + PageDown Перейти к видимой нижней части документа

Ctrl + ] Move to matching bracket

Ctrl + Down Прокрутить вниз

Ctrl + Up Прокрутите вверх

Shift + PageUp Выбрать все выше

Shift + PageDown Выбрать все ниже

Ctrl + Shift + PageUp Выберите видимую область выше

Ctrl + Shift + PageDown Выберите видимую область ниже

Ctrl + Shift + W Выбрать слово

Ctrl + Shift + ] Выбрать до подходящей скобки

Shift + Alt + Arrow Keys Расширение / контракт региона выбора

Справочник по языку

Справочник по языку NinjaScript

Обзор разработки дополнений

Основы разработки надстроек


Платформа NinjaScript AddOn обеспечивает функциональность, охватывающую всю платформу
NinjaTrader, одновременно предоставляя доступ к определенным основным методам и
свойствам, не содержащимся в пространстве имен NinjaScript. Помимо создания собственного
независимого окна или изменения пользовательского интерфейса и функциональности
существующих окон NinjaTrader (графиков и т. Д.), Надстройки также могут подписываться на
данные реального рынка, получать доступ к информации об учетной записи и т. Д.

Примечание. Большинство тем, затронутых на этой странице и ее подстраницах, можно


увидеть в полнофункциональном примере AddOn Framework, доступном на этой странице. Есть
две развернутые версии, к которым вы можете получить доступ, в зависимости от желаемой
среды разработки. Плюсы и минусы каждого подхода описаны в следующем разделе. В любой
версии сильно прокомментированный код в примере может дополнять информацию на этих
страницах, чтобы обеспечить более глубокое понимание.

Среда разработки редактора NinjaScript (NinjaScript Basic)


Редактор NinjaScript можно использовать для создания и написания собственных надстроек на
C #.

Плюсы

• Используйте знакомый редактор NinjaScript (если вам неудобно работать с Visual Studio)

• Изменения в AddOn отражаются сразу после компиляции NS Editor и не требуют перезапуска.

Минусы

• Если вы хотите создать собственный NTWindow, файлы XAML нельзя редактировать в


редакторе NinjaScript.

• Редактору NinjaScript не хватает поддержки общих инструментов разработки и отладки,


доступных в IDE, таких как Visual Studio.

Ниже представлен zip-файл, совместимый с редактором NinjaScript (который также содержит


файл XAML).

• Загрузите файл AddOn Framework NinjaScript Basic на свой рабочий стол.

• В окне Центра управления выберите меню Инструменты> Импорт> NinjaScript.

• Выберите загруженный файл.

После импорта надстройку можно запустить через меню «Создать» в Центре управления.

Среда разработки надстройки (Visual Studio Advanced)


Поскольку надстройки могут включать в себя несколько классов, уникальные пользовательские
интерфейсы и различные типы файлов (XAML, звуки и т. Д.), Рекомендуемая среда разработки
для надстроек отличается от других типов NinjaScript. Следуя приведенным ниже
рекомендациям по настройке среды разработки AddOn, можно упростить этот процесс.

Плюсы
• Используйте Visual Studio или аналогичную IDE для создания решения, связывающего все
файлы проекта вместе.

• Используйте свою среду IDE для создания DLL, а не экспортируйте через NinjaTrader.

• Это позволит вам объединить XAML и другие файлы в DLL.

• Установите событие после сборки, чтобы поместить DLL в соответствующую папку


(NinjaTrader 8 / bin / Custom)

• Установите действие запуска отладки для запуска NinjaTrader.

Минусы

• Необходимо перезапустить NinjaTrader, чтобы повторно загрузить скомпилированную DLL


после изменений.

Если вы используете эту настройку и создаете DLL со своей IDE, среда IDE автоматически
разместит ее там, где она должна быть, и немедленно запустит платформу для тестирования
любых изменений.

Ниже представлен полный проект Visual Studio с такой настройкой. Просто распакуйте
содержимое этого архива в желаемое место, затем откройте решение
«NinjaTraderAddOnProject.sln» в Visual Studio.

Скачать решение Visual Studio для разработки надстроек

Заметки:

• Это решение Visual Studio нельзя импортировать в NinjaTrader. Его необходимо открыть в
Visual Studio.

• По умолчанию файл проекта использует следующий путь в начальном действии: C: \ Program


Files (x86) \ NinjaTrader 8 \ bin64 \ NinjaTrader.exe. Если вы установили NinjaTrader в другой
каталог, вам нужно будет соответствующим образом изменить путь к файлу.

• Решение нацелено на .NET 4.8 с NinjaTrader Release R23 или выше. Если вы откроете его в
более ранней версии .NET, Visual Studio предложит вам загрузить требуемый SDK более
высокой версии.
Создание собственного окна надстройки
Разработчики NinjaScript могут использовать платформу AddOn для создания автономных
независимых окон для предоставления настраиваемых функций. В фреймворке доступны
вспомогательные классы для создания экземпляров окон в стиле, аналогичном заранее
созданным окнам NinjaTrader, включая знакомые функции, такие как связывание окон,
интерфейс с вкладками и возможность сохранять окно и его состояние в рабочих областях.
Кроме того, общие элементы пользовательского интерфейса WPF и XAML можно использовать
для стилизации и изменения окон с помощью платформы .NET.

Подробное пошаговое руководство по созданию собственного окна с использованием


вспомогательных классов NinjaScript см. На странице «Создание собственного окна
надстройки».

На изображении выше показано полностью новое окно, созданное настраиваемым


дополнением.

Другое использование надстройки


Для работы надстройки не требуется собственное окно. Вместо этого его можно использовать
для выполнения функций, не связанных с пользовательским интерфейсом, на платформе,
таких как мониторинг рыночных данных или доступ к информации об учетной записи, позиции и
заказе. Дополнения также можно использовать для добавления функциональных возможностей
или элементов интерфейса в другие окна NinjaTrader, такие как графики.
Для получения подробной информации о других распространенных применениях надстройки
см. Страницу «Другое использование надстройки».

На изображении выше пользовательская кнопка «Образец кнопки» нарисована в окне графика


с помощью надстройки.

Разработка дополнений

Обзор добавлений
Add Ons - это невероятно мощные объекты NinjaScript, которые позволяют создавать
беспрецедентные инструменты, которые легко интегрируются (визуально и функционально) в
NinjaTrader. Опытные программисты могут использовать информацию, доступную через
фреймворк, для создания новых захватывающих окон и утилит, которые могут дать
пользователям невероятное преимущество над рынками.
Как сделать аддоны
Процесс создания надстройки довольно прост, если понимать структуру. Необходимо ответить
на несколько вопросов, чтобы определить, как создать свое дополнение:

1. Где должна быть точка входа для Add On? Например. Следует ли его запускать из меню
Центра управления? Следует ли запускать из графика?

2. Должен ли Add On использовать функции вкладок, доступные в NinjaTrader?

3. Должен ли Add On использовать функциональность связывания окон, доступную в


NinjaTrader?

4.Следует ли надстройка сохраняться в рабочих пространствах NinjaTrader?

Как только функциональность вашего Add On определена, вы можете использовать следующие


строительные блоки для создания своего Add On:

AddOnBase Здесь вы создаете точку входа для Add On.

NTWindow Здесь вы определяете контейнер


родительского окна для своего надстройки.
Если вы выберете, вкладки будут находиться
в этом родительском окне. Здесь также будет
создаваться постоянство рабочего
пространства.

NTTabPage Здесь вы определяете содержимое каждой


вкладки, находящейся внутри NTWindow.
Здесь же вы создаете функцию связывания
окон.

Класс, реализующий интерфейс Это необходимо для обеспечения


INTTabFactory правильной работы вкладок, таких как
добавление, удаление, перемещение вкладок
в NTWindow.

Общий поток идет от AddOnBase> NTWindow> INTTabFactory> NTTabPage.

AddOnBase определяет точку входа пользователя, а затем создает обработчик событий для
создания NTWindow. NTWindow вызывает фабрику вкладок, которая затем передает
содержимое NTTabPage в виде вкладок в NTWindow.

Add On

Пользовательские надстройки можно использовать для расширения функциональности


NinjaTrader. Методы и свойства, описанные в этом разделе, уникальны для пользовательской
разработки Add On.
Для получения дополнительной информации о процессе разработки Add On, пожалуйста,
прочтите эту статью.

NinjaTrader Controls Этот раздел содержит элементы управления,


которые являются встроенными элементами
управления NinjaTrader.

Account Класс Account можно использовать для


подписки на события, связанные с учетной
записью, а также для доступа к информации,
связанной с учетной записью.

BarsRequest BarsRequest можно использовать для


запроса данных Bars и подписки на события
данных Bars в реальном времени.

Connection Класс Connection можно использовать для


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

IInstrumentProvider Interface Если при создании NTTabPage вы хотите


использовать ссылку на инструмент,
обязательно реализуйте интерфейс
IInstrumentProvider.

IIntervalProvider Interface Если при создании NTTabPage вы хотите


использовать интервальную ссылку,
обязательно реализуйте интерфейс
IIntervalProvider.

INTTabFactory Interface Если вы хотите иметь функциональные


возможности страницы вкладок, такие как
добавление, удаление, перемещение,
дублирование вкладок, вы должны создать
класс, реализующий интерфейс
INTTabFactory.

IWorkspacePersistence Interface При создании NTWindow обязательно


реализуйте интерфейс
IWorkspacePersistence, чтобы иметь
возможность сохранять и восстанавливать
свое окно с помощью рабочих пространств
NinjaTrader.

NTTabPage Class Здесь можно определить фактическое


содержимое вкладок внутри настраиваемого
добавления в NTWindow.

Alert and Debug Concepts В большинстве сценариев вы можете


использовать методы, предоставленные
NinjaScript, для запуска предупреждений и
функций отладки. Однако при создании
собственных пользовательских объектов вы
можете захотеть использовать эту
функциональность за пределами области
NinjaScript.

AtmStrategy AtmStrategy содержит свойства и методы,


используемые для управления стратегиями
банкоматов.

ControlCenter ControlCenter - это определенный XAML


класс, содержащий макет и свойства окна
Control Center.

FundamentalData FundamentalData is used to access


fundamental snapshot data and for
subscribing to fundamental data events.

MarketData MarketData может использоваться для


доступа к рыночным данным моментальных
снимков и для подписки на события
рыночных данных.

MarketDepth MarketDepth можно использовать для доступа


к моментальному снимку глубины рынка и
для подписки на события глубины рынка.

NewsItems NewsItems можно использовать для хранения


новостных статей.

NewsSubscription NewsSubscription можно использовать для


подписки на новости.

NTMenuItem NTMenuItem используется для создания


новых пунктов меню.

NTWindow Класс NTWindow определяет родительские


окна для создания пользовательских окон.
Экземпляры NTWindow действуют как
контейнеры для экземпляров NTTabPage, в
которых содержатся элементы
пользовательского интерфейса и связанная с
ними логика.

NumericTextBox NumericTextBox предоставляет


функциональные возможности для числовых
текстовых полей для захвата вводимых
пользователем данных.

OnWindowCreated() Этот метод вызывается всякий раз, когда


создается новое окно NTWindow.

OnWindowDestroyed() Этот метод вызывается всякий раз, когда


уничтожается новое окно NTWindow.

OnWindowRestored() Этот метод используется для вызова любых


пользовательских данных XElement из
рабочей области путем ссылки на окно.

OnWindowSaved() Этот метод используется для сохранения


любых пользовательских данных XElement,
связанных с вашим окном.

StartAtmStrategy() StartAtmStrategy можно использовать для


отправки ордеров на вход со стратегиями
банкоматов.

StrategyBase StrategyBase содержит свойства и методы


для управления объектом стратегии и
является базовым классом, производным от
AtmStrategy.

PropagateInstrumentChange() В NTWindow PropagateInstrumentChange ()


отправляет инструмент в другие окна с тем
же настроенным цветом привязки
инструментов.

PropagateIntervalChange() В NTWindow PropagateIntervalChange ()


отправляет интервал другим окнам с тем же
настроенным цветом Interval Linking.

TabControl Класс TabControl предоставляет


функциональные возможности для работы с
объектами NTTabPage в NTWindow.

TabControlManager Класс TabControlManager можно


использовать для установки или проверки
нескольких свойств объекта TabControl.

Управление NinjaTrader

Следующий раздел содержит элементы управления, которые являются встроенными


элементами управления NinjaTrader. Чтобы полностью интегрировать ваше дополнение в
NinjaTrader, рекомендуется использовать эти элементы управления, а не создавать свои
собственные, когда это возможно.

Примечание. Чтобы очистить эти ресурсы, см. Метод NTTabPage.Cleanup ().

AccountSelector AccountSelector можно использовать как


элемент пользовательского интерфейса, с
которым пользователи могут
взаимодействовать для выбора учетных
записей.

AtmStrategySelector AtmStrategySelector - это элемент


пользовательского интерфейса, с которым
пользователи могут взаимодействовать для
выбора стратегии банкомата.

InstrumentSelector InstrumentSelector - это элемент


пользовательского интерфейса, с которым
пользователи могут взаимодействовать для
выбора инструментов. Это можно
использовать с привязкой инструментов
между окнами.

IntervalSelector IntervalSelector - это элемент


пользовательского интерфейса, с которым
пользователи могут взаимодействовать для
выбора интервалов. Это можно использовать
с интервалом связывания между окнами.

TifSelector TifSelector можно использовать как элемент


пользовательского интерфейса, с которым
пользователи могут взаимодействовать для
выбора TIF.

QuantityUpDown QuantityUpDown можно использовать как


элемент пользовательского интерфейса, с
которым пользователи могут
взаимодействовать для выбора количества.

CleanUp()

Определение
Отменяет регистрацию LinkControls (IInstrumentProvider IIntervalProvider) и вызывает Cleanup ()
для элементов управления ICleanable на NTTabPage. Переопределите это, например, чтобы
отказаться от подписки на события или выполнить любые другие операции очистки, когда
вкладка закрыта.

Примечание. При переопределении Cleanup () настоятельно рекомендуется вызывать


base.Cleanup (), который гарантирует, что любые элементы управления ссылками также будут
отменены. Базовая реализация также будет обрабатывать все элементы управления,
реализующие ICleanable: AccountSelector, AtmStrategySelector, InstrumentSelector,
IntervalSelector, TifSelector.
Возвращаемое значение метода
Этот метод не возвращает значение
Syntax
public override void Cleanup()
{
}
Параметры
Этот метод не принимает никаких параметров
public override void Cleanup()
{
// unregister from any custom events
Connection.ConnectionStatusUpdate -= OnConnectionStatusUpdate;

// вызов base.Cleanup () будет перебирать визуальное дерево в поисках всех дочерних


элементов ICleanable
// то есть AccountSelector, AtmStrategySelector, InstrumentSelector, IntervalSelector,
TifSelector,
// а также отменить регистрацию любых событий управления ссылками
base.Cleanup();
}

AccountSelector

Определение
AccountSelector можно использовать как элемент пользовательского интерфейса, с которым
пользователи могут взаимодействовать для выбора учетных записей.

События и свойства

Cleanup() Удаляет AccountSelector (Примечание:


вызова NTTabPage base.Cleanup ()
достаточно для очистки этого элемента
управления)

SelectedAccount Возвращает учетную запись,


представляющую выбранную учетную запись

SelectionChanged Обработчик событий, когда выбранная


учетная запись была изменена
/ * Пример подписки / отказа от подписки на рыночные данные из надстройки. Концепция
может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private AccountSelector accountSelector

public MyAddOnTab()
{
/// Примечание: pageContent (не показан в этом примере) - это содержимое страницы
XAML
// Находим селектор аккаунта

accountSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "accountSelector") as


AccountSelector;

// Когда выбор селектора учетной записи изменяется, отписываемся и повторно


подписываемся
accountSelector.SelectionChanged += (o, args) =>
{
if (accountSelector.SelectedAccount != null)
{
// Отказ от подписки на любые предыдущие подписки на аккаунт
accountSelector.SelectedAccount.AccountItemUpdate -= OnAccountItemUpdate;
accountSelector.SelectedAccount.ExecutionUpdate -= OnExecutionUpdate;
accountSelector.SelectedAccount.OrderUpdate -= OnOrderUpdate;
accountSelector.SelectedAccount.PositionUpdate -= OnPositionUpdate;

// Подписка на подписку на новую учетную запись


accountSelector.SelectedAccount.AccountItemUpdate += OnAccountItemUpdate;
accountSelector.SelectedAccount.ExecutionUpdate += OnExecutionUpdate;
accountSelector.SelectedAccount.OrderUpdate += OnOrderUpdate;
accountSelector.SelectedAccount.PositionUpdate += OnPositionUpdate;
}
};
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Clean up our resources
base.Cleanup();
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}

XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Tools="clr-namespace:NinjaTrader.Gui.Tools;assembly=NinjaTrader.Gui"
xmlns:AccountPerformance="clr-
namespace:NinjaTrader.Gui.AccountPerformance;assembly=NinjaTrader.Gui"
xmlns:AccountData="clr-namespace:NinjaTrader.Gui.AccountData;assembly=NinjaTrader.Gui"
xmlns:AtmStrategy="clr-
namespace:NinjaTrader.Gui.NinjaScript.AtmStrategy;assembly=NinjaTrader.Gui">

<Grid>
<Tools:AccountSelector x:Name="accountSelector" HorizontalAlignment="Left"
VerticalAlignment="Top"/>
</Grid>

AtmStrategySelector
Определение
AtmStrategySelector - это элемент пользовательского интерфейса, с которым пользователи
могут взаимодействовать для выбора стратегии банкомата.
События и свойства

Cleanup() Удаляет AtmStrategySelector (Примечание:


вызова NTTabPage base.Cleanup ()
достаточно для очистки этого элемента
управления)

CustomPropertiesChanged Обработчик событий при изменении свойств


в стратегии банкомата

Id Строка, определяющая селектор стратегии


банкомата.

SelectedAtmStrategy Возвращает AtmStrategy, представляющую


выбранную стратегию банкомата.

SelectionChanged Обработчик событий при изменении


выбранной стратегии банкомата

Примеры
Этот пример демонстрирует, как использовать селектор стратегии ATM и правильно связать
его поведение с переключателями количества вверх / вниз и TIF.

C#
private QuantityUpDown qudSelector;
private TifSelector tifSelector;
private AtmStrategy.AtmStrategySelector atmStrategySelector;

private DependencyObject LoadXAML()


{
// Примечание: pageContent (не показан в этом примере) - это содержимое страницы
XAML
// Находим селектор количества вверх-вниз

qudSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "qudSelector") as


QuantityUpDown;

// Находим селектор TIF


tifSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "tifSelector") as TifSelector;

// Обязательно привяжите наш селектор учетной записи к нашему селектору TIF, чтобы
обеспечить правильную работу
tifSelector.SetBinding(TifSelector.AccountProperty, new Binding { Source = accountSelector,
Path = new PropertyPath("SelectedAccount") });

// Когда выбор нашего селектора TIF изменяется


tifSelector.SelectionChanged += (o, args) =>
{
// Также меняем выбранный TIF в стратегии банкомата
if (atmStrategySelector.SelectedAtmStrategy != null)
atmStrategySelector.SelectedAtmStrategy.TimeInForce = tifSelector.SelectedTif;
};

// Находим селектор ATM-стратегии и прикрепляем обработчик событий


atmStrategySelector = LogicalTreeHelper.FindLogicalNode(pageContent,
"atmStrategySelector") as AtmStrategy.AtmStrategySelector;
atmStrategySelector.Id = Guid.NewGuid().ToString("N");
if (atmStrategySelector != null)
atmStrategySelector.CustomPropertiesChanged += OnAtmCustomPropertiesChanged;
// Обязательно привяжите наш селектор счетов к нашему селектору стратегии банкомата,
чтобы обеспечить правильную работу
atmStrategySelector.SetBinding(AtmStrategy.AtmStrategySelector.AccountProperty,
new Binding { Source = accountSelector, Path = new PropertyPath("SelectedAccount") });

// Когда выбор нашего селектора банкомата меняется


atmStrategySelector.SelectionChanged += (o, args) =>
{
if (atmStrategySelector.SelectedItem == null)
return;
if (args.AddedItems.Count > 0)
{
// Изменяем выбранный TIF в нашем селекторе TIF тоже
AtmStrategy selectedAtmStrategy = args.AddedItems[0] as AtmStrategy;
if (selectedAtmStrategy != null)
tifSelector.SelectedTif = selectedAtmStrategy.TimeInForce;
}
};
}

private void OnAtmCustomPropertiesChanged(object sender,


NinjaScript.AtmStrategy.CustomPropertiesChangedEventArgs args)
{
// Настраиваем селекторы TIF и Quantity на новые значения стратегии ATM
tifSelector.SelectedTif = args.NewTif;
qudSelector.Value = args.NewQuantity;
}

// ПРИМЕЧАНИЕ: не забудьте очистить ресурсы и отказаться от подписки на события


// Вызывается TabControl, когда вкладка удаляется или окно закрывается

public override void Cleanup()


{
// Очистим наши ресурсы
base.Cleanup();
}

XAML
<AtmStrategy:AtmStrategySelector x:Name="atmStrategySelector" LinkedQuantity="{Binding
ElementName=qudSelector, Path=Value, Mode=OneWay}" Grid.Row="12" Grid.Column="2">
<AtmStrategy:AtmStrategySelector.Margin>
<Thickness Left="{StaticResource MarginButtonLeft}" Top="{StaticResource MarginControl}"
Right="{StaticResource MarginBase}" Bottom="0" />
</AtmStrategy:AtmStrategySelector.Margin>
</AtmStrategy:AtmStrategySelector>

InstrumentSelector

Определение
InstrumentSelector - это элемент пользовательского интерфейса, с которым пользователи могут
взаимодействовать для выбора инструментов. Это можно использовать с привязкой
инструментов между окнами.

События и свойства

Cleanup() Удаляет InstrumentSelector (Примечание:


вызова NTTabPage base.Cleanup ()
достаточно для очистки этого элемента
управления)

Instrument Инструмент, представляющий выбранный


инструмент

InstrumentChanged Обработчик событий, когда инструмент


изменяется на селекторе инструментов

Примеры
Этот пример демонстрирует, как использовать селектор инструментов и правильно связать его
поведение со связью окон.

C#
private InstrumentSelector instrumentSelector;

private DependencyObject LoadXAML()


{
// Примечание: pageContent (не показан в этом примере) - это содержимое страницы
XAML

// Находим селектор инструментов

instrumentSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "instrumentSelector")


as InstrumentSelector;
if (instrumentSelector != null)
instrumentSelector.InstrumentChanged += OnInstrumentChanged;
}

// Этот метод запускается, когда наш селектор инструментов меняет инструменты


private void OnInstrumentChanged(object sender, EventArgs e)
{
Instrument = sender as Cbi.Instrument;
}

/ Член IInstrumentProvider. Требуется, если вы хотите использовать механизм привязки


инструментов в этом окне Add On
public Cbi.Instrument Instrument
{
get { return instrument }
set
{
instrument = value;
if (instrumentSelector != null)
instrumentSelector.Instrument = value;

// Отправляем инструмент в другие окна, связанные с тем же цветом


PropagateInstrumentChange(value);
}
}

/ ПРИМЕЧАНИЕ: не забудьте очистить ресурсы и отказаться от подписки на события


// Вызывается TabControl, когда вкладка удаляется или окно закрывается

public override void Cleanup()


{
// Очистим наши ресурсы
if (instrumentSelector != null)
{
instrumentSelector.InstrumentChanged -= OnInstrumentChanged();
}
base.Cleanup();
}

XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Tools="clr-namespace:NinjaTrader.Gui.Tools;assembly=NinjaTrader.Gui"
xmlns:AccountPerformance="clr-
namespace:NinjaTrader.Gui.AccountPerformance;assembly=NinjaTrader.Gui"
xmlns:AccountData="clr-namespace:NinjaTrader.Gui.AccountData;assembly=NinjaTrader.Gui"
xmlns:AtmStrategy="clr-
namespace:NinjaTrader.Gui.NinjaScript.AtmStrategy;assembly=NinjaTrader.Gui">

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Tools:InstrumentSelector x:Name="instrumentSelector" Grid.Column="0"


LastUsedGroup="MyAddOn"/>
</Grid>

IntervalSelector
Определение
IntervalSelector - это элемент пользовательского интерфейса, с которым пользователи могут
взаимодействовать для выбора интервалов. Это можно использовать с интервалом
связывания между окнами.
События и свойства

Cleanup() Удаляет IntervalSelector (Примечание: вызова


NTTabPage base.Cleanup () достаточно для
очистки этого элемента управления)

Interval BarsPeriod, представляющий текущий


выбранный интервал

IntervalChanged Обработчик событий при изменении


интервала

Примеры
В этом примере показано, как использовать селектор интервала и правильно связать его
поведение с привязкой окон.

C#
private IntervalSelector intervalSelector;

private DependencyObject LoadXAML()


{
// Примечание: pageContent (не показан в этом примере) - это содержимое страницы
XAML

// Находим селектор интервала

intervalSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "intervalSelector") as


IntervalSelector;
if (intervalSelector != null)
intervalSelector.IntervalChanged += OnIntervalChanged;

// Этот метод запускается, когда наш селектор интервалов меняет интервалы


private void OnIntervalChanged(object sender, BarsPeriodEventArgs e)
{
if (e.BarsPeriod == null)
return;
}

/ * Член IIntervalProvider. Обязательно, если вы хотите использовать механизм


интервального компоновщика в этом окне.
В этом примере с компоновщиком интервалов не связаны никакие функции. * /

public BarsPeriod BarsPeriod { get; set; }

// ПРИМЕЧАНИЕ: не забудьте очистить ресурсы и отказаться от подписки на события


// Вызывается TabControl, когда вкладка удаляется или окно закрывается
публичное переопределение void Cleanup ()

{
// Очистим наши ресурсы
if (intervalSelector != null)
intervalSelector.IntervalChanged -= OnIntervalChanged();

base.Cleanup();
}

XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Tools="clr-namespace:NinjaTrader.Gui.Tools;assembly=NinjaTrader.Gui"
xmlns:AccountPerformance="clr-
namespace:NinjaTrader.Gui.AccountPerformance;assembly=NinjaTrader.Gui"
xmlns:AccountData="clr-namespace:NinjaTrader.Gui.AccountData;assembly=NinjaTrader.Gui"
xmlns:AtmStrategy="clr-
namespace:NinjaTrader.Gui.NinjaScript.AtmStrategy;assembly=NinjaTrader.Gui">

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Tools:IntervalSelector x:Name="intervalSelector" Grid.Column="0"


HorizontalAlignment="Left"/>
</Grid>

TifSelector
Определение
TifSelector можно использовать как элемент пользовательского интерфейса, с которым
пользователи могут взаимодействовать для выбора TIF.
События и свойства

Cleanup() Удаляет TifSelector (Примечание: вызова


NTTabPage base.Cleanup () достаточно для
очистки этого элемента управления)

SelectedTif TimeInForce, представляющий выбранный


TIF

Возможные значения:
TimeInForce.Day

TimeInForce.Gtc

TimeInForce.Gtd

TimeInForce.Ioc

TimeInForce.Opg

SelectionChanged Обработчик событий при изменении


выбранной стратегии банкомата

ППримеры
Этот пример демонстрирует, как использовать селектор TIF и правильно связать его поведение
с селекторами количества вверх / вниз и TIF.

C#
private QuantityUpDown qudSelector;
private TifSelector tifSelector;
private AtmStrategy.AtmStrategySelector atmStrategySelector;

private DependencyObject LoadXAML()


{
// Примечание: pageContent (не показан в этом примере) - это содержимое страницы
XAML
// Находим селектор количества вверх-вниз

qudSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "qudSelector") as


QuantityUpDown;

// Находим селектор TIF


tifSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "tifSelector") as TifSelector;

// Обязательно привяжите наш селектор учетной записи к нашему селектору TIF, чтобы
обеспечить правильную работу
tifSelector.SetBinding(TifSelector.AccountProperty, new Binding { Source = accountSelector,
Path = new PropertyPath("SelectedAccount") });

// Когда выбор нашего селектора TIF изменяется


tifSelector.SelectionChanged += (o, args) =>
{
// Также меняем выбранный TIF в стратегии банкомата
if (atmStrategySelector.SelectedAtmStrategy != null)
atmStrategySelector.SelectedAtmStrategy.TimeInForce = tifSelector.SelectedTif;
};

// Находим селектор ATM-стратегии и прикрепляем обработчик событий


atmStrategySelector = LogicalTreeHelper.FindLogicalNode(pageContent,
"atmStrategySelector") as AtmStrategy.AtmStrategySelector;
atmStrategySelector.Id = Guid.NewGuid().ToString("N");
if (atmStrategySelector != null)
atmStrategySelector.CustomPropertiesChanged += OnAtmCustomPropertiesChanged;

// Обязательно привяжите наш селектор счетов к нашему селектору стратегии банкомата,


чтобы обеспечить правильную работу
atmStrategySelector.SetBinding(AtmStrategy.AtmStrategySelector.AccountProperty,
new Binding { Source = accountSelector, Path = new PropertyPath("SelectedAccount") });

// Когда выбор нашего селектора банкомата меняется


atmStrategySelector.SelectionChanged += (o, args) =>
{
if (atmStrategySelector.SelectedItem == null)
return;
if (args.AddedItems.Count > 0)
{
// Change the selected TIF in our TIF selector too
AtmStrategy selectedAtmStrategy = args.AddedItems[0] as AtmStrategy;
if (selectedAtmStrategy != null)
tifSelector.SelectedTif = selectedAtmStrategy.TimeInForce;
}
};

private void OnAtmCustomPropertiesChanged(object sender,


NinjaScript.AtmStrategy.CustomPropertiesChangedEventArgs args)
{
// Adjust our TIF and Quantity selectors to the new ATM strategy values
tifSelector.SelectedTif = args.NewTif;
qudSelector.Value = args.NewQuantity;
}

// NOTE: Don't forget to clean up resources and unsubscribe to events


// Called by TabControl when tab is being removed or window is closed
public override void Cleanup()
{
// Clean up our resources
base.Cleanup();
}

XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Tools="clr-namespace:NinjaTrader.Gui.Tools;assembly=NinjaTrader.Gui"
xmlns:AccountPerformance="clr-
namespace:NinjaTrader.Gui.AccountPerformance;assembly=NinjaTrader.Gui"
xmlns:AccountData="clr-namespace:NinjaTrader.Gui.AccountData;assembly=NinjaTrader.Gui"
xmlns:AtmStrategy="clr-
namespace:NinjaTrader.Gui.NinjaScript.AtmStrategy;assembly=NinjaTrader.Gui">

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Tools:QuantityUpDown x:Name="qudSelector" Value="1" Grid.Column="0"/>


<Tools:TifSelector x:Name="tifSelector" Grid.Column="1"/>
<AtmStrategy:AtmStrategySelector x:Name="atmStrategySelector" LinkedQuantity="{Binding
Value,
ElementName=qudSelector, Mode=OneWay}" Grid.Column="2"/>
</Grid>

QuantityUpDown

Определение
QuantityUpDown можно использовать как элемент пользовательского интерфейса, с которым
пользователи могут взаимодействовать для выбора количества.
События и свойства

Value Тип int, представляющий количество

Примеры

Этот пример демонстрирует, как использовать селектор количества вверх / вниз и правильно
связать его поведение со стратегией ATM и селекторами TIF.
C#
private QuantityUpDown qudSelector;
private TifSelector tifSelector;
private AtmStrategy.AtmStrategySelector atmStrategySelector;

private DependencyObject LoadXAML()


{
// Примечание: pageContent (не показан в этом примере) - это содержимое страницы
XAML
// Находим селектор количества вверх-вниз

qudSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "qudSelector") as


QuantityUpDown;

// Находим селектор TIF


tifSelector = LogicalTreeHelper.FindLogicalNode(pageContent, "tifSelector") as TifSelector;

// Обязательно привяжите наш селектор учетной записи к нашему селектору TIF, чтобы
обеспечить правильную работу
tifSelector.SetBinding(TifSelector.AccountProperty, new Binding { Source = accountSelector,
Path = new PropertyPath("SelectedAccount") });

// Когда выбор нашего селектора TIF изменяется


tifSelector.SelectionChanged += (o, args) =>
{
// Также меняем выбранный TIF в стратегии банкомата
if (atmStrategySelector.SelectedAtmStrategy != null)
atmStrategySelector.SelectedAtmStrategy.TimeInForce = tifSelector.SelectedTif;
};

// Находим селектор ATM-стратегии и прикрепляем обработчик событий


atmStrategySelector = LogicalTreeHelper.FindLogicalNode(pageContent,
"atmStrategySelector") as AtmStrategy.AtmStrategySelector;
atmStrategySelector.Id = Guid.NewGuid().ToString("N");
if (atmStrategySelector != null)
atmStrategySelector.CustomPropertiesChanged += OnAtmCustomPropertiesChanged;

// Обязательно привяжите наш селектор счетов к нашему селектору стратегии банкомата,


чтобы обеспечить правильную работу
atmStrategySelector.SetBinding(AtmStrategy.AtmStrategySelector.AccountProperty,
new Binding { Source = accountSelector, Path = new PropertyPath("SelectedAccount") });
// Когда выбор нашего селектора банкомата меняется
atmStrategySelector.SelectionChanged += (o, args) =>
{
if (atmStrategySelector.SelectedItem == null)
return;
if (args.AddedItems.Count > 0)
{
// Change the selected TIF in our TIF selector too
AtmStrategy selectedAtmStrategy = args.AddedItems[0] as AtmStrategy;
if (selectedAtmStrategy != null)
tifSelector.SelectedTif = selectedAtmStrategy.TimeInForce;
}
};

private void OnAtmCustomPropertiesChanged(object sender,


NinjaScript.AtmStrategy.CustomPropertiesChangedEventArgs args)
{
// Adjust our TIF and Quantity selectors to the new ATM strategy values
tifSelector.SelectedTif = args.NewTif;
qudSelector.Value = args.NewQuantity;
}

// NOTE: Don't forget to clean up resources and unsubscribe to events


// Called by TabControl when tab is being removed or window is closed
public override void Cleanup()
{
// Clean up our resources
base.Cleanup();
}

XAML
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Tools="clr-namespace:NinjaTrader.Gui.Tools;assembly=NinjaTrader.Gui"
xmlns:AccountPerformance="clr-
namespace:NinjaTrader.Gui.AccountPerformance;assembly=NinjaTrader.Gui"
xmlns:AccountData="clr-namespace:NinjaTrader.Gui.AccountData;assembly=NinjaTrader.Gui"
xmlns:AtmStrategy="clr-
namespace:NinjaTrader.Gui.NinjaScript.AtmStrategy;assembly=NinjaTrader.Gui">

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Tools:QuantityUpDown x:Name="qudSelector" Value="1" Grid.Column="0"/>


<Tools:TifSelector x:Name="tifSelector" Grid.Column="1">
<AtmStrategy:AtmStrategySelector x:Name="atmStrategySelector" LinkedQuantity="{Binding
Value,
ElementName=qudSelector, Mode=OneWay}" Grid.Column="2"/>
</Grid>

Account

Определение
Класс Account можно использовать для подписки на события, связанные с учетной
записью, а также для доступа к информации, связанной с учетной записью.

Свойства класса статической учетной записи

All Коллекция объектов Account

AccountStatusUpdate Обработчик событий для обновления статуса


учетной записи

SimulationAccountReset Обработчик событий для сброса на сим-


аккаунтах

ПРИМЕЧАНИЕ: также происходит при


перемотке назад / вперед при
воспроизведении соединений)

Методы и свойства из экземпляров учетной записи

AccountItem Представляет различные переменные


учетной записи, используемые для
отражения значений статуса учетной записи.

AccountItemUpdate Обработчик событий для изменений


значений учетной записи

Cancel() Отменяет указанный (-ые) заказ (-ы) в


учетной записи

CancelAllOrders() Отменяет все заявки на инструмент на счете

Change() Изменяет указанный (-ые) заказ (-ы) в


аккаунте

Connection Соединение, представляющее соединение, с


которым связана эта учетная запись.

CreateOrder() Создает заказы для учетной записи, которые


необходимо отправить через Submit ()

Denomination Валюта, представляющая номинальную


валюту этого соединения.

Executions Коллекция казней на этом счету

ExecutionUpdate Обработчик событий при поступлении новых


исполнений, изменении существующего
выполнения или удалении выполнения.

Flatten() Сглаживает счет по указанным инструментам

Get() Возвращает значение AccountItem.

Name Строка, представляющая имя этой учетной


записи

Orders Сбор заказов на этом аккаунте

OrderUpdate Обработчик событий для изменения заказов

Positions Коллекция позиций на этом счете

PositionUpdate Обработчик событий для изменения позиций

Strategies Сборник стратегий на этом аккаунте

Submit() Отправляет указанный заказ (ы)


Example

private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Находим наш аккаунт Sim101
lock (Account.All)
myAccount = Account.All.FirstOrDefault(a => a.Name == "Sim101");

// Подписка на статические события. Не забудьте отказаться от подписки с


помощью - =, когда закончите
myAccount.AccountStatusUpdate += OnAccountStatusUpdate;

if (myAccount != null)
{
// Распечатываем информацию о нашей учетной записи с помощью
индексатора AccountItem
Print(string.Format("Account Name: {0} Connection Name: {1} Cash Value {2}",
myAccount.Name,
myAccount.Connection.Options.Name,
myAccount.Get(AccountItem.CashValue, Currency.UsDollar)
));

// Распечатываем цены исполнений на нашем счете


lock (myAccount.Executions)
foreach (Execution execution in myAccount.Executions)
Print("Price: " + execution.Price);

// Подпишемся на события. Не забудьте отказаться от подписки с помощью -


=, когда закончите
myAccount.AccountItemUpdate += OnAccountItemUpdate;
myAccount.ExecutionUpdate += OnExecutionUpdate;
}
}
else if (State == State.Terminated)
{
// Отписаться от событий
myAccount.AccountItemUpdate -= OnAccountItemUpdate;
myAccount.ExecutionUpdate -= OnExecutionUpdate;
myAccount.AccountStatusUpdate -= OnAccountStatusUpdate;
}
}

private void OnAccountStatusUpdate(object sender, AccountStatusEventArgs e)


{
/// Что-то делаем с обновлением статуса аккаунта/ Что-то делаем с обновлением
статуса аккаунта
}

private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)


{
/// Что-то делаем с обновлением элемента учетной записи
}

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Что-то делаем с обновлением выполнения
}

All

Определение
Коллекция объектов Account

Стоимость имущества
Коллекция объектов Account

Синтаксис
Счета.Все

Примеры
protected override void OnStateChange()
{
if (State == State.DataLoaded)
{
foreach (Account sampleAccount in Account.All)
Print(String.Format("The account {0} has a {1} unit FX lotsize set", sampleAccount.Name,
sampleAccount.ForexLotSize));
}
}

AccountStatusUpdate
Определение
AccountStatusUpdate можно использовать для подписки на события состояния учетной записи
со всех учетных записей.

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

Синтаксис
AccountStatusUpdate

Examples
/ * Пример подписки / отказа от подписки на события обновления статуса учетной записи из
надстройки. Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /
public class MyAddOnTab : NTTabPage
{
public MyAddOnTab()
{
// Подписка на обновления статуса аккаунта
Account.AccountStatusUpdate += OnAccountStatusUpdate;
}

// Этот метод запускается при любом изменении статуса любой учетной записи
private void OnAccountStatusUpdate(object sender, AccountStatusEventArgs e)
{
// Выводим имя и статус учетной записи
NinjaTrader.Code.Output.Process(string.Format("Account: {0} Status: {1}",
e.Account.Name, e.Status), PrintTo.OutputTab1);
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно отписывайтесь от подписки на статус аккаунта
Account.AccountStatusUpdate -= OnAccountStatusUpdate;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}

SimulationAccountReset
Определение
SimulationAccountReset можно использовать для подписки на события сброса учетной записи
моделирования. Эти сбросы происходят всякий раз, когда пользователь вручную сбрасывает
учетную запись, а также когда пользователь перематывает / перематывает соединение
воспроизведения. Когда сброс происходит из-за изменений в подключении воспроизведения,
важно воссоздать запросы панели.

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

Синтаксис
SimulationAccountRest

Examples

/ * Пример подписки / отказа от подписки на события сброса сим-аккаунта из дополнения.


Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
public MyAddOnTab()
{
// Подписка на сброс сим-аккаунта
Account.SimulationAccountReset += OnSimulationAccountReset;
}

/ * Этот метод запускается при событиях сброса сим-аккаунта. Важно воссоздать запросы
бара
после сброса подключения воспроизведения * /

private void OnSimulationAccountReset(object sender, EventArgs e)


{
Account simAccount = (sender as Account);

// Если учетная запись была сброшена из-за перемотки назад / вперед соединения
воспроизведения
if (simAccount != null && simAccount.Provider == Provider.Playback)
{
// Повторяем запросы наших баров здесь
}
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно откажитесь от подписки на подписку на сброс учетной записи симуляции
Account.SimulationAccountReset -= OnSimulationAccountReset;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}
AccountItem
Определение
Представляет различные переменные учетной записи, используемые для отражения значений
статуса учетной записи. Каждая учетная запись, подключенная к NinjaTrader, будет иметь
собственные уникальные значения AccountItem.
Совет: о стратегиях см. Также OnAccountItemUpdate (). Для других объектов вы также можете
подписаться на поток AccountItemUpdate.

Синтаксис
AccountItem
Parameters

AccountItem.BuyingPower

AccountItem.CashValue

AccountItem.Commission

AccountItem.ExcessIntradayMargin

AccountItem.ExcessInitialMargin

AccountItem.ExcessMaintenanceMargin

AccountItem.ExcessPositionMargin

AccountItem.Fee

AccountItem.GrossRealizedProfitLoss

AccountItem.InitialMargin

AccountItem.IntradayMargin

AccountItem.LongOptionValue

AccountItem.LookAheadMaintenanceMargin

AccountItem.LongStockValue

AccountItem.MaintenanceMargin

AccountItem.NetLiquidation

AccountItem.NetLiquidationByCurrency

AccountItem.PositionMargin

AccountItem.RealizedProfitLoss

AccountItem.ShortOptionValue

AccountItem.ShortStockValue
AccountItem.SodCashValue

AccountItem.SodLiquidatingValue

AccountItem.UnrealizedProfitLoss

AccountItem.TotalCashBalance

AccountItemUpdate
Определение
AccountItemUpdate используется для подписки на события обновления элементов учетной
записи.
Примечание. Не забудьте отказаться от подписки, если вы больше не пользуетесь подпиской.
Синтаксис
AccountItemUpdate

Example

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


из надстройки. Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private Account account;
public MyAddOnTab()
{
// Находим наш аккаунт Sim101
lock (Account.All)
account = Account.All.FirstOrDefault(a => a.Name == "Sim101");

// Подписка на обновления элементов учетной записи


if (account != null)
account.AccountItemUpdate += OnAccountItemUpdate;
}

// Этот метод запускается при любом изменении значения учетной записи


private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)
{
// Выводим запись об учетной записи
NinjaTrader.Code.Output.Process(string.Format("Account: {0} AccountItem: {1} Value: {2}",
e.Account.Name, e.AccountItem, e.Value), PrintTo.OutputTab1);
}
// Вызывается TabControl, когда вкладка удаляется или окно закрывается
public override void Cleanup()
{
// Обязательно откажитесь от подписки на подписку на элемент аккаунта
if (account != null)
account.AccountItemUpdate -= OnAccountItemUpdate;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях.
}

Cancel()

Определение
Отменяет указанные объекты Order.
Синтаксис
Отмена (заказы IEnumerable <Order>)
Параметры

orders Заказ (ы) для отмены

Examples

private Account myAccount;


Order stopOrder = null;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Инициализируем myAccount
}
}

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// // Отменяем стоп-приказ, если исполнение приводит к длинной позиции
if(e.MarketPosition == MarketPosition.Long)
myAccount.Cancel(new[] { stopOrder });
}

CancelAllOrders()

Определение
Отменяет все заказы инструмента.
Синтаксис
CancelAllOrders (инструментальный инструмент)

Parameters

instrument Инструмент отменяемых заказов

Example

private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Инициализируем myAccount
}
}

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Отменить все ордера, если исполнение сработало после 21:00
if (e.Time > new DateTime(now.Year, now.Month, now.Day, 21, 0, 0))
myAccount.CancelAllOrders(e.Execution.Instrument);
}

Change()

Определение
Изменяет указанный объект (ы) Заказа.

Синтаксис
Change(IEnumerable<Order> orders)

Параметры
orders Порядок (а) на изменение

Example

Order stopOrder;
stopOrder.StopPriceChanged = stopOrder.StopPrice - 4 *
stopOrder.Instrument.MasterInstrument.TickSize;

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Изменяем стоп-ордер, если исполнение приводит к длинной позиции
if(e.MarketPosition == MarketPosition.Long)
myAccount.Change(new[] { stopOrder });
}

Connection

Определение
Указывает подключение к данным, используемое для указанной учетной записи.

Стоимость имущества
Экземпляр класса Connection, содержащий информацию о соединении, используемом для
указанной учетной записи.

Синтаксис
<Account>.Connection

Примеры

Examples
private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
myAccount = Account.All.FirstOrDefault(a => a.Name == "Sim101");
}
}

private void OnAccountStatusUpdate(object sender, AccountStatusEventArgs e)


{
Print(String.Format("{0} connection updated", myAccount.Connection.Options.Name));
}

CreateOrder()

Определение
Создает заказ для отправки через Submit ().

Синтаксис
CreateOrder(Instrument instrument, OrderAction action, OrderType orderType, OrderEntry orderEntry,
TimeInForce timeInForce, int quantity, double limitPrice, double stopPrice, string oco, string name,
DateTime gtd, CustomOrder customOrder)

Parameters

инструмент Инструмент заказа

orderAction Possible values:

OrderAction.Buy
OrderAction.BuyToCover
OrderAction.Sell
OrderAction.SellShort

orderType Possible values:

OrderType.Limit
OrderType.Market
OrderType.MIT
OrderType.StopMarket
OrderType.StopLimit

orderEntry Possible values:

OrderEntry.Automated
OrderEntry.Manual

Allows setting the tag for orders submitted


manually or via automated trading logic (CME
tag 1028).

timeInForce Possible values:

TimeInForce.Day
TimeInForce.Gtc
TimeInForce.Gtd
TimeInForce.Ioc
TimeInForce.Opg

quantity Количество заказа

limitPrice Лимитная цена ордера. Используйте «0»,


если этот параметр не имеет отношения к
отправляемому OrderType.

stopPrice Стоп-цена ордера. Используйте «0», если


этот параметр не имеет отношения к
отправляемому OrderType.

oco Строка, представляющая идентификатор


ОСО, используемый для связывания заказов
ОСО вместе.

name Строка, представляющая название заказа.


Не более 50 символов.

Примечание. При использовании стратегии


ATM StartAtmStrategy () это значение
ДОЛЖНО быть "Entry".

gtd Значение DateTime, которое будет


использоваться с TimeInForce.Gtd - для всех
остальных случаев вы можете передать
Core.Globals.MaxDate

customOrder Индивидуальный заказ, если он используется

Examples

Order stopOrder;
stopOrder = myAccount.CreateOrder(myInstrument, OrderAction.Sell, OrderType.StopMarket,
OrderEntry.Automated, TimeInForce.Day, 1, 0, 1400, "myOCO", "stopOrder",
Core.Globals.MaxDate, null);

myAccount.Submit(new[] { stopOrder });

Denomination

Определение
Указывает валюту, установленную на счете

Стоимость имущества
Объект Currency, содержащий информацию о деноминации валюты, указанной в указанной
учетной записи.
<Account>.Connection

Examples

private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Инициализируем myAccount здесь

// Распечатать номинал валюты myAccount

NinjaTrader.Code.Output.Process("myAccount currency is set to " + myAccount.Denomination,


PrintTo.OutputTab1);
}
}

Executions

Определение
Коллекция объектов Execution, созданных для указанной учетной записи. Это текущие
выполнения сеансов, которые должны соответствовать запускам, указанным на вкладке
«Выполнения» окна «Данные учетной записи NinjaTrader».

Стоимость имущества
Коллекция объектов Execution

Syntax
<Account>.Executions
Примечание. В настоящее время не существует поддерживаемого метода для получения
истории выполнения из локальной базы данных.

Examples

private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Initialize myAccount
}
}

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
foreach (Execution execution in myAccount.Executions)
{
Print(String.Format("Execution triggered for Order {0}", execution.Order));
}
}

ExecutionUpdate
Определение
ExecutionUpdate используется для подписки на события обновления выполнения.
Примечание. Не забудьте отказаться от подписки, если вы больше не пользуетесь подпиской.

Syntax
ExecutionUpdate
Examples

/* Пример подписки / отказа от подписки на события обновления выполнения из надстройки.


Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private Account account;
public MyAddOnTab()
{
// Find our Sim101 account
lock (Account.All)
account = Account.All.FirstOrDefault(a => a.Name == "Sim101");

// Subscribe to execution updates


if (account != null)
account.ExecutionUpdate += OnExecutionUpdate;
}

/ * Этот метод запускается при поступлении новых исполнений, в существующее


исполнение вносятся поправки
(например, бэк-офисом брокера) или исполнение удалено (например, бэк-офисом
брокера) * /

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Output the execution
NinjaTrader.Code.Output.Process(string.Format("Instrument: {0} Quantity: {1} Price: {2}",
e.Execution.Instrument.FullName, e.Quantity, e.Price), PrintTo.OutputTab1);
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно откажитесь от подписки на выполнение подписки
if (account != null)
account.ExecutionUpdate -= OnExecutionUpdate;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}

Flatten()

Определение
Сглаживает счет на инструменте.

Синтаксис
Flatten(ICollection<Instrument> instruments)

Parameters

instruments сбор инструментов для отмены ордеров и


закрытия позиций

Examples
Сгладить один инструмент
Account.Flatten(new [] { Instrument.GetInstrument("ES 12-15") });

Flatten a list of instruments


// Обратите внимание, что в разделе «Использование объявлений» необходимо
//
// используя System.Collections.ObjectModel;
//
// добавлен для корректной компиляции этого примера

// создаем список инструментов

Collection<Cbi.Instrument> instrumentsToClose = new Collection<Instrument>();

// add instruments to the collection


instrumentsToClose.Add(Instrument.GetInstrument("AAPL"));
instrumentsToClose.Add(Instrument.GetInstrument("MSFT"));

// передать коллекцию инструментов методу Flatten () для сглаживания


Account.Flatten(instrumentsToClose);

Get()

Определение
Возвращает значение AccountItem, например BuyingPower, CashValue и т. Д.
Возвращаемое значение метода
double, представляющее значение запрошенного AccountItem.

Syntax
Get(AccountItem itemType, Cbi.Currency currency)
Parameters

itemType Желаемый AccountItem для возврата

Currency Валюту счета, в которой должно быть


указано значение (обязательный параметр,
но не влияет на возвращаемое значение)

Examples

// Оценивает, есть ли в аккаунте более 25000 долларов


if (Account.Get(AccountItem.CashValue, Currency.UsDollar) > 25000)
{
/// Сделай что-нибудь;
}

Name

Определение
Указывает имя указанной учетной записи

Стоимость имущества
Строка, представляющая имя учетной записи.
Syntax
<Account>.Name

Example
private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Инициализируем myAccount
}
}

private void OnAccountStatusUpdate(object sender, AccountStatusEventArgs e)


{
// Выводим имя каждой обновленной учетной записи
Print(String.Format("{0} account updated", myAccount.Name));
}

Orders

Определение
Коллекция объектов Order, созданная для указанной учетной записи.

Стоимость имущества
Коллекция объектов Order

Примечание. Имейте в виду, что заказы, размещенные в State.Historical, не отправляются в


аккаунт в реальном времени.

Syntax
<Account>.Orders
Examples
private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Инициализируем myAccount
}
}

private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)


{
// Выводим название и действие по каждому заказу, обработанному в аккаунте.
foreach (Order order in myAccount.Orders)
{
Print(String.Format("Order placed: {0} - {1}", order.Name, order.OrderAction));
}
}

OrderUpdate
Определение
OrderUpdate можно использовать для подписки на события обновления заказа.

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

Синтаксис
Заказать обновление
Examples
/ * Пример подписки / отказа от подписки на события обновления заказа из надстройки.
Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private Account account;
private Order myEntryOrder;
private Order profitTarget;
private Order stopLoss;

public MyAddOnTab()
{
// Find our Sim101 account
lock (Account.All)
account = Account.All.FirstOrDefault(a => a.Name == "Sim101");

// Подписка на обновления заказа


if (account != null)
account.OrderUpdate += OnOrderUpdate;
}

// Этот метод запускается при изменении статуса заказа


private void OnOrderUpdate(object sender, OrderEventArgs e)
{
// Отправляем стоп-ордера / целевую скобку
if (myEntryOrder != null && myEntryOrder == e.Order)
{
if (e.OrderState == OrderState.Filled)
{
string oco = Guid.NewGuid().ToString("N");

profitTarget = account.CreateOrder(e.Order.Instrument, OrderAction.Sell,


OrderType.Limit, OrderEntry.Manual, TimeInForce.Day,
e.Quantity, e.AverageFillPrice + 10 * e.Order.Instrument.MasterInstrument.TickSize,
0, oco, "Profit Target", Core.Globals.MaxDate, null);
stopLoss = account.CreateOrder(e.Order.Instrument, OrderAction.Sell,
OrderType.StopMarket, OrderEntry.Manual, TimeInForce.Day,
e.Quantity, 0, e.AverageFillPrice - 10 *
e.Order.Instrument.MasterInstrument.TickSize, oco, "Stop Loss", Core.Globals.MaxDate, null);
account.Submit(new[] { profitTarget, stopLoss });
}
}
}

// Called by TabControl when tab is being removed or window is closed


public override void Cleanup()
{
// Make sure to unsubscribe to the orders subscription
if (account != null)
account.OrderUpdate -= OnOrderUpdate;
}

// Other required NTTabPage members left out for demonstration purposes. Be sure to add them
in your own code.
}

Positions
Определение
Коллекция объектов Position, созданных для указанной учетной записи.

Стоимость имущества

Коллекция объектов Position

Синтаксис
Account.Positions
<Account>.Positions
Examples
private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Find our Sim101 account
lock (Account.All)
myAccount = Account.All.FirstOrDefault(a => a.Name == "Sim101");
}

if (State == State.DataLoaded)
{
lock (myAccount.Positions)
{
Print("Positions in State.DataLoaded:");

foreach (Position position in myAccount.Positions)


{
Print(String.Format("Position: {0} at {1}", position.MarketPosition,
position.AveragePrice));
}
}
}
}

PositionUpdate
Определение
PositionUpdate может использоваться для подписки на события обновления позиции.

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

Синтаксис
PositionUpdate

Examples
/ * Пример подписки / отказа от подписки на события обновления позиции из надстройки.
Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private Account account;
public MyAddOnTab()
{
// Find our Sim101 account
lock (Account.All)
account = Account.All.FirstOrDefault(a => a.Name == "Sim101");

// Подпишемся на обновления позиции


if (account != null)
account.PositionUpdate += OnPositionUpdate;
}

// Этот метод запускается при изменении позиции


private void OnPositionUpdate(object sender, PositionEventArgs e)
{
// Выводим новую позицию
NinjaTrader.Code.Output.Process(string.Format("Instrument: {0} MarketPosition: {1}
AveragePrice: {2} Quantity: {3}",
e.Position.Instrument.FullName, e.MarketPosition, e.AveragePrice, e.Quantity),
PrintTo.OutputTab1);
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно отписываемся от подписки на позиции
if (account != null)
account.PositionUpdate -= OnPositionUpdate;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных целях.


Обязательно добавьте их в свой код.
}
Совет: базовая рыночная позиция e.Position считается плоской, когда отображается
Operation.Remove, поэтому следует учитывать любое связанное отслеживание в вашей
логике, которое вы хотите активировать или обновить. Операция Operation.Update была
бы видна, если бы между ними не было плоского состояния, то есть на обратной
стороне позиции.

Strategies
Определение
Коллекция объектов StrategyBase, созданных для указанной учетной записи.

Стоимость имущества
Коллекция объектов StrategyBase

Syntax
<Account>.Strategies

Examples

private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Initialize myAccount
}
}

private void OnAccountStatusUpdate(object sender, AccountStatusEventArgs e)


{
foreach (StrategyBase strategy in myAccount.Strategies)
{
Print(String.Format("Account status updated. {0} strategy applied with position {1}",
strategy.Name, strategy.Position));
}
}

Submit()
Определение
Отправляет указанный объект (ы) Order.
Syntax
Submit(IEnumerable<Order> orders)
Parameters

orders Order(s) to submit

Examples

Order stopOrder = null;


stopOrder = myAccount.CreateOrder(myInstrument, OrderAction.Sell, OrderType.StopMarket,
TimeInForce.Day, 1, 0, 1400, "myOCO", "stopOrder", null);

myAccount.Submit(new[] { stopOrder });

Example
private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Find our Sim101 account
lock (Account.All)
myAccount = Account.All.FirstOrDefault(a => a.Name == "Sim101");

// Подписка на статические события. Не забудьте отказаться от подписки с помощью - =,


когда закончите
myAccount.AccountStatusUpdate += OnAccountStatusUpdate;

if (myAccount != null)
{
// Распечатываем информацию о нашей учетной записи с помощью индексатора
AccountItem
Print(string.Format("Account Name: {0} Connection Name: {1} Cash Value {2}",
myAccount.Name,
myAccount.Connection.Options.Name,
myAccount.Get(AccountItem.CashValue, Currency.UsDollar)
));

// Распечатываем цены исполнений на нашем счете


lock (myAccount.Executions)
foreach (Execution execution in myAccount.Executions)
Print("Price: " + execution.Price);

// Подпишемся на события. Не забудьте отказаться от подписки с помощью - =,


когда закончите
myAccount.AccountItemUpdate += OnAccountItemUpdate;
myAccount.ExecutionUpdate += OnExecutionUpdate;
}
}
else if (State == State.Terminated)
{
// Отписаться от событий
myAccount.AccountItemUpdate -= OnAccountItemUpdate;
myAccount.ExecutionUpdate -= OnExecutionUpdate;
myAccount.AccountStatusUpdate -= OnAccountStatusUpdate;
}
}
private void OnAccountStatusUpdate(object sender, AccountStatusEventArgs e)
{
// Что-то делаем с обновлением статуса аккаунта
}

private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)


{
// Что-то делаем с обновлением элемента учетной записи
}

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Что-то делаем с обновлением выполнения
}

BarsRequest

Определение
BarsRequest можно использовать для запроса данных Bars и подписки на события данных Bars
в реальном времени.

Заметки:

1. При использовании параметров DateTime fromLocal и toLocal даты преобразуются в местные


ежедневные метки времени (12:00 AM) и возвращают BarsRequest, представляющий полные
торговые дни. Если вам нужно запросить менее одного полного торгового дня, используйте
параметр barsBack

2. BarsRequest следует вызывать только один раз и подписываться на событие .Update. Не


забудьте отказаться от подписки на обработчик событий .Update, если вы больше не
используете подписку.

3. BarsRequest предоставляет базовые рыночные данные для инструмента, но не


синхронизируется с серией первичных данных индикатора или стратегии. Вам нужно будет
реализовать собственную логику BarsUpdateEvent.

4. данные BarsRequest НЕ МОГУТ использоваться в качестве входных данных для индикатора


NinjaTrader.

5. Выполнение BarsRequest при воспроизведении всегда будет давать полосы до текущего


времени воспроизведения / положения ползунка.
6. Задокументированное поведение BarsRequest будет одинаковым для всех типов NinjaScript.

Syntax
BarsRequest(Cbi.Instrument instrument, int barsBack)
BarsRequest(Cbi.Instrument instrument, DateTime fromLocal, DateTime toLocal)

Parameters

Instrument Инструмент для запроса

barsBack Значение типа int, определяющее количество


запрашиваемых баров с текущего времени.

fromLocal Значение DateTime, определяющее


начальную дату для запроса

toLocal Значение DateTime, определяющее конечную


дату для запроса

Методы и свойства

Bars Объект Bars, возвращенный из запроса

BarsBack Тип int, представляющий количество баров,


использованных в запросе.

BarsPeriod BarsPeriod для запроса баров

FromLocal DateTime, представляющий начальную дату,


используемую в запросе

IsDividendAdjusted Логическое значение, указывающее, будет ли


запрос баров скорректирован по дивидендам.

IsResetOnNewTradingDay Логическое значение, указывающее,


прервется ли запрос баров в EOD.

IsSplitAdjusted Логическое значение, показывающее, будет


ли запрос на разделение баров
скорректирован

Instrument Инструмент запроса баров

LookupPolicy Политики поиска для запроса баров.


Возможные значения:

• Провайдер - запрашивает провайдера.


Репозиторий обновляется по ответу
провайдера

• Репозиторий - поиск только в локальном


репозитории.
MergePolicy Политика слияния для запроса баров.

Request() Запрашивает столбцы как


параметризованные

TradingHours Часы торговли для запроса баров

ToLocal DateTime, представляющий дату окончания,


используемую в запросе

Update Обработчик BarsUpdateEvent для подписки /


отказа от подписки на события обновления
бара

Examples

/ * Пример подписки / отказа от подписки на события данных баров из надстройки, а также


выполнение запросов баров.
Эту концепцию можно перенести на любой объект NinjaScript, над которым вы, возможно,
работаете. * /

public class MyAddOnTab : NTTabPage


{
private int daysBack = 5;
private bool barsRequestSubscribed = false;
private BarsRequest barsRequest;

public MyAddOnTab()
{
// создаем новый запрос баров. Это определит инструмент и диапазон запрашиваемых
баров.
barsRequest = new BarsRequest(Cbi.Instrument.GetInstrument("AAPL"),
DateTime.Now.AddDays(-daysBack), DateTime.Now);

// Параметризуем ваш запрос.


barsRequest.BarsPeriod = new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 1
};
barsRequest.TradingHours = TradingHours.Get("Default 24 x 7");

// Присоединяем обработчик событий для событий в реальном времени, если вы хотите


обрабатывать данные в реальном времени
barsRequest.Update += OnBarUpdate;

// Запрашиваем бары
barsRequest.Request(new Action<BarsRequest, ErrorCode, string>((bars, errorCode,
errorMessage) =>
{
if (errorCode != ErrorCode.NoError)
{
// Здесь обрабатываются ошибки при запросе баров
NinjaTrader.Code.Output.Process(string.Format("Error on requesting bars: {0}, {1}",
errorCode, errorMessage), PrintTo.OutputTab1);
return;
}

// Вывод запрошенных нами баров. Примечание. Последняя возвращенная полоса может


быть полоской, которая в данный момент выполняется.
for (int i = 0; i < bars.Bars.Count; i++)
{
// Выводим бары
NinjaTrader.Code.Output.Process(string.Format("Time: {0} Open: {1} High: {2} Low: {3} Close:
{4} Volume: {5}",
bars.Bars.GetTime(i),
bars.Bars.GetOpen(i),
bars.Bars.GetHigh(i),
bars.Bars.GetLow(i),
bars.Bars.GetClose(i),
bars.Bars.GetVolume(i)), PrintTo.OutputTab1);
}

// Если запрашиваются бары реального времени, но в данный момент нет подключений


lock (Connection.Connections)
if (Connection.Connections.FirstOrDefault() == null)
NinjaTrader.Code.Output.Process("Real-Time Bars: Not connected.", PrintTo.OutputTab1);
}));
}

// Этот метод запускается для событий бара в реальном времени


private void OnBarUpdate(object sender, BarsUpdateEventArgs e)
{
/ * В зависимости от типа BarsPeriod вашего barsRequest могут возникать ситуации, когда
более одного бара
обновляется одним тиком. Обязательно обработайте весь диапазон обновленных
столбцов, чтобы не пропустить ни одного. * /

// Выводим информацию о баре на каждом тике


for (int i = e.MinIndex; i <= e.MaxIndex; i++)
{
// Обработка каждого тика
NinjaTrader.Code.Output.Process(string.Format("Time: {0} Open: {1} High: {2} Low: {3} Close:
{4}",
e.BarsSeries.GetTime(i),
e.BarsSeries.GetOpen(i),
e.BarsSeries.GetHigh(i),
e.BarsSeries.GetLow(i),
e.BarsSeries.GetClose(i)), PrintTo.OutputTab1);
}
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно откажитесь от подписки на подписку на запросы баров
if (barsRequest != null)
{
barsRequest.Update -= OnBarUpdate;
barsRequest.Dispose();
barsRequest = null;
}
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных целях.


Обязательно добавьте их в свой код.
}

Syntax
MergePolicy
Example

// запрашиваем последние 365 однодневных баров


BarsRequest useGlobalRequest = new BarsRequest(Instrument.GetInstrument("ES 09-16"), 365);
useGlobalRequest.BarsPeriod = new BarsPeriod { BarsPeriodType = BarsPeriodType.Day, Value =
1 };

// использовать политику слияния, которую пользователь настроил как глобальную настройку


useGlobalRequest.MergePolicy = MergePolicy.UseGlobalSettings;
useGlobalRequest.Request(new Action<BarsRequest, ErrorCode, string>((barsRequest, errorCode,
errorMessage) =>{

Print("bars returned=" + barsRequest.Bars.Count);

}));

// избавляемся от запроса баров, если мы закончили с ним


useGlobalRequest.Dispose();

MergePolicy

Определение
Определяет политику слияния запроса баров.
Заметки:

• Это свойство применимо ТОЛЬКО к фьючерсным контрактам.

• Общую информацию по обновлению политик слияния можно найти в разделе «Конфигурация


рыночных данных».

• Информацию о политике слияния, настроенной в инструментах, см. В свойстве


MasterInstrument.MergePolicy.

Стоимость имущества
Представляет MergePolicy, используемый для запроса столбцов.

Возможные значения:

DoNotMerge Политика слияния не применяется

MergeBackAdjusted Политика слияния применяется между


контрактами вместе со смещениями
пролонгации

MergeNonBackAdjusted Политика слияния применяется между


контрактами без взаимозачетов

UseGlobalSettings Использует значение, настроенное в меню


Инструменты -> Параметры -> Рыночные
данные.

UseDefault Использует значения по умолчанию,


настроенные для MasterInstrument

Syntax
MergePolicy
Example

// запрашиваем последние 365 однодневных баров


BarsRequest useGlobalRequest = new BarsRequest(Instrument.GetInstrument("ES 09-16"), 365);
useGlobalRequest.BarsPeriod = new BarsPeriod { BarsPeriodType = BarsPeriodType.Day, Value =
1 };

// использовать политику слияния, которую пользователь настроил как глобальную настройку


useGlobalRequest.MergePolicy = MergePolicy.UseGlobalSettings;
useGlobalRequest.Request(new Action<BarsRequest, ErrorCode, string>((barsRequest, errorCode,
errorMessage) =>{

Print("bars returned=" + barsRequest.Bars.Count);

}));

// избавляемся от запроса баров, если мы закончили с ним


useGlobalRequest.Dispose();

Request()

Определение
Выполняет запрос баров для объекта BarsRequest

Syntax
BarsRequest.Request(Action<BarsRequest, ErrorCode, string> callback)
Properties

BarsRequest BarsRequest, представляющий полосы

ErrorCode Код ошибки, представляющий состояние


ошибки

string Строка, представляющая сообщение об


ошибке

Example
// Запрашиваем бары
barsRequest.Request(new Action<BarsRequest, ErrorCode, string>((bars, errorCode,
errorMessage) =>
{
if (errorCode != ErrorCode.NoError)
{
// Здесь обрабатываются ошибки при запросе баров
NinjaTrader.Code.Output.Process(string.Format("Error on requesting bars: {0}, {1}",
errorCode, errorMessage), PrintTo.OutputTab1);
return;
}

// Здесь что-то делаем с возвращенными барами.


for (int i = 0; i < bars.Bars.Count; i++)
{
// Выводим бары
NinjaTrader.Code.Output.Process(string.Format("Time: {1} Open: {2} High: {3} Low: {4}
Close: {5} Volume: {6}",
bars.Bars.GetTime(i),
bars.Bars.GetOpen(i),
bars.Bars.GetHigh(i),
bars.Bars.GetLow(i),
bars.Bars.GetClose(i),
bars.Bars.GetVolume(i)), PrintTo.OutputTab1);
}
}));

Connection (Связь)
Определение
Класс Connection можно использовать для отслеживания событий, связанных с подключением,
а также для доступа к информации, связанной с подключением.

События и свойства класса статического соединения

CancelAllOrders() Отменяет все заказы

Connect() Подключается к соединению

ConnectionStatusUpdate Обработчик событий для обновления статуса


подключения

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


Accounts Список аккаунтов из подключения

Disconnect() Отключается от соединения

Options Варианты конфигурации подключения

PriceStatus ConnectionStatus, представляющий состояние


ленты цен. Возможные значения:

ConnectionStatus.Connected

ConnectionStatus.Connecting
ConnectionStatus.ConnectionLost

Состояние подключения.

ConnectionStatus.Disconnected

Status ConnectionStatus, представляющий статус


фида заказа. Возможные значения:

ConnectionStatus.Connected

ConnectionStatus.Connecting
ConnectionStatus.ConnectionLost

Состояние подключения.

ConnectionStatus.Disconnected

Example

// Пример доступа к информации обо всех подключенных подключениях


public class MyAddOnTab : NTTabPage
{
public MyAddOnTab()
{
// Распечатать информацию обо всех подключенных подключениях
lock (Connection.Connections)
foreach(Connection c in Connection.Connections)
NinjaTrader.Code.Output.Process(string.Format("Connection: {0} Provider: {1}",
c.Options.Name, c.Options.Provider), PrintTo.OutputTab1);

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}
}

CancelAllOrders()
Definition
Cancels all orders for the specified instrument on the connection.
Syntax
<Connection>.CancelAllOrders(Instrument instrument)

instrument Объект Instrument, используемый для


идентификации инструмента, по которому
отменяются заказы.
Example

private Account myAccount;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Initialize myAccount
}
}

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Cancel all orders if an execution is triggered after 9pm
if (e.Time > new DateTime(now.Year, now.Month, now.Day, 21, 0, 0))
myAccount.CancelAllOrders(e.Execution.Instrument);
}

Connect()

Определение
Подключается к соединению.
Syntax
Connection.Connect(ConnectOptions options)
Parameters

options Вариант подключения того, к чему вы хотите


подключиться
Example
/ * Пример подписки / отказа от подписки на события обновления выполнения из надстройки.
Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private Connection connection;
public MyAddOnTab()
{
// Подключение к Kinetick EOD
if (connection == null)
connection = Connect("Kinetick - End Of Day (Free)");
}

private Connection Connect(string connectionName)


{
// Вывод выполнения
try
{
// Получаем настроенное подключение к аккаунту
ConnectOptions connectOptions = null;
lock (Core.Globals.ConnectOptions)
connectOptions = Core.Globals.ConnectOptions.FirstOrDefault(o => o.Name ==
connectionName);

if (connectOptions == null)
{
NinjaTrader.Code.Output.Process("Could not connect. No connection found.",
PrintTo.OutputTab1);
return null;
}

// Если соединение еще не установлено, подключаемся.


lock (Connection.Connections)
if (Connection.Connections.FirstOrDefault(c => c.Options.Name == connectionName) ==
null)
{
Connection connect = Connection.Connect(connectOptions);

// Возвращаем соединение только в случае успешного соединения


if (connect.Status == ConnectionStatus.Connected)
return connect;
else
return null;
}

return null;
}
catch (Exception error)
{
NinjaTrader.Code.Output.Process("Connect exception: " + error.ToString(),
PrintTo.OutputTab1);
return null;
}
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Отключаемся от нашего соединения
if (connection != null)
connection.Disconnect();
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных целях.


Обязательно добавьте их в свой код.
}

ConnectionStatusUpdate
Определение
ConnectionStatusUpdate можно использовать для подписки на события обновления статуса
подключения.

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

Syntax
ConnectionStatusUpdate
Example
/ * Пример подписки / отказа от подписки на события обновления соединения из надстройки.
Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private Connection connection;
public MyAddOnTab()
{
// Подписка на обновления подключения
Connection.ConnectionStatusUpdate += OnConnectionStatusUpdate;
}

// Этот метод запускается при событиях обновления статуса подключения


private void OnConnectionStatusUpdate(object sender, ConnectionStatusEventArgs e)
{
/ * По причинам многопоточности работаем с копией ConnectionStatusEventArgs для
предотвращения ситуаций
где ConnectionStatusEventArgs уже может опережать нас, пока обрабатывает его в
середине. * /

ConnectionStatusEventArgs eCopy = e;

// Если соединение Kinetic ROD прерывается, что-то делаем


if (eCopy.Connection.Options.Name == "Kinetick - End Of Day (Free)")
{
if (eCopy.Status == ConnectionStatus.Disconnected)
// Сделай что-нибудь
}
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно отписывайтесь от подписки на статус подключения
Connection.ConnectionStatusUpdate -= OnConnectionStatusUpdate;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных целях.


Обязательно добавьте их в свой код.
}

Disconnect()(Отключить())
Определение
Отключается от передачи данных.
Syntax
<Connection>.Disconnect()
Example

private void OnExecutionUpdate(object sender, ExecutionEventArgs e)


{
// Если выполнение срабатывает после 21:00, отключимся от источника данных учетной
записи
if (e.Time > new DateTime(now.Year, now.Month, now.Day, 21, 0, 0))
myAccount.Connection.Disconnect();
}

Options
Definition
The connection's configuration options
Properties

ConnectOnStartup bool , указывающее, подключается ли это


соединение автоматически при запуске.

Name A string representing the connection's name

Provider Провайдер, представляющий провайдера


подключения

Example

// Пример доступа к информации обо всех подключенных подключениях


public class MyAddOnTab : NTTabPage
{
public MyAddOnTab()
{
// Распечатать информацию обо всех подключенных подключениях
lock (Connection.Connections)
Connection.Connections.ToList().ForEach(c =>
NinjaTrader.Code.Output.Process(string.Format("Connection: {0}
Provider: {1}", c.Options.Name, c.Options.Provider), PrintTo.OutputTab1);
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных целях.


Обязательно добавьте их в свой код.
}
PriceStatus
Определение
Указывает текущий статус потока цен основного подключения к данным.
Syntax
<Connection>.PriceStatus
Example

private int priceLost;


private int mainLost;

private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)


{
// Подсчитываем количество вызовов OnAccountItemUpdate () с потерянным
ценовым соединением
if (myAccount.Connection.PriceStatus == ConnectionStatus.ConnectionLost)
priceLost += 1;

// Подсчитываем количество вызовов OnAccountItemUpdate () с потерянным


основным соединением
if (myAccount.Connection.Status == ConnectionStatus.ConnectionLost)
mainLost += 1;

// Выводим количество раз, когда каждое соединение было потеряно во время


OnAccountItemUpdate ()
if (mainLost > 0 || priceLost > 0)
Print(String.Format("Main connection lost {0} times. Price feed lost {1} times.",
mainLost, priceLost));
}

Status
Definition
Indicates the current status of the primary data connection.
Properties
<Connection>.Status
Example
private int priceLost;
private int mainLost;

private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)


{
// Подсчитываем количество вызовов OnAccountItemUpdate () с потерянным
ценовым соединением
if (myAccount.Connection.PriceStatus == ConnectionStatus.ConnectionLost)
priceLost += 1;

// Подсчитываем количество необходимого OnAccountItemUpdate () с потерянным


основным соединением
if (myAccount.Connection.Status == ConnectionStatus.ConnectionLost)
mainLost += 1;

// Выводим количество раз, когда каждое соединение было потеряно во время


OnAccountItemUpdate ()
if (mainLost > 0 || priceLost > 0)
Print(String.Format("Main connection lost {0} times. Price feed lost {1} times.",
mainLost, priceLost));
}

IInstrumentProvider Interface(Интерфейс
IInstrumentProvider)

Если при создании NTTabPage вы хотите использовать ссылку на инструмент,


обязательно реализуйте интерфейс IInstrumentProvider.

Examples
public class MyWindowTabPage : NTTabPage, IInstrumentProvider
{
private Instrument instrument;

public MyWindowTabPage()
{
/ * Определяем содержимое для нашей NTTabPage. Мы можем загрузить
свободный XAML для определения элементов управления и макетов
если мы так выберем и здесь.

Примечание. XAML с обработчиками событий, определенными внутри, БУДЕТ


НЕУДАЧНЫМ при попытке загрузки.
Примечание. XAML со "встроенным кодом" БУДЕТ НЕУДАЧНЫМ при попытке
загрузки * /

// Член IInstrumentProvider
public Instrument Instrument
{
get { return instrument; }
set
{
if (instrument != null)
{
// Отказ от подписки на ранее выбранный инструмент
}

if (value != null)
{
// Создаем подписки для вновь выбранного инструмента
}

instrument = value;

// Отправляем инструмент в другие окна, связанные с тем же цветом


PropagateInstrumentChange(value);

// Обновляем название заголовка вкладки


RefreshHeader();
}
}
// Не забудьте также включить все необходимые члены NTTabPage
}

Instrument
Для правильной работы привязки инструментов в вашем аддоне необходимо создать
инструмент.
Examples

// Член IInstrumentProvider
public Instrument Instrument
{
get { return instrument; }
set
{
if (instrument != null)
{
// Отказ от подписки на ранее выбранный инструмент
}

if (value != null)
{
// Создаем подписки для вновь выбранного инструмента
}

instrument = value;

// Отправляем инструмент в другие окна, связанные с тем же цветом


PropagateInstrumentChange(value);

// Обновляем название заголовка вкладки


RefreshHeader();
}
}

IIntervalProvider Interface
Если при создании NTTabPage вы хотите использовать интервальную ссылку, обязательно
реализуйте интерфейс IIntervalProvider.

Examples
public class MyWindowTabPage : NTTabPage, IIntervalProvider
{
public MyWindowTabPage()
{
/ * Определяем содержимое для нашей NTTabPage. Мы можем загрузить свободный
XAML для определения элементов управления и макетов
если мы так выберем и здесь.

Примечание. XAML с обработчиками событий, определенными внутри, БУДЕТ


НЕУДАЧНЫМ при попытке загрузки.
Примечание. XAML со "встроенным кодом" БУДЕТ НЕУДАЧНЫМ при попытке загрузки
*/

// Член IIntervalProvider
public BarsPeriod BarsPeriod { get; set; }

// Не забудьте также включить все необходимые члены NTTabPage


}

BarsPeriod
Для правильной работы интервальной привязки в вашем Add On необходимо создать
BarsPeriod.
Examples

// Член IIntervalProvider
public BarsPeriod BarsPeriod { get; set; }

INTTabFactory Interface

Если вы хотите иметь функциональные возможности страницы вкладок, такие как


добавление, удаление, перемещение, дублирование вкладок, вы должны создать класс,
реализующий интерфейс INTTabFactory.

Этот интерфейс содержит два метода, которые необходимо скрыть:

NTWindow CreateParentWindow();
NTTabPage CreateTabPage(string typeName, bool isNewWindow = false);
Examples
public class MyWindowFactory : INTTabFactory
{
// Член INTTabFactory. Создает родительское окно, содержащее вкладки
public NTWindow CreateParentWindow()
{
return new MyWindow();
}

// Член INTTabFactory. Создает новые страницы вкладок всякий раз, когда


пользователь нажимает кнопку +
public NTTabPage CreateTabPage(string typeName)
{
return new MyWindowTabPage();
}
}

CreateParentWindow()
Это определяет, какое NTWindow будет создано в качестве родительского окна для нашего Add
On.
Examples

// Член INTTabFactory. Создает родительское окно, содержащее вкладки


public NTWindow CreateParentWindow()
{
return new MyWindow();
}

CreateTabPage()
Это определяет, какая NTTabPage создается всякий раз, когда требуется новая вкладка в
нашем родительском окне для нашего Add On.

Examples

// Член INTTabFactory. Создает новые страницы вкладок всякий раз, когда пользователь
нажимает кнопку +
public NTTabPage CreateTabPage(string typeName, bool isNewWindow = false)
{
return new MyWindowTabPage();
}

IWorkspacePersistence Interface

При создании NTWindow обязательно реализуйте интерфейс IWorkspacePersistence, чтобы


иметь возможность сохранять и восстанавливать свое окно с помощью рабочих пространств
NinjaTrader.

Примечание. Классы AddOn, производные от NTWindow или реализующие


IWorkspacePersistance, НЕ МОГУТ быть вложенным типом другого класса и ДОЛЖНЫ иметь
конструктор по умолчанию.

Этот интерфейс содержит два метода и одно свойство, которое должно быть скрыто
реализующим классом:

Restore() Восстанавливает окно из рабочих областей.

Save() Сохраняет окно в рабочие области.

WorkspaceOptions Устанавливает необходимые параметры


рабочего пространства.

Examples
public class MyWindow : NTWindow, IWorkspacePersistence
{
// конструктор по умолчанию
public MyWindow()
{
// Определим наш NTWindow. Если мы хотим использовать вкладки в стиле NT, мы
определим это здесь.

// Свойство WorkspaceOptions должно быть установлено

Loaded += (o, e) =>


{
if (WorkspaceOptions == null)
WorkspaceOptions = new WorkspaceOptions("MyWindow-" +
Guid.NewGuid().ToString("N"), this);
};
}

// Член IWorkspacePersistence. Требуется для восстановления окна из рабочих областей


public void Restore(XDocument document, XElement)
{
if (MainTabControl != null)
MainTabControl.RestoreFromXElement(element);
}

// Член IWorkspacePersistence. Требуется для сохранения окна в рабочие области


public void Save(XDocument document, XElement element)
{
if (MainTabControl != null)
MainTabControl.SaveToXElement(element);
}

// Член IWorkspacePersistence
public WorkspaceOptions WorkspaceOptions { get; set; }
}

Restore()
Restores the window from workspaces.

Examples
// Член IWorkspacePersistence. Требуется для восстановления окна из рабочих областей
public void Restore(XDocument document, XElement)
{
if (MainTabControl != null)
MainTabControl.RestoreFromXElement(element);
}

Save()
Сохраняет окно в рабочие области.

Examples

// Член IWorkspacePersistence. Требуется для сохранения окна в рабочие области


public void Save(XDocument document, XElement element)
{
if (MainTabControl != null)
MainTabControl.SaveToXElement(element);
}

WorkspaceOptions
Определение
Устанавливает необходимые параметры рабочего пространства.

Заметки:
• Класс WorkspaceOptions включает логику для открытия, закрытия, сохранения и
восстановления рабочих пространств, проверки того, что окна находятся вне экрана, и
установки основных свойств, таких как имя рабочего пространства и текущий статус.
• Свойство WorkspaceOptions необходимо просто объявить в NTWindow, как в примере ниже.
Вся содержащаяся в нем логика обрабатывается автоматически.

Совет. Чтобы получить полный рабочий пример использования этого класса, загрузите базовый
пример AddOn Framework NinjaScript на свой рабочий стол.
Examples

// Член IWorkspacePersistence
public WorkspaceOptions WorkspaceOptions { get; set; }

NTTabPage Class
Здесь можно определить фактическое содержимое вкладок внутри настраиваемого добавления
в NTWindow.

Примечание. Класс, производный от NTTabPage, должен быть создан, если требуется


функциональность связи инструмента или интервала связи. Интерфейсы IInstrumentProvider и
IIntervalProvider также должны быть реализованы для обеспечения правильного связывания.

Cleanup() Отменяет регистрацию LinkControls и


вызывает Cleanup () для элементов
управления ICleanable на NTTabPage

GetHeaderPart() Указывает имя заголовка вкладки.

Restore() Восстанавливает любые элементы в нашей


NTTabPage из рабочей области.

Save() Сохраняет элементы нашей NTTabPage в


рабочую область.

Examples
public class MyWindowTabPage : NTTabPage, NinjaTrader.Gui.Tools.IInstrumentProvider,
IIntervalProvider
{
private Instrument instrument;

public MyWindowTabPage()
{
/ * Определяем содержимое для нашей NTTabPage. Мы можем загрузить свободный
XAML для определения элементов управления и макетов
если мы так выберем и здесь.

Примечание. XAML с обработчиками событий, определенными внутри, БУДЕТ


НЕУДАЧНЫМ при попытке загрузки.
Примечание. XAML со "встроенным кодом" БУДЕТ НЕУДАЧНЫМ при попытке загрузки *
/
}

// Вызывается TabControl при удалении вкладки или закрытии окна


public override void Cleanup()
{
/ * Отказаться от подписки и очистить ресурсы, используемые только что закрытой
вкладкой. Ты можешь иметь
ресурсы, которые вы еще не хотите очищать, потому что окно все еще используется * /
}

// Член NTTabPage. Требуется для определения названия заголовка вкладки


protected override string GetHeaderPart(string variable)
{
// Определяем текст для имени заголовка вкладки
return variable;
}

// Член NTTabPage. Требуется для восстановления элементов из рабочих пространств


protected override void Restore(System.Xml.Linq.XElement element)
{
if (element == null)
return;

// Восстановление любых элементов, которые вы могли сохранить. например выбранные


счета или инструменты
}

// Член NTTabPage. Требуется для сохранения элементов в рабочих пространствах


protected override void Save(System.Xml.Linq.XElement element)
{
if (element == null)
return;

// Save any elements you may want persisted. e.g. selected accounts or instruments
}

// IInstrumentProvider member
public Instrument Instrument
{
get { return instrument; }
set
{
if (instrument != null)
{
// Unsubscribe to subscriptions to previously selected instrument
}

if (value != null)
{
// Create subscriptions for the newly selected instrument
}

instrument = value;

// Update the tab header name


RefreshHeader();
}
}

// IIntervalProvider member
public BarsPeriod BarsPeriod { get; set; }
}

CleanUp()

Определение
Отменяет регистрацию LinkControls (IInstrumentProvider IIntervalProvider) и вызывает Cleanup ()
для элементов управления ICleanable на NTTabPage. Переопределите это, например, чтобы
отказаться от подписки на события или выполнить любые другие операции очистки, когда
вкладка закрыта.
Примечание. При переопределении Cleanup () настоятельно рекомендуется вызывать
base.Cleanup (), который гарантирует, что любые элементы управления ссылками также будут
отменены. Базовая реализация также будет обрабатывать все элементы управления,
реализующие ICleanable: AccountSelector, AtmStrategySelector, InstrumentSelector,
IntervalSelector, TifSelector.

Возвращаемое значение метода


Этот метод не возвращает значение

Syntax
public override void Cleanup()
{
}
Параметры
Этот метод не принимает никаких параметров
Examples

public override void Cleanup()


{
// отменяем регистрацию от любых пользовательских событий
Connection.ConnectionStatusUpdate -= OnConnectionStatusUpdate;

// вызов base.Cleanup () будет перебирать визуальное дерево в поисках всех дочерних


элементов ICleanable
// то есть AccountSelector, AtmStrategySelector, InstrumentSelector, IntervalSelector,
TifSelector,
// а также отменить регистрацию любых событий управления ссылками

base.Cleanup();
}

GetHeaderPart()
Определение
Указывает имя заголовка вкладки.
Examples
// Член NTTabPage. Требуется для определения названия заголовка вкладки
protected override string GetHeaderPart(string variable)
{
// Определяем текст для имени заголовка вкладки
switch (variable)
{
case "@INSTRUMENT": return Instrument == null ? Resource.GuiNewTab :
Instrument.MasterInstrument.Name;
case "@INSTRUMENT_FULL": return Instrument == null ? Resource.GuiNewTab :
Instrument.FullName;
}
return variable;
}

Restore()

Восстанавливает любые элементы в нашей NTTabPage из рабочей области. (например,


выбранные счета или инструменты)
Examples

// Член NTTabPage. Требуется для восстановления элементов из рабочих пространств


public void Restore(XElement element)
{
if (element == null)
return;

// Восстановление любых элементов, которые вы могли сохранить. например выбранные


счета или инструменты
}

Save()
Сохраняет элементы из нашей NTTabPage в рабочую область (например, выбранные счета или
инструменты)
Examples

// Член NTTabPage. Требуется для сохранения элементов в рабочих пространствах


public void Save(XElement element)
{
if (element == null)
return;

// Сохраняем любые элементы, которые вы хотите сохранить. например выбранные счета


или инструменты
}

Alert and Debug Concepts(Концепции


предупреждений и отладки)
В большинстве сценариев вы можете использовать методы, предоставленные NinjaScript, для
запуска предупреждений и функций отладки. Однако при создании собственных
пользовательских объектов вы можете захотеть использовать эту функциональность за
пределами области NinjaScript (например, при создании NTTabPage для надстроек).

Использование вывода NinjaScript


Вместо Print () используйте Output.Process () для написания сообщения.

Вместо ClearOutputWindow () используйте Output.Reset () для очистки окна вывода.

Example

// Вместо Print ()
NinjaTrader.Code.Output.Process("my message", PrintTo.OutputTab1);

// Вместо ClearOutputWindow ()
NinjaTrader.Code.Output.Reset()
Использование предупреждений
Вместо Alert () используйте NinjaTrader.NinjaScript.Alert.AlertCallback () для отправки
предупреждения.

Вместо ResetAlert () используйте NinjaTrader.NinjaScript.Alert.RearmAlert ()

Example

// Instead of Alert()
NinjaTrader.NinjaScript.Alert.AlertCallback(NinjaTrader.Cbi.Instrument.GetInstrument("MSFT"), this,
"someId", NinjaTrader.Core.Globals.Now, Priority.High, "message", null, Brushes.Blue,
Brushes.White, 0);
// Instead of ResetAlert()
NinjaTrader.NinjaScript.Alert.ResetAlert("someId");

Разнообразный
Вместо Log () используйте NinjaScript.Log () для отправки сообщения в журналы NinjaTrader.

Вместо PlaySound () используйте Globals.PlaySound () для воспроизведения звука.

Вместо SendMail () используйте Globals.SendMail () для отправки почты.

Совет: как Globals.PlaySound (), так и .SendMail (), указанные выше, также могут использоваться
в обычных объектах NinjaScript, однако это не рекомендуется, поскольку они не будут
игнорировать вызовы вне State.Realtime, которые могут дать неожиданные результаты.

Examples

// Вместо Log ()
NinjaScript.Log("My log message", LogLevel.Error);

// Вместо PlaySound ()
NinjaTrader.Core.Globals.PlaySound(@"C:\mySound.wav");

// Вместо SendMail ()
NinjaTrader.Core.Globals.SendMail("customers@email.com", "cc_these_people@email.com",
"Subject", "Mail body", null);

Коды ошибок в файлах журнала


Перечисление ErrorCode можно найти в журналах NinjaTrader время от времени, когда
возникает ошибка, и они могут предоставить дополнительные подсказки о причине
неожиданного поведения во время вашей отладки. Эти коды ошибок не обязательно связаны с
вашим кодом, но они могут указывать на проблему, которую необходимо решить за пределами
области вашего кода, что экономит ваше время при попытке найти источник ошибок в вашем
коде. Ниже приведен список значений перечисления ErrorCode и их значений:

NoError Ошибок не было

LogOnFailed Не удалось войти в систему из-за неверных


учетных данных

OrderRejected Брокер отклонил текущий ордер

UnableToCancelOrder Заказ не может быть отменен сейчас, но


может быть успешно отменен позже
UnableToChangeOrder Либо биржа, либо брокер не поддерживает
обновление ордеров для рассматриваемого
инструмента, либо ордер еще не был
отправлен.

UserAbort Операция была прервана пользователем

Panic Произошла неопределенная ошибка

AlertCallback()
Определение
Создает событие предупреждения, которое должно быть вызвано, указанное строкой «id», и
будет воспроизводиться соответствующий файл .wav, соответствующий параметру
«soundLocation». После срабатывания предупреждения его сообщение отражается в окне
«Журнал предупреждений» на основе кистей фона и переднего плана, предоставленных в
обратном вызове.

Заметки:

1. Если метод AlertCallback () вызывается снова с тем же строковым параметром «id» до


истечения заданной длительности «rearmSeconds», событие предупреждения будет сброшено
на основе предоставленного нового параметра «rearmSeconds». Это может привести к
непреднамеренному сбросу предупреждения. В этом случае следует передать параметр
rearmSeconds равным «0», чтобы гарантировать, что указанное событие предупреждения
всегда возникает.

2. Метод AlertCallback () - это та же основная функция, что и более простой метод Alert (),
который в качестве альтернативы может использоваться с индикаторами и стратегиями
NinjaScript. AlertCallback () был доступен для использования с надстройками или другими более
продвинутыми вариантами использования.

3. Предоставление параметра «rearmSeconds» больше, чем «0», добавит соответствующий


идентификатор оповещения в состояние возврата, что позволяет повторно выдать оповещение
только по истечении указанного временного интервала в секундах. Вы можете сбросить
параметр повторного включения предупреждения с помощью ResetAlertRearmById ().

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax
NinjaTrader.NinjaScript.Alert.AlertCallback(Instrument instrument, object source, string id, DateTime
time, Priority priority, string message, string soundLocation, Brush backBrush, Brush foreBrush, int
rearmSeconds)
Предупреждение: ДОЛЖЕН быть предоставлен параметр "id", иначе будет сгенерировано
исключение с нулевым аргументом.

Parameters

instrument Объект инструмента, связанный с


предупреждением.

source Общий тип объекта, создавшего


предупреждение (например, "это").

id Строка, представляющая уникальный


идентификатор для предупреждения.

time DateTime, представляющий время, связанное


с предупреждением.

priority Устанавливает приоритет предупреждения по


отношению к другим предупреждениям.

Любое из следующих значений:

Priority.High

Priority.Low

Priority.Middle

message Строка, представляющая сообщение с


предупреждением.

soundLocation Строка, представляющая абсолютный путь к


файлу .wav для воспроизведения.

backBrush Устанавливает цвет фона строки окна


предупреждений для этого предупреждения
при срабатывании (ссылка)

foreBrush Устанавливает цвет переднего плана строки


окна предупреждений для этого
предупреждения при срабатывании (ссылка)

rearmSeconds Тип int, который устанавливает количество


секунд, в течение которых предупреждение
будет повторно активировано.

Примечание: если то же предупреждение


(идентифицированное параметром id)
вызывается в пределах временного окна,
равного времени последнего
предупреждения + rearmSeconds,
предупреждение будет проигнорировано.
Советы: Вы можете получить каталог установки NinjaTrader по умолчанию для доступа к папке
звуков, используя свойство NinjaTrader.Core.Globals.InstallDir. См. Пример использования ниже.

Examples

NinjaTrader.NinjaScript.Alert.AlertCallback(NinjaTrader.Cbi.Instrument.GetInstrument("MSFT"), this,
"someId", NinjaTrader.Core.Globals.Now, Priority.High, "message",
NinjaTrader.Core.Globals.InstallDir+@"\sounds\Alert1.wav", new SolidColorBrush(Colors.Blue),
new SolidColorBrush(Colors.White), 0);

RearmAlert()

Определение
Повторно вызывает существующее событие предупреждения с помощью строкового параметра
id, созданного с помощью метода AlertCallback (). Предупреждение, сгенерированное
NinjaScript, может потребоваться повторно после срабатывания предупреждения в зависимости
от параметра rearmSeconds Alert ().

Примечание. В NinjaScriptBase реализован нестатический метод с тем же именем. См. Метод


RearmAlert () для индикаторов или стратегий.

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax
NinjaTrader.NinjaScript.Alert.RearmAlert(string id)
Parameters

id Уникальный строковый идентификатор,


представляющий идентификатор
предупреждения для сброса

Examples

if (resetCondition)
{
NinjaTrader.NinjaScript.Alert.ResetAlertRearmById("someId");
resetCondition = false;
}

AtmStrategy
AtmStrategy содержит свойства и методы, используемые для управления стратегиями
банкоматов. При работе с AtmStrategySelector выбранные объекты могут быть переданы
AtmStrategy для получения или изменения их свойств.

Заметки:

1. Чтобы получить полный рабочий пример использования этого класса, загрузите пример
фреймворка, расположенный в нашем обзоре разработки надстроек.

2. Дополнительные сведения о программной работе со стратегиями банкоматов в целом см. В


разделе «Использование стратегий банкоматов».

Example

// Использование AtmStrategy для обработки выбора пользователя в селекторе стратегии


банкомата
myAtmStrategySelector.SelectionChanged += (o, args) =>
{
if (myAtmStrategySelector.SelectedItem == null)
return;
if (args.AddedItems.Count > 0)
{
// Изменяем выбранный TIF в селекторе TIF в зависимости от того, что выбрано в
селекторе стратегии ATM
NinjaTrader.NinjaScript.AtmStrategy selectedAtmStrategy = args.AddedItems[0] as
NinjaTrader.NinjaScript.AtmStrategy;
if (selectedAtmStrategy != null)
{
myTifSelector.SelectedTif = selectedAtmStrategy.TimeInForce;
}
}
};

ControlCenter
Определение
ControlCenter - это определенный XAML класс, содержащий макет и свойства окна Control
Center. При изменении окна Центра управления (например, чтобы добавить пункт меню в меню
«Новый» для запуска NTWindow как части надстройки, как показано в примере ниже), общая
ссылка на объект Window может быть приведена к В частности, ControlCenter.

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

Example
private NTMenuItem ControlCenterNewMenu;

protected override void OnWindowCreated(Window window)


{
// Мы хотим разместить пункт меню для AddOn в меню «New» Центра управления
// Сначала получаем ссылку на окно Центра управления

ControlCenter cc = window as ControlCenter;


if (cc == null)
return;

/ * Определяем, что мы хотим разместить надстройку в меню «Новый» Центра


управления
К другим меню можно получить доступ через «Automation ID» элемента управления.
Например: toolsMenuItem, workspacesMenuItem, connectionsMenuItem, helpMenuItem. * /
ControlCenterNewMenu = cc.FindFirst("ControlCenterMenuItemNew") as NTMenuItem;
}

FundamentalData
Определение
FundamentalData используется для доступа к фундаментальным данным моментальных
снимков и для подписки на события фундаментальных данных.

Примечание. Не забудьте отказаться от подписки, если вы больше не пользуетесь


подпиской.

Properties

AverageDailyVolume double , представляющий средний дневной


объем

Beta double , представляющий бета

CalendarYearHigh A double представляет собой высокую


цену календарного года

CalendarYearHighDate DateTime, представляющий дату


максимальной цены календарного года.

CalendarYearLow double , обозначающий низкую цену


календарного года.
CalendarYearLowDate DateTime, представляющий дату
минимальной цены календарного года.

CurrentRatio double значение, представляющее


коэффициент текущей ликвидности

DividendAmount double значение, обозначающее сумму


дивидендов

DividendPayDate DateTime, представляющий дату выплаты


дивидендов

DividendYield double значение дивидендной доходности

EarningsPerShare double значение, представляющее прибыль


на акцию

FiveYearsGrowthPercentage double , представляющий 5-летний процент


роста

High52Weeks double , представляющий 52-недельный


максимум

High52WeeksDate DateTime, представляющий дату максимума


цены за 52 недели.

HistoricalVolatility double , представляющий историческую


нестабильность

InsiderOwned double значение, представляющее сумму,


принадлежащую инсайдерам

Instrument Инструмент, представляющий инструмент

Low52Weeks double , представляющий 52-недельный


минимум

Low52WeeksDate DateTime, представляющий дату минимума


цены за 52 недели.

MarketCap double , представляющий рыночную


капитализацию

NextYearsEarningsPerShare double значение, представляющее прибыль


на акцию в следующем году.

PercentHeldByInstitutions double значение, представляющее процент,


принадлежащий учреждениям

PriceEarningsRatio double значение, обозначающее


соотношение цена / прибыль.

RevenuePerShare double значение, представляющее доход на


акцию

SharesOutstanding long , представляющий акции в обращении

ShortInterest double , представляющий короткий интерес

ShortInterestRatio double значение, обозначающее


коэффициент короткой ставки

VWAP double , представляющий VWAP

Update Обработчик событий для подписки / отказа от


подписки на события глубины рынка

Syntax
FundamentalData

Example

/ * Пример подписки / отказа от подписки на фундаментальные данные из дополнения.


Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private FundamentalData fundamentalData;

public MyAddOnTab()
{
// Подпишемся на фундаментальные данные. Данные снэпшота предоставляются
прямо при подписке
fundamentalData = new FundamentalData(value);
fundamentalData.Update += OnFundamentalData;

// Печать фундаментальных данных моментального снимка для среднего дневного


объема
NinjaTrader.Code.Output.Process(fundamentalData.AverageDailyVolume,
PrintTo.OutputTab1);
}

// Этот метод запускается для фундаментальных событий данных


private void OnFundamentalData(object sender, FundamentalDataEventArgs e)
{
// Что-то делаем с фундаментальными событиями данных
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно откажитесь от подписки на подписку на фундаментальные данные
if (fundamentalData != null)
fundamentalData.Update -= OnFundamentalData;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}

MarketData
Определение
MarketData можно использовать для доступа к рыночным данным моментальных снимков и для
подписки на события рыночных данных.

Заметки:

1. Не забудьте отказаться от подписки, если вы больше не пользуетесь подпиской.

2. Вы должны отказаться от подписки на событие с рыночными данными, только если вы


действительно подписаны.

Properties

Ask MarketDataEventArgs, представляющий цену


спроса

Bid MarketDataEventArgs, представляющий цену


предложения

DailyHigh MarketDataEventArgs, представляющий


дневной максимум

DailyLow MarketDataEventArgs, представляющий


дневной минимум

DailyVolume MarketDataEventArgs, представляющий


дневной объем

Instrument Инструмент, представляющий инструмент

Last MarketDataEventArgs, представляющий


последнюю цену

LastClose MarketDataEventArgs, представляющий


последнее закрытие

Opening MarketDataEventArgs, представляющий цену


открытия

OpenInterest MarketDataEventArgs, представляющий


открытый интерес

Settlement MarketDataEventArgs, представляющий


расчетную цену

Update Обработчик событий для подписки / отказа от


подписки на события глубины рынка
Примечание. Попытка отказаться от подписки
на это событие до того, как будет оформлена
подписка, приведет к ошибкам.

Syntax
MarketData

Example

/ * Пример подписки / отказа от подписки на рыночные данные из надстройки. Концепция


может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private MarketData marketData;

public MyAddOnTab()
{
// Подпишемся на рыночные данные. Данные снэпшота предоставляются прямо при
подписке
// Примечание: в этом примере "инструмент" является заполнителем, вам нужно будет
заменить
// с действительным объектом инструмента с помощью различных методов или
доступных свойств в зависимости от
// на типе NinjaScript, с которым вы работаете (например, Bars.Instrument или
Instrument.GetInstrument ()

marketData = new MarketData(instrument);


marketData.Update += OnMarketData;

// Печать снимка рыночных данных с последней ценой и временем


NinjaTrader.Code.Output.Process(marketData.Last.Price.ToString() + " " +
marketData.Last.Time.ToString(),
PrintTo.OutputTab1);
}

// Этот метод запускается при событиях рыночных данных


private void OnMarketData(object sender, MarketDataEventArgs e)
{
// Что-то делать с событиями рыночных данных
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно откажитесь от подписки на подписку на рыночные данные
if (marketData != null)
marketData.Update -= OnMarketData;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях.
}

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

Properties

Asks Список цен спроса

Bids Список цен предложений

Instrument Инструмент, представляющий инструмент


события глубины рынка

Update Обработчик событий для подписки / отказа от


подписки на события глубины рынка

Syntax
MarketDepth

Example
/ * Пример подписки / отказа от подписки на глубину рынка из надстройки. Концепция может
быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private MarketDepth<MarketDepthRow> marketDepth;

public MyAddOnTab()
{
// Подпишемся на рыночные данные. Данные снэпшота предоставляются прямо при
подписке
// Примечание: в этом примере "инструмент" является заполнителем, вам нужно будет
заменить
// с действительным объектом инструмента с помощью различных методов или
доступных свойств в зависимости от
// на типе NinjaScript, с которым вы работаете (например, Bars.Instrument или
Instrument.GetInstrument ()

marketDepth = new MarketDepth<MarketDepthRow>(instrument);


marketDepth.Update += OnMarketDepth;
}

// Этот метод запускается при событиях глубины рынка и после обновления данных
моментального снимка.
private void OnMarketDepth(object sender, MarketDepthEventArgs e)
{
// Распечатываем ценовую лестницу Ask
for (int i = 0; i < marketDepth.Asks.Count; i++)
{
NinjaTrader.Code.Output.Process(string.Format("Position: {0} Price: {1} Volume: {2}", i,
marketDepth.Asks[i].Price, marketDepth.Asks[i].Volume), PrintTo.OutputTab1);
}
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно откажитесь от подписки на подписку на рыночные данные
if (marketDepth != null)
marketDepth.Update -= OnMarketDepth;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код
}

NewsItems
Определение
NewsItems можно использовать для хранения новостных статей.
Properties

Items Коллекция NewsEventArgs, представляющая


новостные статьи

NewsToMaintain Тип int, представляющий количество статей


для поддержки.

Update() Для хранения новостных статей

Syntax
NewsItems

Example
/ * Пример хранения и доступа к новостям из надстройки. Концепция может быть
перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private NewsSubscription newsSubscription;
private NewsItems newsItems;

public MyAddOnTab()
{
// Подписка на новости
newsSubscription = new NewsSubscription();
newsSubscription.Update += OnNews;
newsItems = new NewsItems(10);

// Распечатать новости
PrintNews(newsItems);
}

// Этот метод запускается при поступлении новых событий новостей. События старых
новостей не предоставляются при подписке.
private void OnNews(object sender, NewsEventArgs e)
{
// Сохраняем новости
newsItems.Update(e);
}

// Перебираем сохраненные новостные статьи и выводим их


private void PrintNews(NewsItems news)
{
for (int x = 0; x < news.Items.Count; x++)
{
NinjaTrader.Code.Output.Process(string.Format("ID: {0} News Provider: {1} Headline:
{2}",
news.Items[x].Id,
news.Items[x].NewsProvider,
news.Items[x].Headline), PrintTo.OutputTab1);
}
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно отписывайтесь от подписки на новости
if (newsSubscription != null)
newsSubscription.Update -= OnNews;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях. Обязательно добавьте их в свой код.
}

NewsSubscription
Определение
NewsSubscription можно использовать для подписки на новости.

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

Properties

Update Обработчик событий для подписки / отказа от


подписки на события глубины рынка

Syntax
NewsSubscription

Example
/ * Пример подписки / отказа от подписки на новости от дополнения. Концепция может быть
перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /

public class MyAddOnTab : NTTabPage


{
private NewsSubscription newsSubscription;
private NewsItems newsItems;

public MyAddOnTab()
{
// Подписка на новости
newsSubscription = new NewsSubscription();
newsSubscription.Update += OnNews;
newsItems = new NewsItems(10);
}

// Этот метод запускается при поступлении новых событий новостей. События старых
новостей не предоставляются при подписке.
private void OnNews(object sender, NewsEventArgs e)
{
// Вывести заголовок новости
NinjaTrader.Code.Output.Process(string.Format("ID: {0} News Provider: {1} Headline: {2}",
e.Id,
e.NewsProvider,
e.Headline), PrintTo.OutputTab1);

// Ведение новостей
newsItems.Update(e);
}

// Вызывается TabControl, когда вкладка удаляется или окно закрывается


public override void Cleanup()
{
// Обязательно отписывайтесь от подписки на новости
if (newsSubscription != null)
newsSubscription.Update -= OnNews;
}

// Остальные обязательные члены NTTabPage не учитываются в демонстрационных


целях.
}
NTMenuItem
Определение
NTMenuItem используется для создания новых пунктов меню. Например, экземпляр этого
класса можно поместить в существующее меню Центра управления, чтобы запустить
NTWindow как часть надстройки, как показано в примере кода ниже.

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

Examples

private NTMenuItem myNewMenuItem;


private NTMenuItem existingControlCenterNewMenu;

protected override void OnWindowCreated(Window window)


{
// Мы хотим разместить пункт меню для AddOn в меню «New» Центра управления
// Сначала получаем ссылку на окно Центра управления

ControlCenter cc = window as ControlCenter;


if (cc == null)
return;

/ * Определяем, что мы хотим разместить надстройку в меню «Новый» Центра управления


К другим меню можно получить доступ через «Automation ID» элемента управления.
Например: toolsMenuItem, workspacesMenuItem, connectionsMenuItem, helpMenuItem. * /

existingControlCenterNewMenu = cc.FindFirst("ControlCenterMenuItemNew") as NTMenuItem;


if (existingControlCenterNewMenu == null)
return;

// Создание экземпляра myNewMenuItem


// Заголовок устанавливает имя нашего аддона, видимого в структуре меню. «Стиль»
устанавливает стиль шрифта.

myNewMenuItem = new NTMenuItem { Header = "AddOn Framework", Style =


Application.Current.TryFindResource("MainMenuItem") as Style };

// Добавляем наш пункт меню AddOn в меню "New"


existingControlCenterNewMenu.Items.Add(myNewMenuItem);

// Подпишемся на событие, когда пользователь нажимает пункт меню


myNewMenuItem.Click += OnMenuItemClick;
}

NTMessageBoxSimple.Show()
Определение
Создает окно окна сообщения.

Примечание. Дополнительные сведения об использовании окон MessageBox см. В


документации по классу .NET MessageBox.

Возвращаемое значение метода

MessageBoxResult; перечисление, представляющее нажатие кнопки, используемой для


закрытия окна MessageBox

Syntax
NTMessageBoxSimple.Show(Window input, string messageTxt, string caption, MessageBoxButton
buttonSet, MessageBoxImage icon)

Parameters

parent Окно (DependencyObject), представляющее


окно-владелец

messageTxt Тело сообщения окна MessageBox

caption Заголовок окна MessageBox

buttonSet Перечисление MesageBoxButton,


определяющее кнопки, используемые для
окна MessageBox.

icon Перечисление MesageBoxImage,


определяющее значок, используемый для
окна MessageBox.

Examples
// Создаем окно MessageBox из диаграммы
ChartControl.Dispatcher.InvokeAsync(new Action(() => {
NinjaTrader.Gui.Tools.NTMessageBoxSimple.Show(Window.GetWindow(ChartControl.OwnerChart
as DependencyObject), "Message Body", "Message Header", MessageBoxButton.OK,
MessageBoxImage.None);
}));
// Создание окна MessageBox при нажатии кнопки в надстройке
private void OnMenuItemClick(object sender, RoutedEventArgs e)
{
NinjaTrader.Gui.Tools.NTMessageBoxSimple.Show(Window.GetWindow(e.Source as
DependencyObject), "Message Body", "Message Header", MessageBoxButton.OK,
MessageBoxImage.None);
}

NTWindow

Определение
Класс NTWindow определяет родительские окна для создания пользовательских окон.
Экземпляры NTWindow действуют как контейнеры для экземпляров NTTabPage, в которых
содержатся элементы пользовательского интерфейса и связанная с ними логика.

Заметки:

• Интерфейс IWorkspacePersistance должен быть реализован, если вы хотите, чтобы ваше окно
было сохранено и восстановлено с помощью рабочих пространств NinjaTrader.

• Классы AddOn, которые являются производными от NTWindow или реализуют


IWorkspacePersistance, НЕ МОГУТ быть вложенным типом другого класса и ДОЛЖНЫ иметь
конструктор по умолчанию.

Пример
В приведенном ниже примере показано, как создать экземпляр NTWindow, пока:

• Реализация IWorkspacePersistence для обеспечения сохранения / восстановления окна в


рабочих областях.

• Настройка заголовка и размеров окна.

• Создание экземпляра TabControl для поддержки вкладок в окне

• Настройка параметров рабочего пространства

Совет: Чтобы получить полный рабочий пример использования этого класса, загрузите пример
фреймворка, расположенный в нашем обзоре разработки надстроек.

public class AddOnFrameworkWindow : NTWindow, IWorkspacePersistence


{
// конструктор по умолчанию
public AddOnFrameworkWindow()
{
// устанавливаем свойство Caption (не заголовок), поскольку заголовок управляется
внутренне, чтобы правильно сочетать выбранный заголовок вкладки и заголовок для
отображения на панели задач Windows
// Это имя отображается в верхнем левом углу окна
Caption = "AddOn Framework";

// Устанавливаем размеры окна по умолчанию


Width = 1085;
Height = 900;

// TabControl должен быть создан для содержимого окна, если требуются функции вкладки
TabControl tc = new TabControl();

// Присоединенные свойства, определенные в классе TabControlManager, должны быть


установлены для достижения добавления, удаления и перемещения вкладок
TabControlManager.SetIsMovable(tc, true);
TabControlManager.SetCanAddTabs(tc, true);
TabControlManager.SetCanRemoveTabs(tc, true);

// если желательна возможность добавлять новые вкладки, TabControl должен иметь


прикрепленное свойство "Factory".
TabControlManager.SetFactory(tc, new AddOnFrameworkWindowFactory());
Content = tc;

/ * Чтобы иметь возможность использовать кнопки ссылок, элементы управления вкладками


должны быть производными от Tools.NTTabPage
Их можно добавить с помощью метода расширения AddNTTabPage (страница NTTabPage)
*/
tc.AddNTTabPage(new AddOnFrameworkTab());

// Свойство WorkspaceOptions должно быть установлено


Loaded += (o, e) =>
{
if (WorkspaceOptions == null)
WorkspaceOptions = new WorkspaceOptions("AddOnFramework-" +
Guid.NewGuid().ToString("N"), this);
};
}

// Член IWorkspacePersistence. Требуется для восстановления окна из рабочей области


public void Restore(XDocument document, XElement element)
{
if (MainTabControl != null)
MainTabControl.RestoreFromXElement(element);
}

// Член IWorkspacePersistence. Требуется для сохранения окна в рабочую область


public void Save(XDocument document, XElement element)
{
if (MainTabControl != null)
MainTabControl.SaveToXElement(element);
}

// Член IWorkspacePersistence
public WorkspaceOptions WorkspaceOptions { get; set; }
}
NumericTextBox
NumericTextBox предоставляет функциональные возможности для числовых текстовых полей
для захвата вводимых пользователем данных. Этот элемент пользовательского интерфейса
может быть определен в XAML для надстройки, если это необходимо, с функциональными
возможностями и логикой, связанными с текстовым полем, определенным в C #, как в примерах
ниже.

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

NumericTextBox наследуется от System.Windows.Controls.Textbox, и для экземпляра класса


можно получить доступ к следующим дополнительным свойствам:

Minimum Определяет минимальное значение, которое


можно ввести

Maximum Определяет максимальное значение, которое


можно ввести

ValueType Определяет System.Type, который может


быть принят

Examples
XAML Definition of the UI Element
<! - Создайте сетку для размещения NumericTextBox ->
<Grid>
<! - Определить NumericTextBox ->
<t:NumericTextBox x:Name="daysBackSelector" Text="5" ValueType="{x:Type system:Int32}"
Width="50" Grid.Column="2">
<! - Установить поля для бокса ->
<t:NumericTextBox.Margin>
<Thickness Left="{StaticResource MarginButtonLeft}" Top="{StaticResource
PaddingColumn}" Right="{StaticResource MarginBase}"/>
</t:NumericTextBox.Margin>
</t:NumericTextBox>
</Grid>

C# Code Handling Logic


private NumericTextBox daysBack;

private DependencyObject LoadXAML()


{
// Находим селектор дней назад
daysBack = LogicalTreeHelper.FindLogicalNode(pageContent, "daysBackSelector") as
NumericTextBox;
}

OnWindowCreated()
Определение
Этот метод вызывается всякий раз, когда создается новое окно NTWindow. Он будет
вызываться в потоке этого окна. Здесь вы должны установить свой AddOn в существующее
окно или, если вы создаете свое собственное окно, добавить пункт меню в Центр управления
NinjaTrader.

Примечание: этот метод также будет вызываться при перекомпиляции проекта


NinjaTrader.Custom (например, при компиляции индикатора, стратегии или надстройки).

Возвращаемое значение метода


Этот метод не возвращает значение

Syntax
OnWindowCreated(Window window)
Parameters

window Объект Window, который добавляется в


рабочую область.

Examples
public class MyWindowAddOn : AddOnBase
{
private NTMenuItem myMenuItem;
private NTMenuItem existingMenuItem;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Description = "Our custom MyWindow add on";
Name = "MyWindow";
}
}

// Будет вызываться при создании нового NTWindow. Он будет вызываться в потоке этого
окна
protected override void OnWindowCreated(Window window)
{
// Мы хотим разместить ваше дополнение в меню Центра управления
ControlCenter cc = window as ControlCenter;
if (cc == null)
return;

/ * Определяем, что мы хотим разместить наше дополнение в меню «New» Центра


управления
Доступ к другим меню можно получить через идентификатор автоматизации элемента
управления. Например: toolsMenuItem,
workspacesMenuItem, connectionsMenuItem, helpMenuItem. * /

existingMenuItem = cc.FindFirst("ControlCenterMenuItemNew") as NTMenuItem;


if (existingMenuItem == null)
return;

// 'Заголовок' устанавливает имя нашего дополнения, видимого в структуре меню


myMenuItem = new NTMenuItem { Header = "My Menu Item",
Style = Application.Current.TryFindResource("MainMenuItem") as Style };

// Помещаем наше дополнение в меню "New"


existingMenuItem.Items.Add(myMenuItem);

// Подпишемся на событие, когда пользователь нажимает на ваш пункт меню надстройки


myMenuItem.Click += OnMenuItemClick;
}
// Открываем окно нашего надстройки при щелчке по пункту меню
private void OnMenuItemClick(object sender, RoutedEventArgs e)
{
// Показать NTWindow "MyWindow"
Core.Globals.RandomDispatcher.InvokeAsync(new Action(()=> new MyWindow().Show()));
}
}

OnWindowDestroyed()
Определение
Этот метод вызывается всякий раз, когда уничтожается новое окно NTWindow. Он будет
вызываться в потоке этого окна. Окно уничтожается либо пользователем, закрывающим окно,
закрывая рабочую область, либо при закрытии NinjaTrader.

Примечание: этот метод также будет вызываться при перекомпиляции проекта


NinjaTrader.Custom (например, при компиляции индикатора, стратегии или надстройки).

Возвращаемое значение метода


Этот метод не возвращает значение

Syntax
OnWindowDestroyed(Window window)
Parameters

window Объект Window, который удаляется из


рабочей области
Examples
public class MyWindowAddOn : AddOnBase
{
private NTMenuItem myMenuItem;
private NTMenuItem existingMenuItem;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Description = "Our custom MyWindow add on";
Name = "MyWindow";
}
}
// Будет вызываться при уничтожении нового окна NTWindow. Он будет вызываться в потоке
этого окна
protected override void OnWindowDestroyed(Window window)
{
if (myMenuItem != null && window is ControlCenter)
{
if (existingMenuItem != null && existingMenuItem.Items.Contains(myMenuItem))
existingMenuItem.Items.Remove(myMenuItem);

myMenuItem.Click -= OnMenuItemClick;
myMenuItem = null;
}
}
}

OnWindowRestored()
Определение
Вызывается при восстановлении окна из рабочей области, которая вызывается после
OnWindowCreated (). Этот метод используется для вызова любых пользовательских данных
XElement из рабочей области путем ссылки на окно. См. Также OnWindowSaved () для
получения информации о том, как сохранить пользовательские данные XElement при
сохранении окна.

Возвращаемое значение метода


Этот метод не возвращает значение

Syntax
OnWindowRestored(Window window, XElement element)
Parameters

window Объект Window, который восстанавливается


из рабочей области

element Объект XElement, представляющий


восстанавливаемое рабочее пространство

Examples
protected override void OnWindowRestored(Window window, XElement element)
{
Print("OnWindowRestored for " + window.GetHashCode());

// находим элемент рабочего пространства "Sample AddOn", который был создан и


сохранен ранее с помощью метода OnWindowSaved ()
XElement sampleAddOnElement = element.Element("SampleAddOn");

// ничего не делаем, если этот элемент не существует


if (sampleAddOnElement == null)
return;

// перебираем все содержимое элемента "SampleAddOn"


foreach (XElement content in sampleAddOnElement.Elements())
{
// находим содержимое "ButtonState", восстанавливаем его значение и устанавливаем
его в качестве отслеживаемого buttonState
if (content.Name == "ButtonState")
{
bool buttonState = false;
bool.TryParse(content.Value, out buttonState);
continue;
}
// Разбираем дополнительные элементы здесь
}

// Не забудьте вызвать базовый метод OnWindowRestored после того, как закончите.


base.OnWindowRestored(window, element);
}

OnWindowSaved()
Определение
Вызывается при сохранении окна в рабочей области, которая вызывается перед
OnWindowDestroyed (). Этот метод используется для сохранения любых пользовательских
данных XElement, связанных с вашим окном.

Возвращаемое значение метода


Этот метод не возвращает значение

Syntax
OnWindowSaved(Window window, XElement element)

Parameters
window Объект Window, который сохраняется в
рабочей области.

element Объект XElement, представляющий


сохраняемую рабочую область.

Examples
protected override void OnWindowSaved(Window window, XElement element)
{
Print("OnWindowSaved for " + window.GetHashCode());

// создаем новый XElement для сохранения последнего состояния настраиваемой кнопки в


рабочей области
XElement xml = new XElement("SampleAddOn", new XElement("ButtonState", true));

// e.g.,
// <SampleAddOn>
// <ButtonState>true</ButtonState>
// </SampleAddOn>

// добавляем новый элемент в рабочую область, который можно будет восстановить позже
element.Add(xml);

// Не забудьте вызвать базовый метод OnWindowSaved после завершения операции.


base.OnWindowSaved(window, element);
}

StartAtmStrategy()
Определение
StartAtmStrategy можно использовать для отправки ордеров на вход со стратегиями
банкоматов.

Syntax
NinjaTrader.NinjaScript.AtmStrategy.StartAtmStrategy(AtmStrategy atmStrategyTemplate, Order
entryOrder)
NinjaTrader.NinjaScript.AtmStrategy.StartAtmStrategy(string atmStrategyTemplateName, Order
entryOrder)

Properties

atmStrategyTemplate AtmStrategy, представляющая стратегию


банкомата, которую вы хотите использовать

atmStrategyTemplateName Строка, представляющая название стратегии


банкомата, которую вы хотите использовать.

entryOrder Ордер, представляющий порядок входа

Критично: аргумент «name» в методе CreateOrder () ДОЛЖЕН иметь имя «Entry» для успешного
запуска стратегии ATM.

Example

/ * Пример запуска стратегии банкомата из окна Add On. Концепция может быть перенесена
к любому объекту NinjaScript, над которым вы можете работать. * /
public class MyAddOnTab : NTTabPage
{
private Account account;
private Order entryOrder;

public MyAddOnTab()
{
// Находим наш аккаунт Sim101
lock (Account.All)
account = Account.All.FirstOrDefault(a => a.Name == "Sim101");

if (account != null)
{
entryOrder = account.CreateOrder(Cbi.Instrument.GetInstrument("AAPL"),
OrderAction.Buy, OrderType.Market,
TimeInForce.Day, 1, 0, 0, string.Empty, "Entry", null);

// Отправляем наш ордер на вход со стратегией банкомата под названием


"myAtmStrategyName"
NinjaTrader.NinjaScript.AtmStrategy.StartAtmStrategy("myAtmStrategyName",
entryOrder);
}
}
// Остальные обязательные члены NTTabPage не учитываются в демонстрационных целях.
Не забудьте добавить их в свой собственный код при создании окна Add On.
}

StrategyBase
StrategyBase содержит свойства и методы для управления объектом стратегии и является
базовым классом, производным от AtmStrategy.
Примечание. Чтобы получить полный рабочий пример использования этого класса, загрузите
пример фреймворка, расположенный в нашем обзоре разработки надстроек.

Example

// Кнопка acctStratButton на NTTabPage отображает все стратегии ATM и NinjaScript,


настроенные для выбранной учетной записи, при нажатии
private void OnButtonClick(object sender, RoutedEventArgs e)
{
Button button = sender as Button;

if (button != null && ReferenceEquals(button, acctStratButton))


{
// Когда кнопка нажата, перебираем все стратегии ATM и NinjaScript
// Сюда входят все активные, восстановленные при последнем подключении или
деактивированные с момента последнего подключения
// Во-первых, заблокируйте коллекцию Strategies, чтобы избежать изменений в
коллекции, влияющих на наш вывод

lock (accountSelector.SelectedAccount.Strategies)
// Перебираем коллекцию стратегий в выбранной учетной записи
foreach (StrategyBase strategy in accountSelector.SelectedAccount.Strategies)
outputBox.AppendText(string.Format("{0}Name: {1}{0}ATM Template Name: {2}
{0}Instrument: {3}{0}State: {4}{0}Category: {5}{0}",
Environment.NewLine,
strategy.Name,
strategy.Template,
strategy.Instruments[0].FullName,
strategy.State,
strategy.Category));
}
}

PropagateInstrumentChange()
Определение
В NTWindow PropagateInstrumentChange () отправляет инструмент в другие окна с тем же
настроенным цветом привязки инструментов.

Заметки:
• Для использования PropagateInstrumentChange () необходимо определить общедоступное
свойство Instrument, как в примере ниже.

• Чтобы получить полный рабочий пример использования этого класса, загрузите пример
фреймворка, расположенный в нашем обзоре разработки надстроек.

Example

// Член IInstrumentProvider. Требуется, если вы хотите использовать механизм связи


инструментов в NTWindow.
public Cbi.Instrument Instrument
{
get { return instrument; }
set
{
// Логика процесса, связанная с переключением инструментов, например:
// Отписываемся от подписки на старые инструменты ...
// Подписка на новый инструмент ...
// Изменяем значение, отображаемое в селекторе инструментов в NTWindow ...
// Обновляем имя заголовка вкладки в AddOnFramework, чтобы оно совпадало с
именем нового инструмента ...
// так далее...

// Отправляем инструмент в другие окна, связанные с тем же цветом

PropagateInstrumentChange(value);
}
}

PropagateIntervalChange()
Определение
В NTWindow PropagateIntervalChange () отправляет интервал другим окнам с тем же
настроенным цветом Interval Linking.

Заметки:

1.Чтобы использовать PropagateInstrumentChange (), необходимо определить общедоступное


свойство Instrument, как в примере ниже.

2. Чтобы получить полный рабочий пример использования этого класса, загрузите пример
фреймворка, расположенный в нашем обзоре разработки надстроек.
Example

// Этот настраиваемый метод будет запущен, когда селектор интервала в


настраиваемом NTTabPage изменяет интервалы
private void OnIntervalChanged(object sender, BarsPeriodEventArgs args)
{
if (args.BarsPeriod == null)
return;

PropagateIntervalChange(args.BarsPeriod);
}

TabControl
Определение
Класс TabControl предоставляет функциональные возможности для работы с объектами
NTTabPage в NTWindow. TabControl должен быть создан в конструкторе для экземпляра
NTWindow, чтобы настроить окно так, чтобы оно могло размещать вкладки и работать с ними.

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

Пример
В приведенном ниже примере мы определяем экземпляр NTWindow, а затем используем
TabControl для выполнения различных задач настройки:

• Предоставьте NTWindow возможность добавлять, удалять и перемещать вкладки.

• Присоедините Factory к TabControl для обработки логики создания новых вкладок.

• Настройте TabControl с возможностью использования связывания окон

public class MyWindow : NTWindow, IWorkspacePersistence


{
public MyWindow()
{
// TabControl должен быть создан для содержимого окна, если требуются функции
вкладки
TabControl tc = new TabControl();

// Присоединенные свойства, определенные в классе TabControlManager, должны быть


настроены для добавления, удаления или перемещения вкладок
TabControlManager.SetIsMovable(tc, true);
TabControlManager.SetCanAddTabs(tc, true);
TabControlManager.SetCanRemoveTabs(tc, true);

// если желательна возможность добавлять новые вкладки, TabControl должен иметь


прикрепленное свойство "Factory", установленное.
TabControlManager.SetFactory(tc, new MyWindowFactory());
Content = tc;
/ * Чтобы иметь возможность использовать кнопки ссылок, элементы управления вкладками
должны быть производными от Tools.NTTabPage
Их можно добавить с помощью метода расширения AddNTTabPage (страница NTTabPage)
*/

tc.AddNTTabPage(new MyTab());
}
}

/ * Класс, реализующий Tools.INTTabFactory, должен быть создан и установлен как


присоединенное свойство для TabControl
чтобы использовать функцию добавления / удаления / перемещения / дублирования
страницы вкладки * /

public class MyWindowFactory : INTTabFactory


{
// Член INTTabFactory. Требуется для создания родительского окна
public NTWindow CreateParentWindow()
{
return new MyWindow();
}

// Член INTTabFactory. Требуется для создания вкладок


public NTTabPage CreateTabPage(string typeName, bool isTrue)
{
return new MyTab();
}
}

TabControlManager
Определение
Класс TabControlManager можно использовать для установки или проверки нескольких свойств
объекта TabControl. Вместо того, чтобы создавать экземпляр объекта TabControlManager, вы
можете использовать общедоступные статические методы класса для установки определенных
свойств для указанного TabControl, как в примере кода ниже.
Примечание. Чтобы получить полный рабочий пример использования этого класса, загрузите
пример фреймворка, расположенный в нашем обзоре разработки надстроек.

Setters

SetCanAddTabs(DependencyObject obj, Устанавливает TabControl может добавлять


bool value) новые вкладки

SetCanDuplicateTabs(DependencyObject Устанавливает TabControl может


obj, bool value) дублировать вкладки в новых вкладках или
новых окнах

SetCanRemoveTabs(DependencyObject Устанавливает TabControl может удалять


obj, bool value) вкладки

SetFactory(DependencyObject obj, bool Устанавливает NTTabFactory для TabControl


value)

SetIsSimulation(DependencyObject obj, Устанавливает для текущей NTTabPage цвет


bool value) имитации, если это правда. Этот метод
необходимо использовать логически из
NTTabPage.

SetIsMovable(DependencyObject obj, bool Устанавливает TabControl позволяет


value) изменять порядок вкладок в окне

Getters

GetCanAddTabs(DependencyObject obj) Указывает, что TabControl может добавлять


новые вкладки

GetCanDuplicateTabs(DependencyObject Указывает, что TabControl может


obj) дублировать вкладки в новых вкладках или
новых окнах

GetCanRemoveTabs(DependencyObject Указывает, что TabControl может удалять


obj) вкладки

GetFactory(DependencyObject obj) Получает NTTabFactory, используемый


TabControl

GetIsSimulation(DependencyObject obj) Указывает, что цвет моделирования,


выбранный в меню параметров,
отображается на фоне вкладки, когда на
вкладке выбрана учетная запись
моделирования.

GetIsMovable(DependencyObject obj) Указывает, что TabControl позволяет


изменять порядок вкладок в окне

Example

public AddOnFrameworkWindow()
{
// TabControl должен быть создан для содержимого окна, если требуются функции вкладки
TabControl tc = new TabControl();

// Прикрепленные свойства, определенные в классе TabControlManager, должны быть


установлены для обеспечения перемещения вкладок, добавления / удаления вкладок
TabControlManager.SetIsMovable(tc, true);
TabControlManager.SetCanAddTabs(tc, true);
TabControlManager.SetCanRemoveTabs(tc, true);

// если желательна возможность добавлять новые вкладки, TabControl должен иметь


прикрепленное свойство "Factory".
TabControlManager.SetFactory(tc, new AddOnFrameworkWindowFactory());
Content = tc;

/ * Чтобы иметь возможность использовать кнопки ссылок, элементы управления


вкладками должны быть производными от Tools.NTTabPage
Их можно добавить с помощью метода расширения AddNTTabPage (страница NTTabPage)
*/
tc.AddNTTabPage(new AddOnFrameworkTab());

Bars Type
Создание настраиваемых типов полосок обеспечивает невероятную гибкость в способе
представления данных на диаграмме. Методы и свойства, описанные в этом разделе,
уникальны для разработки пользовательских типов стержней.

Методы и свойства

AddBar() Добавляет новые точки данных для типа


столбцов.

ApplyDefaultBasePeriodValue Устанавливает базовые значения по


умолчанию, используемые для BarsPeriod,
выбранного пользователем (например,
PeriodValue по умолчанию, DaysToLoad и т.
Д.) Для вашего настраиваемого типа бара.

ApplyDefaultValue Устанавливает значения BarsPeriod по


умолчанию, используемые для
настраиваемого типа бара.

BuiltFrom Определяет базовый набор данных,


используемый для построения BarsType (т. Е.
Tick, Minute, Day).

GetInitialLookBackDays() Определяет, сколько дней загружаются


данные, когда пользователь делает запрос
данных «назад».

GetPercentComplete() Определяет значение, которое ваш BarsType


вернет для Bars.PercentComplete
Icon Форма, которая отображается рядом с
пунктом меню «Тип полос».

IsRemoveLastBarSupported Определяет, может ли тип столбцов


использовать метод RemoveLastBar (), если
он имеет значение true, в противном случае
будет создано исключение.

IsTimebased Используется для обозначения того, что


BarsType построен на основе временных
столбцов (день, минута, секунда).

OnDataPoint() Метод OnDataPoint () - это то место, где вы


должны настроить точки данных (значения
столбцов) вашей серии с помощью AddBar ()
и UpdateBar ().

RemoveLastBar() Удаляет последнюю точку данных для типа


столбцов.

SessionIterator Предоставляет информацию о торговой


сессии для типа баров. Должен быть
построен с использованием объекта bars.

UpdateBar() Обновляет точку данных в нашем типе


столбцов.

AddBar()
Определение
Добавляет новые точки данных для типа столбцов.
Syntax
AddBar(Bars bars, double open, double high, double low, double close, DateTime time, long volume)
AddBar(Bars bars, double open, double high, double low, double close, DateTime time, long volume,
double bid, double ask)

Параметры

bars Объект Bars вашего типа бара

open Двойное значение, представляющее цену


открытия

high Двойное значение, обозначающее высокую


цену

low Двойное значение, обозначающее низкую


цену

close Двойное значение, представляющее цену


закрытия

time Значение DateTime, представляющее время


volume long значение, представляющее объем

bid Двойное значение, представляющее цену


предложения.

ask Двойное значение, представляющее цену


предложения

Examples

AddBar(bars, open, high, low, close, time, (long)Math.Min(volumeTmp, bars.BarsPeriod.Value));

ApplyDefaultBasePeriodValue()
Определение
Устанавливает базовые значения по умолчанию, используемые для BarsPeriod, выбранного
пользователем (например, PeriodValue по умолчанию, DaysToLoad и т. Д.) Для вашего
настраиваемого типа бара.

Возвращаемое значение метода


Этот метод не возвращает значения.

Parameters

period BarsPeriod, выбранный пользователем при


использовании этого типа Bars

Синтаксис
Вы должны переопределить метод в своем типе столбцов со следующим синтаксисом:

public override void ApplyDefaultBasePeriodValue(BarsPeriod period)


{

}
Examples
public override void ApplyDefaultBasePeriodValue(BarsPeriod period)
{
// устанавливает значение периода минутных баров по умолчанию равным 1, а дни для
загрузки - 5
if (period.BaseBarsPeriodType == BarsPeriodType.Minute)
{
period.BaseBarsPeriodValue = 1;
DaysToLoad = 5;
}
// устанавливает значение периода тиковых баров по умолчанию на 150, а дни для
загрузки - на 3
else if (period.BaseBarsPeriodType == BarsPeriodType.Tick)
{
period.BaseBarsPeriodValue = 150;
DaysToLoad = 3;
}

ApplyDefaultValue
Определение
Устанавливает значения BarsPeriod по умолчанию, используемые для настраиваемого типа
бара.

Возвращаемое значение метода


Этот метод не возвращает значения.

Parameters

period BarsPeriod, выбранный пользователем при


использовании этого типа Bars

Синтаксис
Вы должны переопределить метод в своем типе столбцов со следующим синтаксисом:

public override void ApplyDefaultValue(BarsPeriod period)


{

Examples
public override void ApplyDefaultValue(BarsPeriod period)
{
period.BarsPeriodTypeName = "MyBarType";
period.Value = 1;
}

BuiltFrom
Определение
Определяет базовый набор данных, используемый для построения BarsType (т. Е. Tick, Minute,
Day). Свойство BuiltFrom будет управлять частотой, с которой OnDataPoint () обрабатывает
исторические данные.

Стоимость имущества
Перечисление BarsPeriodType. Будут признаны следующие ценности:

• BarsPeriodType.Tick

• BarsPeriodType.Minute

• BarsPeriodType.Day

Предупреждение: использование других типов периодов баров (например, диапазона, объема


или других типов пользовательских баров) НЕ поддерживается. Указанные выше значения
BarsPeriodType представляют все основные точки данных, необходимые для построения
столбца.

Syntax
BuiltFrom
Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "MyCustomBarsType";
BarsPeriod = new BarsPeriod { BarsPeriodType = (BarsPeriodType) 15, BarsPeriodTypeName
= "MyCustomBarsType(15)", Value = 1 };
BuiltFrom = BarsPeriodType.Minute;// обновляем OnDataPoint () каждую минуту на
исторических данных
DaysToLoad = 5;
}

else if (State == State.Configure)


{
}
}

DefaultChartStyle
Определение
Позволяет установить ChartStyle по умолчанию для использования с типом баров NinjaTrader.

Стоимость имущества
Значение ChartStyleTypeÂenum, представляющее ChartStyle, которое будет установлено по
умолчанию. Системные настройки по умолчанию включают:

• ChartStyleType.Box,

• ChartStyleType.CandleStick,

• ChartStyleType.LineOnClose,

• ChartStyleType.OHLC,

• ChartStyleType.PointAndFigure,

• ChartStyleType.KagiLine,

• ChartStyleType.OpenClose,

• ChartStyleType.Mountain

Syntax
DefaultChartStyle

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "SampleBarsType";
BarsPeriod = new BarsPeriod { BarsPeriodType = (BarsPeriodType) 15,
BarsPeriodTypeName = "SampleBarsType(15)", Value = 1 };
BuiltFrom = BarsPeriodType.Minute;
DaysToLoad = 5;
DefaultChartStyle = Gui.Chart.ChartStyleType.CandleStick;
IsIntraday = true;
}
}

GetInitialLookBackDays()
Определение

Определяет, сколько дней загружаются данные, когда пользователь делает запрос данных
«назад».

Возвращаемое значение метода


Этот метод возвращает значение типа int.

Method Parameters

barsPeriod Период баров, выбранный пользователем


при использовании этого типа баров

tradingHours Часы торговли, выбранные пользователем


при использовании этого типа Баров.

barsBack Вертикальные полосы, выбранные


пользователем при использовании этого типа
полос

Синтаксис
Вы должны переопределить метод в своем типе столбцов, используя следующий синтаксис.
public override int GetInitialLookBackDays(BarsPeriod barsPeriod, TradingHours tradingHours, int
barsBack)
{
}

Examples

public override int GetInitialLookBackDays(BarsPeriod barsPeriod, TradingHours tradingHours,


int barsBack)
{
// Возвращает минимальное количество дней, необходимое для успешной загрузки числа
// количество баров, запрошенных для ежемесячного типа Bars
return (int) barsPeriod.Value * barsBack * 31;
}

Совет: попробуйте запросить объем данных, который подходит именно для того, что
необходимо. Запрос слишком большого набора данных приведет к загрузке ненужных данных.
Запрос слишком маленького набора данных приведет к выполнению нескольких запросов.

GetPercentComplete()
Определение
Определяет значение, которое ваш BarsType вернет для Bars.PercentComplete

Возвращаемое значение метода


Этот метод возвращает двойное значение.

Method Parameters

bars Объект баров, выбранный пользователем


при использовании этого типа баров.

now Значение DateTime для измерения

Синтаксис
Вы должны переопределить метод в своем типе столбцов, используя следующий синтаксис.

public override double GetPercentComplete(Bars bars, DateTime now)


{

Examples
public override double GetPercentComplete(Bars bars, DateTime now)
{
// Рассчитываем процент завершения для наших месячных баров
if (now.Date <= bars.LastBarTime.Date)
{
int month = now.Month;
int daysInMonth = (month == 2) ? (DateTime.IsLeapYear(now.Year) ? 29 : 28) :
(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 ||
month == 12 ? 31 : 30);
return (daysInMonth - (barsSeries.LastBarTime.Date.AddDays(1).Subtract(now).TotalDays /
barsSeries.BarsPeriod.Value)) /
daysInMonth; // оценка
}
return 1;
}

Icon
Определение
Форма, которая отображается рядом с пунктом меню «Тип полос». Поскольку это стандартный
объект, можно использовать любой тип значка (символы Юникода, пользовательский ресурс
файла изображения, путь геометрии и т. Д.).

Дополнительные сведения об использовании изображений для создания значков см. На


странице «Использование изображений с настраиваемыми значками».

Примечание. При использовании символов UniCode сначала убедитесь, что нужные символы
существуют в пакете значков для семейства шрифтов, используемого в NinjaTrader.

Стоимость имущества
Общий виртуальный объект, представляющий значок меню инструментов рисования. Это
свойство доступно только для чтения.

Синтаксис
Вы должны переопределить это свойство, используя следующий синтаксис:

public override object Icon


Examples

public override object Icon


{
get
{
// используем символ юникода в качестве нашей строки, которая будет отображать стрелку
string uniCodeArrow = "\u279A";
return uniCodeArrow;
}
}

IsRemoveLastBarSupported
Определение
Определяет, может ли тип столбцов использовать метод RemoveLastBar (), если он имеет
значение true, в противном случае будет создано исключение. Типы полос, которые используют
концепцию удаления последней полосы, НЕ МОГУТ использоваться с повтором тиков, и в
результате повтор тика будет отключен в пользовательском интерфейсе, если для
IsRemoveLastBarSupported установлено значение true.

Примечание. Это свойство доступно только для чтения, но может быть переопределено в
настраиваемом типе полосы.

Syntax
IsRemoveLastBarSupported
Стоимость имущества
Логическое значение, определяющее, может ли BarsType удалить последний; значение по
умолчанию - false.

Examples

// позволяет вызывать RemoveLastBar ()


public override bool IsRemoveLastBarSupported { get { return true; } }

IsTimeBased
Определение
Используется для обозначения того, что BarsType построен на основе временных столбцов
(день, минута, секунда). Установка этого свойства для настраиваемого типа полосы полезна
для правильных вычислений на основе многих основных данных и логики сеанса, а также
может использоваться сторонними объектами NinjaScript для определения того, как
взаимодействовать с полосами.
Стоимость имущества
bool значение, которое, когда истинно, сообщает другим объектам, что столбцы построены по
времени; по умолчанию установлено значение false.

Syntax
Bars.IsTimeBased

Examples
Установка значений по умолчанию IsTimeBased в настраиваемом типе
BarsType
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "Custom BarsType";
IsTimeBased = true// указывает ядру, что эти бары построены с использованием
времени.
}
}

Чтение IsTimeBased из настраиваемого объекта NinjaScript


protected override void OnBarUpdate()
{
// включаем отметки времени в миллисекундах для тиковых баров
string timeFormat = "HH:mm:ss:fff";

if (Bars.BarsType.IsTimeBased)
{
// для столбцов, основанных на времени, форматирование только до "секунд"
timeFormat = "HH:mm:ss";
}
// форматируем строку на основе подходящего формата времени
Print(Time[0].ToString(timeFormat));
}

OnDataPoint()
Определение
Вызывается для каждой записи в соответствующем базовом наборе данных, который
используется для построения BarType (т. Е. Для каждого тика, минуты или дня). Метод
OnDataPoint () - это то место, где вы должны настраивать точки данных (значения столбцов)
вашей серии с помощью AddBar () и UpdateBar (). См. Также свойство BuiltFrom.

Заметки:

1. Обработка исторических данных получает одно обновление для каждого базового бара,
определенного свойством BuiltFrom.

2. При использовании TickReplay исторические обновления будут вызывать каждый тик,


обрабатываемый ядром, независимо от определенного свойства BuiltFrom.

3.После перехода в режим реального времени обновления будут вызывать каждый тик,
обрабатываемый ядром.

4. Параметры спроса / предложения будут доступны ТОЛЬКО исторически при использовании


повторного воспроизведения тиков, если вы не используете серию в 1 тик.

5. isBar может иметь значение true в случае, если BarsSeries был внутренне скопирован в
другой BarsSeries, и требуется только для IsTimeBased = true BarsTypes (например, Second /
Minute / Day ...).

Возвращаемое значение метода


Этот метод не возвращает значения.

Method Parameters

bars Объект Bars вашего типа бара

open bool значение, представляющее цену


открытия

high bool значение, обозначающее высокую


цену

low bool значение, обозначающее низкую


цену

close bool значение, представляющее цену


закрытия

time Значение DateTime, представляющее


время

volume long значение, представляющее объем


isBar Логическое значение, представляющее,
должен ли OnDataPoint обрабатывать
метку времени как уже построенную
полосу или как

метка времени внутри дня.

bid bool значение, представляющее цену


предложения.

ask bool значение, представляющее цену


предложения

Синтаксис
Вы должны переопределить метод в своем типе столбцов, используя
следующий синтаксис.

protected override void OnDataPoint(Bars bars, double open, double high, double low, double
close,
DateTime time, long volume, bool isBar, double bid, double ask)
{

}
Examples

protected override void OnDataPoint(Bars bars, double open, double high, double low,
double close, DateTime time, long volume, bool isBar, double bid, double ask)
{
int minIndex;

// Создаем первую точку данных нашей серии


if (bars.Count == 0)
{
minIndex = 0;
AddBar(bars, open, high, low, close, TimeToBarTime(time, (int) bars.BarsPeriod.Value),
volume);
}
// Обновляем нашу точку данных последней информацией
else if ((time.Month <= bars.LastBarTime.Month && time.Year == bars.LastBarTime.Year) ||
time.Year < bars.LastBarTime.Year)
{
if (high != bars.GetHigh(bars.Count - 1) || low != bars.GetLow(bars.Count - 1) ||
close != bars.GetClose(bars.Count - 1) || volume > 0)
{
minIndex = bars.Count - 1;
UpdateBar(bars, high, low, close, bars.LastBarTime, volume);
}
else
minIndex = -1;
}
// Добавляем новые точки данных
else
{
minIndex = bars.Count;
AddBar(bars, open, high, low, close, time, (long)Math.Min(volumeTmp,
bars.BarsPeriod.Value));
}
FirstBarAmended = minIndex;
}

RemoveLastBar()
Определение
Удаляет последнюю точку данных для типа столбцов. Могут быть случаи, когда для вашего
настраиваемого типа полосы может потребоваться изменить последние значения,
добавленные для уже закрытой полосы. Вызов RemoveLastBar () удалит последние точки для
этого типа бара и позволит вам вызвать AddBar () с обновленными значениями.

Заметки:
• Чтобы использовать этот метод, метод IsRemoveLastBarSupported должен иметь значение
true.

• RemoveLastBar () НЕ МОЖЕТ использоваться с TickReplay.

Syntax
RemoveLastBar(Bars bars)

Parameters

bars Объект Bars вашего типа бара

Examples

RemoveLastBar(bars);

SetPropertyName()
Определение
Устанавливает имя свойства по умолчанию для настраиваемой строки, которая будет
отображаться в пользовательском интерфейсе.

Возвращаемое значение метода

Этот метод не возвращает значения.

Syntax
SetPropertyName(string propertyName, string displayName)

Method Parameters

propertyName Строка, представляющая свойство, которое


нужно переименовать. Возможные значения
включают:
•UpBrush
•DownBrush
•BarWidth
•Stroke
•Stroke2
•Value
•Value2
•BaseBarsPeriodType
•BaseBarsPeriodValue
•PointAndFigurePriceType
•ReversalType

displayName string, представляющая желаемое имя


свойства.

Example
protected override void OnStateChange()
{
if (State == State.Configure)
{
Properties.Remove(Properties.Find("Stroke", true));
Properties.Remove(Properties.Find("Stroke2", true));

SetPropertyName("UpBrush", "AdvanceBar");
SetPropertyName("DownBrush", "DeclineBar");
}
}

Примечание. Если вы не хотите использовать определенные свойства, доступные через


SetPropertyName (), вам нужно будет удалить их из списка через Properties.Remove, как
показано в примере выше.
SessionIterator
Определение
Предоставляет информацию о торговой сессии для типа баров. Должен быть построен с
использованием объекта bars.

Стоимость имущества
Объект SessionIterator, который используется для расчета информации о торговых днях /
сессиях.

Syntax
SessionIterator

Examples

protected override void OnDataPoint(Bars bars, double open, double high, double low, double close,
DateTime time, long volume, bool isBar, double bid, double ask)
{
// строим итератор сеанса из обновляемого объекта bar
if (SessionIterator == null)
SessionIterator = new SessionIterator(bars);

// проверяем, находимся ли мы в новой торговой сессии, основываясь на торговых часах,


выбранных пользователем
bool isNewSession = SessionIterator.IsNewSession(time, isBar);

// рассчитываем новый торговый день


if (isNewSession)
SessionIterator.CalculateTradingDay(time, isBar);

Print(SessionIterator.ActualTradingDayExchange);

UpdateBar()
Определение
Обновляет точку данных в нашем типе столбцов.

Syntax
UpdateBar(Bars bars, double high, double low, double close, DateTime time, long volumeAdded)
Parameters

bars Объект Bars вашего типа бара

high bool значение, обозначающее высокую цену

low bool значение, обозначающее низкую цену

close bool значение, представляющее цену


закрытия

time `Значение DateTime, представляющее время

volume Длинное значение, представляющее объем`

Examples

UpdateBar(bars, high, low, close, time, volume);

Chart Style
Пользовательские стили диаграмм можно использовать на диаграммах для представления
информации о столбцах в другом визуальном представлении. Методы и свойства, описанные в
этом разделе, уникальны для разработки пользовательских стилей диаграмм. Ниже приведен
указатель свойств и методов, задокументированных для стилей диаграмм.
Methods and Properties

BarWidth Раскрашенная ширина панели ChartStyle

BarWidthUI Значение ширины полосы, отображаемое в


пользовательском интерфейсе.

ChartStyleType Определяет значение уникального


идентификатора, используемое для
регистрации настраиваемого стиля ChartStyle

DownBrush Объект Brush, используемый для


определения цвета рисования полос вниз
для ChartStyle.

DownBrushDX Объект SharpDX.Brush, используемый для


рисования полос вниз для ChartStyle

GetBarPaintWidth() Возвращает нарисованную ширину полосы


диаграммы.

IsTransparent Указывает, что полосы в ChartStyle


прозрачны

OnRender() Управляемый событиями метод,


используемый для визуализации
содержимого в ChartStyle

SetPropertyName() Устанавливает имя свойства по умолчанию


для настраиваемой строки, которая будет
отображаться в пользовательском
интерфейсе

TransformBrush() Масштабирует кисть не сплошного цвета,


используемую для отрисовки стиля
диаграммы, для правильного отображения в
NinjaTrader.

UpBrush Объект Brush, используемый для


определения цвета рисования полос вверх
для ChartStyle.

UpBrushDX Объект SharpDX.Brush, используемый для


рисования полос вверх для ChartStyle.

BarWidth
Определение
Раскрашенная ширина полосы ChartStyle. Это значение будет обновляться при изменении
размера ChartControl.

Стоимость имущества
Двойное значение, представляющее текущую ширину полос диаграммы

Syntax
BarWidth

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "Example ChartStyle";
ChartStyleType = (ChartStyleType) 52;
BarWidth = 1;
}
}

BarWidthUI
Определение
Значение ширины полосы, отображаемое в пользовательском интерфейсе. Это значение будет
округлено из внутреннего свойства BarWidth, которое обновляется при изменении размера
ChartControl.

Стоимость имущества
Значение типа int, представляющее ширину полос диаграммы, которая может быть
установлена пользователем.

Syntax
BarWidthUI

Examples

protected override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars


chartBars)
{

int barWidth = GetBarPaintWidth(BarWidthUI);

ChartStyleType
Определение
Определяет значение уникального идентификатора, используемое для регистрации
настраиваемого стиля ChartStyle. Существует 11 стилей графиков по умолчанию, которые
поставляются с NinjaTrader, которые зарезервированы для таблицы на этой странице в
разделе параметров этой страницы.

Примечание. Свойство ChartStyle может позволить зарегистрировать большое количество


стилей диаграмм при установке одного пользователя (до 2 147 483 647). Однако важно
отметить, что два установленных стиля ChartStyles на компьютере пользователя все еще могут
конфликтовать, если они будут зарегистрированы с одним и тем же значением перечислителя.
В этом случае NinjaTrader проигнорирует конфликтующий тип ChartStyle, и информация,
относящаяся к этому конфликту, будет отображаться на вкладке «Журнал» Центра управления
NinjaTrader.

Добавлено 31.01.2018: мы советуем пользователям использовать значения больше 1023 при


выборе перечисления. Поскольку NinjaTrader время от времени может добавлять новое
значение перечисления в этот диапазон, что может вызывать конфликты.
Стоимость имущества
Значение перечисления, представляющее ChartStyle, который необходимо зарегистрировать.

Совет: рекомендуется выбрать высокое уникальное значение перечисления, чтобы избежать


конфликта с другими стилями диаграмм, которые могут использоваться в одной установке.

Синтаксис
Вы должны привести ChartStyleType из int, используя следующий синтаксис:
(ChartStyleType) 80;

Параметры
Зарезервированные значения перечисления перечислены ниже:

0 Box

1 CandleStick

2 LineOnClose

3 OHLC

4 PointAndFigure

5 KagiLine

6 OpenClose

7 Mountain

8 Volumetric

9 HollowCandleStick

10 Equivolume

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "Example ChartStyle";
ChartStyleType = (ChartStyleType) 80;
BarWidth = 1;
}
}
DownBrush
Определение
Объект Brush, используемый для определения цвета рисования полос вниз для ChartStyle.

Примечание. Эта реализация класса Brush в Windows Presentation Forms (WPF) не


используется напрямую для рисования полос на диаграмме. Вместо этого он преобразуется в
кисть SharpDX в свойстве DownBrushDX. Это свойство используется для захвата
пользовательского ввода для изменения цвета кисти.

Стоимость имущества
Объект кисти WPF, используемый для рисования полос вниз

Syntax
DownBrush

Example

protected override void OnStateChange()


{
if (State == State.Configure)
{
// Устанавливаем новое имя для свойства DownBrush
SetPropertyName("DownBrush", "DecliningBrush");
}
}

DownBrushDX
Definition
A SharpDX Brush object used to paint the down bars for the ChartStyle.

Property Value
A SharpDX Brush object used to paint the down bars

Syntax
DownBrushDX
Example

protected override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars


chartBars)
{
for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
{
double closeValue = bars.GetClose(idx);
double openValue = bars.GetOpen(idx);
// Устанавливаем кисть текущей свечи на UpBrushDX или DownBrushDX, в зависимости от
// направление бара

Brush brush = closeValue >= openValue ? UpBrushDX : DownBrushDX;


}
}

GetBarPaintWidth()

Определение
Возвращает нарисованную ширину полосы диаграммы. Метод GetBarPintWidth () вернет
минимальное значение 1.

Примечание. Это абстрактный метод, необходимый для компиляции объекта ChartStyle. Если
вы не планируете пересчитывать barWidth, просто верните параметр barWidth по умолчанию,
который передается в этом методе. Пожалуйста, смотрите раздел Примеры на этой странице
для получения дополнительной информации.

Возвращаемое значение метода


Значение типа int

Синтаксис
Вы должны игнорировать этот метод, используя следующий синтаксис:

public override int GetBarPaintWidth(int barWidth)


{

}
Method Parameters

barWidth Значение типа int, представляющее текущую


ширину полосы для вычисления
Examples
Возврат значения barWidth по
умолчанию
public override int GetBarPaintWidth(int barWidth)
{
return barWidth
}

Вычисление и возврат нового barWidth из исходной barWidth


public override int GetBarPaintWidth(int barWidth)
{
// calculate a new bar width
return 1 + 2 * (barWidth - 1) + 2 * (int) Math.Round(Stroke.Width);
}

Icon
Определение
Фигура, которая отображается рядом с пунктом меню «Стиль диаграммы». Поскольку это
стандартный объект, можно использовать любой тип значка (символы Юникода,
пользовательский ресурс файла изображения, путь геометрии и т. Д.).

Дополнительные сведения об использовании изображений для создания значков см. На


странице «Использование изображений с настраиваемыми значками».

Примечание. При использовании символов UniCode сначала убедитесь, что нужные символы
существуют в пакете значков для семейства шрифтов, используемого в NinjaTrader.

Стоимость имущества
Общий виртуальный объект, представляющий значок меню инструментов рисования. Это
свойство доступно только для чтения.

Синтаксис
Вы должны переопределить это свойство, используя следующий синтаксис:

public override object Icon


Examples
public override object Icon
{
get
{
// используем символ юникода в качестве нашей строки, которая будет отображать стрелку
string uniCodeArrow = "\u279A";
return uniCodeArrow;
}
}

IsTransparent
Определение
Указывает, что полосы в ChartStyle прозрачны.

Стоимость имущества
Логическое значение, которое, когда оно истинно, указывает, что UpBrush, DownBrush и
Stroke.Brush все установлены на прозрачные. Возвращает false, если какой-либо из трех
непрозрачных.

Syntax
IsTransparent

Example

protected override void OnStateChange()


{
if (State == State.Configure)
{
// Распечатать сообщение, если UpBrush, DownBrush и Stroke.Brush все прозрачны
if (IsTransparent)
Print("All bars are currently set to transparent");
}
}

OnRender()

Определение
Управляемый событиями метод, используемый для визуализации содержимого в ChartStyle.
Метод OnRender () вызывается каждый раз при обновлении значений диаграммы. Эти
обновления управляются входящими данными в столбцы диаграммы или пользователем,
вручную взаимодействующим с элементом управления диаграммы или шкалой диаграммы.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в своем ChartStyle, используя следующий синтаксис:
protected override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars
chartBars)
{

}
Method Parameters

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

chartBars ChartBars, представляющий серию Bars для


диаграммы

Examples
protected override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars
chartBars)
{
// Логика рендеринга для нашего стиля диаграммы
}

SetPropertyName()

Определение
Устанавливает имя свойства по умолчанию для настраиваемой строки, которая будет
отображаться в пользовательском интерфейсе.

Возвращаемое значение метода


Этот метод не возвращает значения.
Syntax
SetPropertyName(string propertyName, string displayName)
Method Parameters

propertyName Строка, представляющая свойство, которое


нужно переименовать. Возможные значения
включают:

•UpBrush
•DownBrush
•BarWidth
•Stroke
•Stroke2

displayName string, представляющая желаемое имя


свойства.

Example

protected override void OnStateChange()


{
if (State == State.Configure)
{
Properties.Remove(Properties.Find("Stroke", true));
Properties.Remove(Properties.Find("Stroke2", true));

SetPropertyName("UpBrush", "AdvanceBar");
SetPropertyName("DownBrush", "DeclineBar");
}
}

Примечание. Если вы не хотите использовать определенные свойства, доступные через


SetPropertyName (), вам нужно будет удалить их из списка через Properties.Remove, как
показано в примере выше.

TransformBrush()
Определение
Масштабирует кисть не сплошного цвета, используемую для рендеринга стиля диаграммы, для
правильного отображения в NinjaTrader.
Примечание. Этот метод не влияет на кисти со сплошным цветом. Вам нужно будет
использовать только кисть с линейным или радиальным градиентом.

Возвращаемое значение метода


Этот метод не возвращает значения.
Syntax
TransformBrush(SharpDX.Direct2D1.Brush brush, RectangleF rect)
Method Parameters

brush Объект SharpDX.Direct2D1.Brush,


представляющий кисть, используемую для
рендеринга

rect Структура RectangleF, представляющая


прямоугольник для визуализации

Examples

protected override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars


chartBars)
{
TransformBrush(brush, rect);
}

UpBrush
Определение
Объект Brush, используемый для определения цвета рисования полос вверх для ChartStyle.

Примечание. Эта реализация класса Brush в Windows Presentation Forms (WPF) не


используется напрямую для рисования полос на диаграмме. Вместо этого он преобразуется в
кисть SharpDX в свойстве UpBrushDX. Это свойство используется для захвата
пользовательского ввода для изменения цвета кисти.

Стоимость имущества
Объект кисти WPF, используемый для рисования полос вверх
Syntax
UpBrush

Examples

protected override void OnStateChange()


{
if (State == State.Configure)
{
// Устанавливаем новое имя для свойства UpBrush
SetPropertyName("UpBrush", "AdvancingBrush");
}
}

UpBrushDX
Определение
Объект SharpDX Brush, используемый для рисования полос вверх для ChartStyle.

Стоимость имущества
Объект SharpDX Brush, используемый для рисования полос вверх

Syntax
UpBrushDX

Examples

protected override void OnRender(ChartControl chartControl, ChartScale chartScale, ChartBars


chartBars)
{
for (int idx = chartBars.FromIndex; idx <= chartBars.ToIndex; idx++)
{
double closeValue = bars.GetClose(idx);
double openValue = bars.GetOpen(idx);

// Устанавливаем кисть текущей свечи на UpBrushDX или DownBrushDX, в зависимости


от
// направление бара
Brush brush = closeValue >= openValue ? UpBrushDX : DownBrushDX;
}
}

Drawing Tools
AddPastedOffset() Виртуальный метод, который вызывается
каждый раз, когда инструмент рисования
копируется и вставляется в диаграмму.

Anchors Создает набор привязок диаграммы, которые


будут представлять различные точки
инструмента рисования.

AttachedTo Объект, содержащий информацию о том, где


прикреплен инструмент для рисования.

ChartAnchor Определяет объекты, используемые


инструментами рисования, которые
представляют собой точку на диаграмме, где
расположен инструмент рисования.

ConvertToVerticalPixels Используется для преобразования позиции


курсора (в пикселях) в пиксели устройства,
представленные на оси Y диаграммы.

CreateAnchor() Используется для создания новой привязки


диаграммы в указанной точке мыши

DisplayOnChartsMenus Определяет, должен ли инструмент


рисования быть указан в меню инструментов
рисования диаграммы.

Dispose() Освобождает все ресурсы устройства,


используемые для инструмента рисования

DrawingState Представляет текущее состояние


инструмента рисования для выполнения
различных действий, таких как построение,
редактирование или перемещение.

DrawnBy Представляет объект NinjaScript, с помощью


которого был создан инструмент рисования.

GetAttachedToChartBars() Возвращает информацию, относящуюся к


базовой серии стержней, к которой
прикреплен инструмент рисования.

GetClosestAnchor() Возвращает ближайшую привязку диаграммы


в пределах указанного максимального
расстояния от курсора мыши.

GetCursor() Управляемый событиями метод, который


вызывается при выборе объекта диаграммы.
GetSelectionPoints() Возвращает точки данных объекта
диаграммы, с которыми пользователь может
взаимодействовать.

Icon Фигура, которая отображается рядом с


пунктом меню инструмента рисования.

IgnoresSnapping Определяет, будут ли привязки диаграммы


инструмента рисования использовать
координаты мыши режима привязки
диаграммы

IgnoresUserInput Определяет, может ли пользователь


щелкнуть инструмент рисования.

IsAttachedToNinjaScript Указывает, прикреплен ли инструмент


рисования к объекту NinjaScript (например, к
индикатору или стратегии).

IsGlobalDrawingTool Указывает, установлен ли в настоящее время


инструмент рисования как глобальный объект
рисования

IsLocked Определяет, должен ли инструмент


рисования быть заблокирован на месте

IsUserDrawn Указывает, был ли инструмент рисования


нарисован пользователем вручную

OnBarsChanged() Управляемый событиями метод, который


вызывается каждый раз, когда серия базовых
столбцов изменяется для диаграммы, на
которой находится инструмент рисования.

OnMouseDown() Управляемый событиями метод, который


вызывается каждый раз, когда указатель
мыши над элементом управления
диаграммой удерживает нажатой кнопку
мыши.

OnMouseMove() Управляемый событиями метод, который


вызывается каждый раз, когда указатель
мыши находится над элементом управления
диаграммой, а мышь перемещается.

OnMouseUp() Метод, управляемый событиями, вызывается


каждый раз, когда указатель мыши находится
над элементом управления диаграммой и
отпускается кнопка мыши.

SupportsAlerts Указывает, можно ли использовать


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

ZOrderType Определяет порядок, в котором инструмент


рисования будет отображаться
AddPastedOffset()
Определение
Виртуальный метод, который вызывается каждый раз, когда DrawingTool копируется и
вставляется в диаграмму. По умолчанию значение цены якорей графиков смещается вниз на 1
процент. Однако при желании это поведение можно изменить для пользовательского
инструмента рисования.

Возвращаемое значение метода


Этот метод не возвращает значение
Синтаксис
Вы должны переопределить этот метод, используя следующий синтаксис:
public override void AddPastedOffset(ChartPanel panel, ChartScale chartScale)
{

Method Parameters

panel ChartPanel, представляющая панель


диаграммы

chartScale ChartScale, представляющий ось Y

Examples

public override void AddPastedOffset(ChartPanel chartPanel, ChartScale chartScale)


{
foreach (ChartAnchor anchor in Anchors)
{
// толкаем каждый якорь на 1 минуту вправо
DateTime tmpTime = anchor.Time;
anchor.Time = tmpTime.AddMinutes(1);
}
}

Anchors
Определение
Возвращает настраиваемую коллекцию ChartAnchors, которая будет представлять различные
точки инструмента рисования.
Примечание. Вы должны объявить это свойство вместе с привязками диаграммы,
используемыми в инструменте рисования, который вы планируете использовать для итерации.
Откроется простой перечислитель, который позволит вам перебирать якоря диаграммы,
определенные в этом интерфейсе.

Стоимость имущества
Виртуальный интерфейс IEnumerable, состоящий из ChartAnchors

Синтаксис
Вы должны переопределить это свойство, используя следующий синтаксис:
public override IEnumerable<ChartAnchor> Anchors
{

}
Examples
// определяет привязки диаграммы, используемые для инструмента рисования
public ChartAnchor StartAnchor { get; set; }
public ChartAnchor MiddleAnchor { get; set; }
public ChartAnchor EndAnchor { get; set; }

// создаем набор якорей диаграммы, используемых для простой итерации


public override IEnumerable<ChartAnchor> Anchors
{
get
{
return new[] { StartAnchor, MiddleAnchor, EndAnchor };
}
}

// настраиваем экземпляры привязки диаграммы и назначаем отображаемое имя каждому


protected override void OnStateChange()
{
if (State == State.SetDefaults)
{

Name = "My Drawing Tool";

StartAnchor = new ChartAnchor();


MiddleAnchor = new ChartAnchor();
EndAnchor = new ChartAnchor();

StartAnchor.DisplayName = "My Start Anchor";


MiddleAnchor.DisplayName = "My Middle Anchor";
EndAnchor.DisplayName = "My End Anchor";

}
}

// для каждого прохода рендеринга распечатываем отображаемое имя якорей диаграммы


protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
foreach (ChartAnchor anchor in Anchors)
{
Print(anchor.DisplayName);
}
}
AttachedTo
Определение
Объект, содержащий информацию о том, где прикреплен инструмент для рисования.

Доступные свойства

AttachedToType Перечисление, представляющее тип объекта,


к которому прикреплен рисунок. Возможные
значения:

• Bars - столбцы родительского графика.

• GlobalInstrument - столбцы инструмента


пересекли все графики.

• Indicator - индикатор NinjaScript.

• Strategy - стратегия NinjaScript.

ChartObject Интерфейс ChartObject, такой как индикатор,


стратегия, столбцы графика.

DisplayName Строковое значение, указывающее имя


объекта, к которому прикреплен инструмент
рисования.

Instrument Инструмент, к которому прикреплен


инструмент для рисования

Syntax
AttachedTo
Examples

if (AttachedTo.AttachedToType == AttachedToType.Indicator)
// сделай что-нибудьуд

ChartAnchor
Определение
Определяет объекты, используемые инструментами рисования, которые представляют собой
точку на диаграмме, где расположен инструмент рисования.
Syntax
class ChartAnchor
Конструкторы
new ChartAnchor() Инициализирует новый экземпляр объекта
ChartAnchor

new ChartAnchor(DateTime time, double price, Инициализирует новый экземпляр объекта


ChartControl chartControl) ChartAnchor, используя время, цену и
относительный элемент управления
графиком.

new ChartAnchor(DateTime time, double Инициализирует новый экземпляр объекта


yValue, int currentBar, ChartControl ChartAnchor, используя время, координаты
chartControl) оси Y, текущий столбец и относительный
элемент управления диаграммой.

Methods and Properties

CopyDataValues() Копирует значения времени и цены


ChartAnchor из одного якоря в другое.

DisplayName Строковое значение, задающее префикс


имени, используемый для всех свойств
привязки диаграммы.

DrawingTool Инструмент рисования, которому


принадлежит привязка диаграммы

DrawnOnBar Получает текущее значение столбца, на


котором привязка диаграммы нарисована
объектом NinjaScript.

GetPoint() Возвращает точки данных привязки


диаграммы.

IsBrowsable Значение типа bool, определяющее привязку,


отображается в пользовательском
интерфейсе.

IsEditing В настоящее время редактируется значение


типа bool, определяющее привязку.

IsNinjaScriptDrawn Указывает, была ли привязка диаграммы


нарисована объектом NinjaScript

IsXPropertiesVisible Значение типа bool, определяющее свойства


X, отображается в пользовательском
интерфейсе.

IsYPropertyVisible Логическое значение, определяющее


значение данных Y, отображается в
пользовательском интерфейсе.

MoveAnchor() Перемещает значения x и y привязки


диаграммы от начальной точки на величину
дельта-точки.

MoveAnchorX() Перемещает значения x привязки от


начальной точки на величину дельта-точки.
MoveAnchorY() Перемещает значения привязки y от
начальной точки на величину дельта-точки

Price Определяет значение цены, по которой


рисуется привязка графика.

SlotIndex Указывает ближайший паз стержня, в


котором нарисован якорь.

Time Определяет значение даты / времени, когда


отрисовывается привязка диаграммы.

UpdateFromPoint() Обновляет значения x и y привязки из


заданной точки (в пикселях устройства)

UpdateXFromPoint() Обновляет значения X привязки из заданной


точки (в пикселях устройства)

UpdateYFromPoint() Обновляет значение Y привязки из заданной


точки (в пикселях устройства)

Examples

public ChartAnchor MyAnchor { get; set; } // объявляет объект ChartAnchor "MyAnchor"

public override IEnumerable<ChartAnchor> Anchors { get { return new[] { MyAnchor }; } }//


добавляет объект ChartAnchor "MyAnchor" в коллекцию привязок, используемых для
взаимодействия с вашими привязками

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Description = @"Drawing tool example";
Name = "SampleDrawingTool";

MyAnchor = new ChartAnchor();// создает новые экземпляры объекта ChartAnchor


MyAnchor.IsEditing = true;
MyAnchor.DrawingTool = this;
MyAnchor.IsBrowsable = false;
}
}

public override void OnMouseUp(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
if (DrawingState == DrawingState.Editing)
{
if (MyAnchor.IsEditing)
{
// если привязка редактируется, обновляем точку привязки
dataPoint.CopyDataValues(MyAnchor);
}
}
}

CopyDataValues()
Определение
Копирует значения времени и цены ChartAnchor из одного якоря в другое. Сюда входят
значения BarsAgo, SlotIndex, Time, Price и DrawnOnBar. Этот метод полезен для обновления
привязки диаграммы к недавней точке данных, когда пользователь взаимодействует с
привязкой диаграммы на чертеже.

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax

<chartAnchor>.CopyDataValues(ChartAnchor toAnchor)
Method Parameters

toAnchor ChartAnchor для копирования

Examples

public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
// если пользователь перемещает рисованный объект, копируем самый последний dataPoint в
MyAnchor
if (DrawingState == DrawingState.Moving)
dataPoint.CopyDataValues(Anchor);
}

DisplayName
Определение
Устанавливает префикс отображаемого имени, используемый для всех свойств привязки
диаграммы.

Стоимость имущества
Строковое значение, используемое для идентификации имени соответствующей привязки.
Значение по умолчанию - null.

Syntax
<ChartAnchor>.DisplayName

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
MyAnchor = new ChartAnchor();
MyAnchor.DisplayName = "MyChartAnchor";
}
}

DrawingTool
Определение
Объект DrawingTool, которому принадлежит привязка диаграммы.

Стоимость имущества
Объект IDrawingTool, представляющий владельца привязки диаграммы

Syntax
<ChartAnchor>.DrawingTool
Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "SampleDrawingTool";
MyAnchor = new ChartAnchor();
MyAnchor.DrawingTool = this;
//NinjaTrader.NinjaScript.DrawingTools.SampleDrawingTool
}
else if (State == State.Configure)
{

}
}

DrawnOnBar
Определение
Получает текущее значение столбца, на котором привязка диаграммы нарисована объектом
NinjaScript. Пожалуйста, см. Раздел «Чертеж» для получения дополнительной информации.

Примечание. Это значение НЕ будет работать с объектами, нарисованными вручную. Это


свойство зарезервировано для якорей диаграммы, которые были нарисованы другим объектом
NinjaScript (например, с использованием метода Draw в индикаторе). Для объектов,
нарисованных вручную, см. Свойство SlotIndex.

Стоимость имущества
Значение типа int - это значение, на котором отображается текущий столбец, привязанный к
диаграмме. Это свойство доступно только для чтения.

Syntax
<ChartAnchor>.DrawnOnBar

Examples

// Размещает текст, если высокий 2419, и печатает, на какой полосе был нарисован текст
if (High[0] == 2419)
{
Text myText = Draw.Text(this, @"Text " + CurrentBar, @"High is 2419" , 0, High[0]);
Print("Text is on bar " + myText.Anchor.DrawnOnBar);
}

GetPoint()
Определение
Возвращает точку данных привязки диаграммы в пикселях устройства.

Возвращаемое значение метода


Точечная структура; значение точки в пикселях устройства для данной панели и масштаба
диаграммы

Syntax
<chartAnchor>.GetPoint(ChartControl chartControl, ChartPanel chartPanel, ChartScale, [bool
pixelAlign])

Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющий панель


диаграммы

chartScale ChartScale, представляющий ось Y

pixelAlign Необязательный логический тип,


определяющий, следует ли округлять точку
данных до ближайшей точки 0,5 пикселя.

Examples

// получает точки данных привязки диаграммы


Point anchorPoint = MyAnchor.GetPoint(chartControl, chartPanel, chartScale);

IsBrowsable
Определение
Определяет, видна ли привязка в пользовательском интерфейсе. Если установлено значение
true, значения привязки Y и X можно просмотреть в свойствах объектов чертежа.

Стоимость имущества
Значение типа bool, которое, когда оно истинно, будет отображать значения данных привязки
из свойств рисованного объекта; в противном случае - ложь. Значение по умолчанию - истина.
Syntax
<ChartAnchor>.IsBrowsable

Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
MyAnchor = new ChartAnchor();
MyAnchor.IsBrowsable = true;
}
else if (State == State.Configure)
{

}
}

IsEditing
Определение
Определяет, можно ли редактировать привязку.

Стоимость имущества
Значение типа bool, которое, когда оно истинно, определяет, находится ли привязка диаграммы
в состоянии, в котором ее можно редактировать. По умолчанию - false.

Syntax
<ChartAnchor>.IsEditing

Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel,


ChartScale chartScale, Point point)
{
if(DrawingState == DrawingState.Building)
{
// если инструмент рисования в настоящее время редактирует, обновить до текущей
точки мыши
if(MyAnchor.IsEditing)
{
MyAnchor.UpdateFromPoint(point, chartControl, chartScale);

// устанавливаем привязку для отключения редактирования после завершения


обновления
MyAnchor.IsEditing = false;
}
}
}

IsNinjaScriptDrawn
Определение
Указывает, была ли привязка диаграммы нарисована объектом NinjaScript (например,
индикатором или стратегией).

Стоимость имущества
Значение типа bool, которое возвращает true для объекта, было нарисовано другим объектом
NinjaScript; в противном случае - ложь. Это свойство доступно только для чтения.

Syntax
<ChartAnchor>.IsNinjaScriptDrawn
Examples

// разблокирует нарисованный объект NinjaScript и позволяет пользователю изменять


привязку, в то время как объект NinjaScript по-прежнему «владеет» объектом
protected override void OnBarUpdate()
{
foreach(IDrawingTool dt in DrawObjects)
{
DrawingTools.Line sampleLine = dt as DrawingTools.Line;

if (sampleLine != null && sampleLine.StartAnchor.IsNinjaScriptDrawn)


{
sampleLine.IsLocked = false;
Print(sampleLine.StartAnchor.ToString());
}
}
}

IsXPropertiesVisible
Определение
Указывает, что свойства X привязки отображаются в пользовательском интерфейсе. Если
установлено значение true, значения X можно просмотреть в свойствах объектов чертежа.
Стоимость имущества
Значение типа bool, которое, когда оно истинно, будет отображать значения данных X (время)
привязки из свойств рисованного объекта; в противном случае - ложь. Значение по умолчанию -
истина.
Syntax
<ChartAnchor>.IsXPropertiesVisibile
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
MyAnchor = new ChartAnchor();
MyAnchor.IsXPropertiesVisible = true;
}
else if (State == State.Configure)
{

}
}

IsYPropertyVisibile

Определение
Указывает, что свойства Y привязки отображаются в пользовательском интерфейсе. Если
установлено значение true, значения Y можно просмотреть в свойствах объектов чертежа.

Стоимость имущества
Значение типа bool, которое, когда оно истинно, будет отображать значения данных Y (цена)
привязки из свойств рисованного объекта; в противном случае - ложь. Значение по умолчанию -
истина.

Syntax
<ChartAnchor>.IsYPropertyVisibile
Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
MyAnchor = new ChartAnchor();
MyAnchor.IsYPropertyVisibile = true;
}
else if (State == State.Configure)
{

}
}

MoveAnchor()
Определение
Перемещает значения x и y привязки диаграммы от начальной точки на величину дельта-точки.

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax
<ChartAnchor>.MoveAnchor(ChartAnchor startDataPoint, ChartAnchor deltaDataPoint, ChartControl
chartControl, ChartPanel chartPanel, ChartScale chartScale, DrawingTool drawingTool)
Method Parameters

startPoint Значение исходного начального


местоположения привязки диаграммы,
представленное точечной структурой.

startDataPoint Значение исходного начального


местоположения привязки диаграммы,
представленное привязкой диаграммы

deltaPoint Новое значение местоположения привязки


диаграммы, которое будет обновлено,
представлено точечной структурой

deltaDataPoint Новое значение местоположения привязки


диаграммы, которое будет обновлено,
представлено привязкой диаграммы

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

chartPanel ChartPanel, представляющая панель


диаграммы
drawingTool Инструмент рисования, которому
принадлежит перемещаемая привязка
диаграммы (обычно это).

Examples

// перемещаем привязку диаграммы к значениям x и y


MyAnchor.MoveAnchor(lastPoint, newPoint, chartControl, chartPanel, chartScale, this);

MoveAnchorX()
Определение
Перемещает значение x привязки от начальной точки на величину дельта-точки.

Возвращаемое значение метода


Этот метод не возвращает значения.
Syntax
<ChartAnchor>.MoveAnchorX(Point startPoint, Point deltaPoint, ChartControl chartControl,
ChartPanel chartPanel, ChartScale chartScale)
Method Parameters

startPoint Исходное значение начальной точки привязки


диаграммы

deltaPoint Новое значение точки привязки диаграммы


будет обновлено

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

Examples

//move only the chart anchors x (bar/time) value


MyAnchor.MoveAnchorX(lastPoint, newPoint, chartControl, chartScale);

MoveAnchorY()
Определение
Перемещает значение y привязки от начальной точки на величину дельта-точки.
Возвращаемое значение метода
Этот метод не возвращает значения.
Syntax
<ChartAnchor>.MoveAnchorY(Point startPoint, Point deltaPoint, ChartControl chartControl,
ChartScale chartScale)

Method Parameters

startPoint Исходное значение начальной точки привязки


диаграммы

deltaPoint Новое значение точки привязки диаграммы


будет обновлено

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

Examples

// перемещаем только якоря графика Y (цена) значение


MyAnchor.MoveAnchorY(lastPoint, newPoint, chartControl, chartPanel, chartScale);

PriceОп
Определение
Определяет значение цены, по которой рисуется привязка графика.

Стоимость имущества
Двойное значение, представляющее значение цены
Syntax
<ChartAnchor>.Price
Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, Point point)
{
Print(MyAnchor.Price)// печатает точку данных оси Y привязки диаграммы
// 1999.25

SlotIndex
Определение
Указывает значение ближайшего слота бара, где на графике рисуется привязка. В диаграмме с
одной серией всегда будет равное количество слотов и полос, однако для диаграмм с
несколькими сериями могут быть дополнительные слоты по сравнению с серией столбцов, в
которой находится ваш инструмент рисования.

Стоимость имущества
Двойное значение, представляющее текущий бар.

Примечание: значение индекса столбца представлено как двойное, поскольку это возможно (и
вероятно), что данная привязка диаграммы нарисована между столбцами (то есть, если
пользователь рисует инструмент с отключенным режимом привязки).

Syntax
ChartAnchor.SlotIndex
Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
Print(MyAnchor.SlotIndex); // выводит значение ближайшего текущего бара
//4502.02734375
}

П Time

Определение
Определяет значение даты / времени, когда отрисовывается привязка диаграммы.

Стоимость имущества
Значение DateTime, представляющее значение времени
Syntax
<ChartAnchor>.Time
Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel,


ChartScale chartScale, Point point)
{
Print(MyAnchor.Time);//выводит дату и время привязки диаграммы по оси X
// 26.08.2014 18:55:00
}

UpdateFromPoint()
Определение
Обновляет значения x и y привязки из заданной точки (в пикселях устройства).

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax
<ChartAnchor>.UpdateFromPoint(Point point, ChartControl chartControl, ChartScale chartScale)

Method Parameters

point Значение точки привязки диаграммы,


подлежащее обновлению

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

Examples

// устанавливаем точки привязки графика x и y


MyAnchor.UpdateFromPoint(point, chartControl, chartScale);

еремещает значение y п
ривяз

UpdateXFromPoint()ки о
Определение
Обновляет значение X привязки из заданной точки (в пикселях устройства).

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax
<ChartAnchor>.UpdateXFromPoint(Point point, ChartControl chartControl, ChartScale chartScale)
Method Parameters

point Значение точки привязки диаграммы,


подлежащее обновлению

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

Examples

// устанавливаем якоря графика x значение точки


MyAnchor.UpdateXFromPoint(point, chartControl, chartScale);

UpdateYFromPoint()
Определение
Обновляет значение Y привязки из заданной точки (в пикселях устройства).

Возвращаемое значение метода


Этот метод не возвращает значения.
Syntax
<ChartAnchor>.UpdateYFromPoint(Point point, ChartScale chartScale)

Method Parameters

point Значение точки привязки диаграммы,


подлежащее обновлению

chartScale ChartScale, представляющий ось Y

Examples

// устанавливаем якоря графика x значение точки


MyAnchor.UpdateYFromPoint(point, chartScale);

ConvertToVerticalPixels()
Определение
Используется для преобразования позиции курсора (в пикселях) в пиксели устройства,
представленные на оси Y диаграммы. Этот метод потребуется только в том случае, если
заданное вами значение предоставлено в пиксельной точке WPF (например, точка данных,
используемая в OnMouseDown), но вам потребуется значение в отображаемых пикселях
диаграммы. Это полезно при работе с инструментами рисования и диаграммами, которые
имеют несколько панелей диаграмм.

Возвращаемое значение метода


Значение типа int, представляющее преобразованное значение в пикселях устройства.

Syntax
ConvertToVerticalPixels(ChartControl chartControl, ChartPanel chartPanel, double wpfY)

Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющая панель


диаграммы

wpfY double значение, которое необходимо


преобразовать

Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
// получение точки данных привязки диаграммы при щелчке мышью
Point myPoint = dataPoint.GetPoint(chartControl, chartPanel, chartScale);

Print("before convert: " + myPoint.Y);// перед преобразованием: 630,5

// преобразовываем точку данных в пиксели устройства

double yPixel = ConvertToVerticalPixels(chartControl, chartPanel, myPoint.Y);

Print("after convert: " + yPixel); // после преобразования: 1108


}

CreateAnchor()
Определение
Используется для создания новой привязки диаграммы в указанной точке мыши.
Возвращаемое значение метода
Новый ChartAnchor в указанной точке в пикселях устройства.

Syntax
CreateAnchor(Point point, ChartControl chartControl, ChartScale chartScale)
Method Parameters

point Точка в пикселях устройства,


представляющая текущую позицию
курсора мыши

chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
// получаем точку щелчка мышью
Point myPoint = dataPoint.GetPoint(chartControl, chartPanel, chartScale);

// создаем якорь в этой точке


ChartAnchor MyAnchor = CreateAnchor(myPoint, chartControl, chartScale);

Print(MyAnchor.Time); // 3/16/2015 8:18:48 AM


}

DisplayOnChartsMenus
Определение
Определяет, отображается ли инструмент рисования в меню инструментов рисования
диаграммы.

Стоимость имущества
Значение типа bool, если true, инструмент рисования будет создан в меню инструментов
рисования диаграммы; в противном случае - ложь. Значение по умолчанию - истина.
Syntax

DisplayOnChartsMenus

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = @"My Drawing Tool";
DisplayOnChartsMenus = true;
}
}

Dispose()

Определение
Освобождает все ресурсы устройства, используемые для инструмента рисования.

Возвращаемое значение метода


Этот метод не возвращает значение

Синтаксис
Утилизировать ()

Параметры метода
Этот метод не принимает никаких параметров

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = @"My Drawing Tool";
}
else if (State == State.Terminated)
Dispose();
}

DrawingState
Определение
Представляет текущее состояние инструмента рисования для выполнения различных
действий, таких как построение, редактирование или перемещение.

Стоимость недвижимости
Перечисление, представляющее текущее состояние инструмента рисования. Возможные
значения:

DrawingState.Building Начальное состояние при первом рисовании


инструмента рисования, позволяющее
установить привязки для рисования.

DrawingState.Editing Позволяет изменять значения любого из


якорей инструментов рисования.

DrawingState.Normal Инструмент рисования нормально


отображается на диаграмме и не находится в
состоянии, позволяющем вносить изменения.

DrawingState.Moving Весь инструмент рисования должен быть


перемещен пользователем.

Syntax
DrawingState
Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, Point point)
{
switch(DrawingState)
{
case DrawingState.Normal:
DrawingState = DrawingState.Editing; // устанавливаем состояние, чтобы разрешить
редактирование
break;
case DrawingState.Editing:
// сделайте здесь свои правки
break;
case DrawingState.Moving:
return; // не разрешать перемещение при редактировании
}

DrawnBy
Определение
Представляет объект NinjaScript, создавший объект рисования.

Стоимость имущества
Объект NinjaScript, создавший инструмент рисования; это значение будет нулевым, если
нарисовано пользователем.
Syntax
DrawnBy

Examples

protected override void OnRender(ChartControl chartControl, ChartScale chartScale)


{
// если инструмент рисования был создан не пользователем,
// выводим имя созданного объекта
if(!IsUserDrawn)
Print(DrawnBy.Name);
}

GetAttachedToChartBars()
Определение
Возвращает информацию, относящуюся к базовой серии стержней, к которой
прикреплен инструмент рисования. Если инструмент рисования прикреплен к
индикатору, а не к серии столбцов, будут возвращены серии столбцов индикатора,
используемые для ввода.

Примечание. Для инструментов рисования, сделанных глобальными, этот метод не


будет возвращать значимые значения, поскольку они не привязаны к определенной
серии столбцов.
Возвращаемое значение метода
Объект ChartBars
Syntax
GetAttachedToChartBars()
Параметры метода
Этот метод не принимает никаких параметров

Examples

protected override void OnRender(ChartControl chartControl, ChartScale chartScale)


{
// получаем прикрепленные бары графика
ChartBars myBars = GetAttachedToChartBars();

Print(myBars.Bars.ToChartString()); // NQ 03-15 (1 Minute)


}

GetClosestAnchor()
// получаем attDefinition
Возвращает ближайшую привязку диаграммы в пределах указанного максимального
расстояния от курсора мыши.

Возвращаемое значение метода


Этот метод возвращает существующие столбцы диаграммы ChartAnchorached.

Syntax
GetClosestAnchor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, double
maxDist, Point point)
Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющая панель


диаграммы

chartScale ChartScale, представляющий ось Y

maxDist Двойное значение, представляющее


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

point Точка в пикселях устройства,


представляющая текущую позицию курсора
мыши

Examples
public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale
chartScale, Point point)
{
// получаем ближайшую привязку к тому месту, где щелкнул пользователь
ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, 10, point);

if (closest != null)
{
// устанавливаем курсор, чтобы указать, что его можно перемещать
return Cursors.SizeNWSE;
}
// в противном случае установите курсор обратно на стрелку
else return Cursors.Arrow;
}

GetCursor()
Определение
Управляемый событиями метод, который вызывается при выборе объекта диаграммы. Этот
метод можно использовать для изменения изображения курсора, используемого в различных
состояниях.

Возвращаемое значение метода


Этот метод возвращает Cursor, используемый для рисования указателя мыши.

Синтаксис
Вы должны переопределить метод в Инструменте рисования, используя следующий синтаксис:

public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, Point point)
{

}
Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющая панель


диаграммы

chartScale ChartScale, представляющий ось Y


point Точка в пикселях устройства,
представляющая текущую позицию курсора
мыши

Examples

public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, Point point)
{
switch (DrawingState)
{
// при рисовании отображать курсор как перо
case DrawingState.Building: return Cursors.Pen;

// при движении отображать четырехконечный курсор для изменения размера


case DrawingState.Moving: return Cursors.SizeAll;

default: return Cursors.Pen;


}
}

GetSelectionPoints()
Определение
Возвращает точки данных объекта диаграммы, с которыми пользователь может
взаимодействовать. Эти точки используются для визуального обозначения того, что объект
диаграммы выбран, и позволяют пользователю манипулировать этим объектом. Этот метод
вызывается только в том случае, если IsSelected имеет значение true.

Возвращаемое значение метода


Коллекция точек, представляющих координаты x и y объекта диаграммы.

Синтаксис
Вы должны переопределить метод, используя следующий синтаксис:
public override Point[] GetSelectionPoints(ChartControl chartControl, ChartScale chartScale)
{

Method Parameters
chartControl ChartControl, представляющий ось x

chartScale ChartScale, представляющий ось Y

Examples

public override Point[] GetSelectionPoints(ChartControl chartControl, ChartScale chartScale)


{

ChartPanel chartPanel = chartControl.ChartPanels[chartScale.PanelIndex];

// получаем точку привязки для отображения на инструменте рисования


Point anchorPoint = Anchor.GetPoint(chartControl, chartPanel, chartScale, false);
return new[] { anchorPoint } ;
}

Icon
Определение
Фигура, которая отображается рядом с пунктом меню «Инструмент рисования». Поскольку это
стандартный объект, можно использовать любой тип значка (символы Юникода,
пользовательский ресурс файла изображения, путь геометрии и т. Д.). Дополнительные
сведения об использовании изображений для создания значков см. На странице
«Использование изображений с настраиваемыми значками».

Примечание. При использовании символов UniCode сначала убедитесь, что нужные символы
существуют в пакете значков для семейства шрифтов, используемого в NinjaTrader.

Стоимость имущества
Общий виртуальный объект, представляющий значок меню инструментов рисования. Это
свойство доступно только для чтения.

Syntax

Вы должны переопределить это свойство, используя следующий синтаксис:

public override object Icon


Examples

public override object Icon


{
get
{
// используем символ Юникода в качестве нашей строки, которая будет отображать
стрелку
string uniCodeArrow = "\u279A";
return uniCodeArrow;
}
}

IgnoresSnapping
Определение
Определяет, будут ли привязки диаграммы инструмента рисования использовать координаты
мыши режима привязки диаграммы.

Стоимость имущества
Логическое значение, при котором инструмент рисования игнорирует привязку; в противном
случае - ложь. По умолчанию установлено значение false.

Syntax
IgnoresSnapping

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IgnoresSnapping = true;// Установите значение true, чтобы получать координаты мыши
без привязки
}
else if (State == State.Configure)
{

}
}
IgnoresUserInput
Определение
Определяет, может ли пользователь щелкнуть инструмент рисования.

Стоимость имущества
Значение типа bool, которое становится истинным, если пользователь не может
взаимодействовать с инструментом рисования; в противном случае - ложь. По умолчанию
установлено значение false.

Syntax
IgnoresUserInput

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{

IgnoresUserInput = true; // Установите значение true, чтобы сделать объект


рисования неинтерактивным
}
else if (State == State.Configure)
{

}
}

IsAttachedToNinjaScript
Определение
Указывает, прикреплен ли в настоящее время инструмент рисования к объекту NinjaScript
(например, к индикатору или стратегии).

Стоимость имущества
Значение типа bool, которое имеет значение true, если инструмент рисования прикреплен к
объекту NinjaScript; в противном случае - ложь. Это свойство доступно только для чтения.
Syntax
IsAttachedToNinjaScript

Examples

public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
// не взаимодействуют, если нарисованы индикатором или стратегией
if (IsAttachedToNinjaScript)
return;
}

IsGlobalDrawingTool
Определение
Указывает, установлен ли в настоящее время инструмент рисования как глобальный объект
рисования. Глобальные рисованные объекты отображаются на любой диаграмме, которая
соответствует базовому инструменту родительской диаграммы.

Стоимость имущества
Значение типа bool, которое возвращает истину, если инструмент рисования в настоящее
время присоединен как глобальный объект рисования; в противном случае - ложь.
Syntax
IsGlobalDrawingTool

Examples

public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
// не взаимодействуем, если привязаны к глобальному графику
if (IsGlobalDrawingTool)
return;
}

IsLocked
Определение
Определяет, нужно ли зафиксировать инструмент рисования на месте. Это свойство можно
установить вручную через пользовательский интерфейс или явно с помощью кода.
Стоимость имущества
Значение типа bool, которое имеет значение true, если инструмент рисования заблокирован; в
противном случае - ложь. По умолчанию установлено значение false.

Примечание. Для инструментов рисования, которые рисуются индикатором или стратегией, это
свойство по умолчанию имеет значение true.
Syntax
IsLocked

Examples

public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, Point point)
{
if (IsLocked)
// если объект заблокирован, не пытайтесь двигаться
return;
}

IsUserDrawn
Определение
Указывает, был ли инструмент рисования нарисован пользователем вручную, а не программно
нарисован объектом NinjaScript (например, индикатором или стратегией).

Стоимость имущества
Значение типа bool, которое имеет значение true, если рисованный объект был нарисован
вручную; в противном случае - ложь. Это свойство доступно только для чтения

Syntax
IsUserDrawn
Examples

if (IsUserDrawn)
{
// что-то делаем, только если объект нарисован вручную
}
OnBarsChanged()
Определение
Управляемый событиями метод, который вызывается каждый раз при изменении ряда базовых
столбцов для диаграммы, на которой находится инструмент рисования. Например, если
пользователь изменил основной инструмент или временные рамки баров, используемых на
графике.

Возвращаемое значение метода


Этот метод не возвращает значение

Синтаксис
Вы должны переопределить этот метод, используя следующий синтаксис:
public override void OnBarsChanged()
{

}
Параметры метода
Этот метод не принимает никаких параметров
Examples

public override void OnBarsChanged()


{
// бары изменились, сделайте что-нибудь
}

OnMouseDown()
Определение
Управляемый событиями метод, который вызывается каждый раз, когда указатель мыши над
элементом управления диаграммой удерживает нажатой кнопку мыши.

Возвращаемое значение метода


Этот метод не возвращает значения.

Примечание: для комбинированной операции с одним щелчком, то есть щелчка мышью,


перемещения и освобождения, указанная точка данных всегда будет начальной начальной.
Синтаксис
Вы должны переопределить метод в Инструменте рисования, используя следующий синтаксис.
public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{

}
Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющая панель


диаграммы

chartScale ChartScale, представляющий ось Y

dataPoint ChartAnchor, представляющий точку, в


которой пользователь щелкнул

Examples

public override void OnMouseDown(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
switch (DrawingState)
{
case DrawingState.Building:
dataPoint.CopyDataValues(Anchor);
Anchor.IsEditing = false;
DrawingState = DrawingState.Normal;
IsSelected = false;
break;
case DrawingState.Normal:
// убедитесь, что они щелкнули рядом с нами. используйте GetCursor, если что-то имеет
более одной точки
Point point = dataPoint.GetPoint(chartControl, chartPanel, chartScale);
if (GetCursor(chartControl, chartPanel, chartScale, point) != null)
DrawingState = DrawingState.Moving;
else
IsSelected = false;
break;
}
}
OnMouseMove()
Определение
Управляемый событиями метод, который вызывается каждый раз, когда указатель мыши
находится над элементом управления диаграммой, а мышь перемещается.

Возвращаемое значение метода


Этот метод не возвращает значения.

Примечание: для комбинированной операции с одним щелчком, то есть щелчка мышью,


перемещения и освобождения, указанная точка данных всегда будет начальной начальной.

Синтаксис
Вы должны переопределить метод в Инструменте рисования, используя следующий синтаксис.
public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{

Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющая панель


диаграммы

chartScale ChartScale, представляющий ось Y

dataPoint ChartAnchor, представляющий точку, в


которой пользователь перемещает мышь.

private ChartAnchor lastMouseMoveAnchor = new ChartAnchor();


private ChartAnchor MyAnchor;
public override void OnMouseMove(ChartControl chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{
// добавляем любую логику, когда сюда перемещается мышь
if (DrawingState == DrawingState.Moving)
{
// перемещаем привязку диаграммы, когда инструмент рисования находится в состоянии
перемещения
MyAnchor.MoveAnchor(lastMouseMoveAnchor, dataPoint, chartControl, chartPanel, chartScale,
this);
// не забудьте обновить дельта-точку до последней использованной!
dataPoint.CopyDataValues(lastMouseMoveAnchor);
}
}

OnMouseUp()
Определение
Метод, управляемый событиями, вызывается каждый раз, когда указатель мыши находится над
элементом управления диаграммой и отпускается кнопка мыши.

Возвращаемое значение метода


Этот метод не возвращает значение

Примечание: для комбинированной операции с одним щелчком, то есть щелчка мышью,


перемещения и освобождения, указанная точка данных всегда будет начальной начальной.

Синтаксис
Вы должны переопределить метод, используя следующий синтаксис.
public override void OnMouseUp(ChartControl chartControl, ChartPanel chartPanel, ChartScale
chartScale, ChartAnchor dataPoint)
{

}
Method Parameters

chartControl ChartControl, представляющий ось x

chartPanel ChartPanel, представляющая панель


диаграммы

chartScale ChartScale, представляющий ось Y

dataPoint ChartAnchor, представляющий точку, в


которой пользователь отпускает мышь.

Examples

public override void OnMouseUp(ChartControl chartControl, ChartPanel chartPanel, ChartScale


chartScale, ChartAnchor dataPoint)
{
// когда пользователь отпускает мышь, убедитесь, что состояние рисования установлено на
нормальное
if (DrawingState == DrawingState.Editing || DrawingState == DrawingState.Moving)
DrawingState = DrawingState.Normal;
}

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

Стоимость имущества
Логическое значение, которое при истине определяет, что пользователь может настроить
предупреждение на основе этого инструмента рисования; в противном случае - ложь.

Примечание. По умолчанию это свойство имеет значение false и ДОЛЖНО быть


переопределено при инициализации, чтобы можно было настроить оповещения вручную. Вы не
можете установить это во время выполнения.
Syntax
SupportsAlerts

Вы можете переопределить это свойство, используя следующий синтаксис:


public override bool SupportsAlerts
Examples

public override bool SupportsAlerts { get { return true; } }

ZOrderType
Определение
Определяет порядок, в котором инструмент рисования будет отображаться. Это поможет
контролировать индекс ZOrder между объектами диаграммы.

Стоимость имущества
Перечисление, определяющее тип ZOrder инструмента рисования. Возможные значения:

DrawingToolZOrder.Normal Поведение по умолчанию, инструменты


рисования отображаются так, как они
отображаются в индексе ZOrder.

DrawingToolZOrder.AlwaysDrawnFirst Гарантирует, что инструмент рисования


всегда отображается первым

DrawingToolZOrder.AlwaysDrawnLast Гарантирует, что инструмент рисования


всегда является последним объектом для
рендеринга

Syntax
ZOrderType

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = @"My Drawing Tool";

// всегда рисуем это последним


ZOrderType = DrawingToolZOrder.AlwaysDrawnLast;
}
else if (State == State.Configure)
{
}
}

Import Type
Могут быть разработаны пользовательские типы импорта данных, позволяющие
импортировать исторические данные из любого формата. В этом разделе описаны два важных
метода обработчика событий:
Methods and Properties

OnNextInstrument() Вызывается в начале процесса импорта

OnNextDataPoint() Вызывается для каждой строки данных,


содержащихся в импортируемом файле.

OnNextInstrument()
Определение
Метод OnNextInstrument () вызывается в начале процесса импорта для каждого
импортируемого файла. Этот метод вызывается только после того, как он определит, что файл
содержит допустимый инструмент.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
См. Пример ниже. Мастер кода NinjaScript автоматически сгенерирует для вас синтаксис
метода.

Example

private int currentInstrumentIdx = -1;

public string[] FileNames


{ get; set; }

protected override void OnNextInstrument()


{
if (FileNames == null)
return;

// Пытаемся читать из файла в массив FileNames, созданный выше


// Регистрируем ошибку и продолжаем, если данные не читаются

try
{
reader = new StreamReader(FileNames[currentInstrumentIdx]);
}
catch (Exception exp)
{
NinjaScript.Log(FileNames[currentInstrumentIdx], exp.Message, LogLevel.Error);
continue;
}
}

OnNextDataPoint()
Определение
Метод OnNextDataPoint () вызывается для каждой строки данных, содержащихся в
импортируемом файле. Этот метод вызывается только в том случае, если тип импорта
определяет, что файл имеет допустимую точку данных, и будет продолжать вызываться до тех
пор, пока не достигнет конца файла или пока точка данных не станет недействительной.

Возвращаемое значение метода


Этот метод не возвращает значения.
Синтаксис
См. Пример ниже. Мастера кода NinjaScript автоматически генерируют синтаксис метода для
вас.

Example

private StreamReader reader;

protected override void OnNextDataPoint()


{
if (reader == null)
return;

// Постоянно считываем данные с помощью StreamReader, определенного выше


while (true)
{
DataPointString = reader.ReadLine();
// Дополнительное форматирование данных здесь
}
}

Indicator
Методы и свойства, описанные в этом разделе, уникальны для разработки пользовательских
индикаторов. Свойства конфигурации индикатора глобально определяют различное поведение
индикаторов. Все свойства имеют значения по умолчанию и могут быть переопределены, задав
их в методе OnStateChange () индикатора.

Совет: См. Также раздел «Общие» для получения дополнительных сведений о методах и
свойствах, которые являются общими для типов NinjaScript.

Methods and Properties

AddLine() Добавляет линейные объекты на график.

AddPlot() Добавляет объекты графика, которые


определяют способ отображения ряда
данных индикатора или стратегии на
графике.

BarsRequiredToPlot Количество столбцов на графике,


необходимое перед построением скрипта.

DisplayInDataBox Определяет, отображаются ли графики в


поле данных диаграммы.

DrawHorizontalGridLines Строит горизонтальные линии сетки на


панели индикатора.

DrawOnPricePanel Определяет панель диаграммы,


отображаемую рисованными объектами.

DrawVerticalGridLines Строит вертикальные линии сетки на панели


индикатора.

IndicatorBaseConverter Пользовательский класс TypeConverter,


обрабатывающий разработанное поведение
коллекции дескрипторов свойств индикатора.

IsChartOnly Если установлено значение true, любой


индикатор будет доступен только для
построения графиков - индикаторы с
включенным этим свойством, например, не
должны отображаться при вызове в окне
SuperDOM или MarketAnalyzer.

IsSuspendedWhileInactive Предотвращает возникновение событий


рыночных данных в реальном времени, пока
функция хостинга индикатора находится в
состоянии, которое можно было бы считать
приостановленным и не используемым
пользователем немедленно.

PaintPriceMarkers Если true, любые значения графиков


индикатора отображают ценовые маркеры по
оси Y.

ShowTransparentPlotsInDataBox Определяет, отображаются ли значения


графиков, для которых установлена
прозрачная кисть, в поле данных диаграммы.

AddLine()
Определение
Добавляет линейные объекты на график.

Примечание. Строки видны ТОЛЬКО из сетки свойств пользовательского интерфейса, когда


AddLine () вызывается из State.SetDefaults. Если ваш индикатор или стратегия динамически
добавляет линии во время State.Configure, у вас НЕ будет возможности выбрать линию или
установить конфигурацию линии через пользовательский интерфейс. В качестве альтернативы
вы можете использовать настраиваемые общедоступные свойства Brush, Stroke или значения,
которые доступны в State.SetDefaults, и передавать эти значения в AddLine () во время
State.Configure. Вызов AddLine () таким образом следует зарезервировать для особых случаев.
См. Примеры ниже.
Methods and Properties
AreLinesConfigurable Определяет, можно ли настроить линии,
используемые в индикаторе, из диалогового
окна индикатора.

Line Class Объекты, производные от класса Line,


используются для характеристики
визуального отображения (построения) линии
осциллятора на графике.

Lines Коллекция, содержащая все объекты Line,


которые определяют линии осциллятора
характеристик визуализации индикатора.

Syntax
AddLine(Brush brush, double value, string name)
AddLine(Stroke stroke, double value, string name)

Предупреждение: этот метод должен вызываться ТОЛЬКО в методе OnStateChange () во время


State.SetDefaults или State.Configure
Parameters

brush Объект Brush, используемый для построения


линии

name Строковое значение, представляющее имя


строки

stroke Объект Stroke, используемый для построения


линии

value Двойное значение, представляющее


значение, при котором линия будет
нарисована

Examples
Defining a single UI configurable static line

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "Examples Indicator";
// Добавляем линию осциллятора со значением 30
AddLine(Brushes.Gray, 30, "Lower");
}
}
Indicator which dynamically adds a line in State.Configure

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "Examples Indicator";

// логическое свойство, которое может установить пользователь


UseSpecialMode = false;
// Выбор кисти по умолчанию передан в пользовательский интерфейс
MyBrush = Brushes.Red;
}
else if (State == State.Configure)
{
// если пользователь разрешает логическое свойство
if (UseSpecialMode)
{
// добавляем линию, используя выбранную по умолчанию кисть и специальное
имя линии
AddLine(MyBrush, 40, "My Special Line");
}
else
{
// в противном случае использовать выбранную кисть по умолчанию и обычное
имя линии
AddLine(MyBrush, 60, "My Regular Line");
}
}
}

[XmlIgnore]
public Brush MyBrush { get; set; }

public bool UseSpecialMode { get; set; }

AreLinesConfigurable
Определение
Определяет, можно ли настроить линии, используемые в индикаторе, из диалогового окна
индикатора.

Стоимость имущества
Логическое значение, которое имеет значение true, если какие-либо линии индикатора можно
настроить; в противном случае - ложь. По умолчанию установлено значение true.

Syntax
AreLinesConfigurable

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
AddLine(Brushes.Gray, 30, "Lower");
AreLinesConfigurable = false;// Индикаторные линии не настраиваются
}
}

Line Class
Определение
Объекты, производные от класса Line, используются для характеристики визуального
отображения (построения) линии осциллятора на графике.
Syntax
Line(Stroke stroke)
Parameters

stroke Стиль обводки

Lines
Определение
Коллекция, содержащая все объекты Line, которые определяют линии осциллятора
характеристик визуализации индикатора.

Стоимость имущества
Коллекция объектов Line.
Syntax
Lines[int index]

Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
// Строки добавляются в коллекцию Lines по порядку
AddLine(Brushes.Gray, 30, "Lower"); // Сохраняется в строках [0]
AddLine(Brushes.Gray, 70, "Upper"); // Сохраняется в строках [1]
}
}

// Динамически меняем цвет и толщину верхней линии в зависимости от значения


индикатора
protected override void OnBarUpdate()
{
if(Value[0] > 70)
{
Lines[1].Brush = Brushes.Blue;
Lines[1].Width = 3;
}
else
{
Lines[1].Brush = Brushes.Gray;
Lines[1].Width = 1;
}
}

AddPlot()
Определение
Добавляет объекты графика, которые определяют способ отображения ряда данных
индикатора или стратегии на графике. Когда этот метод вызывается для добавления графика,
создается связанный объект Series <double>, содержащийся в коллекции Values.

Примечание. Графики видны ТОЛЬКО из сетки свойств пользовательского интерфейса, когда


AddPlot () вызывается из State.SetDefaults. Если ваш индикатор или стратегия динамически
добавляет графики во время State.Configure, у вас НЕ будет возможности выбрать график или
установить конфигурацию графика через пользовательский интерфейс. В качестве
альтернативы вы можете использовать настраиваемые общедоступные свойства Brush, Stroke
или PlotStyle, которые доступны в State.SetDefaults, и передавать эти значения в AddPlot () во
время State.Configure. Вызов AddPlot () таким образом следует зарезервировать для особых
случаев. См. Примеры ниже.

Methods and Properties


ArePlotsConfigurable Определяет, можно ли настроить графики,
используемые в индикаторе, в диалоговом
окне индикатора.

Displacement Значение смещения, которое сдвигает


визуально отображаемое значение
индикатора.

PlotBrushes Содержит массив объектов цветовой серии,


содержащих исторические цвета столбцов.

Plots Коллекция, содержащая все объекты Plot,


определяющие их характеристики
визуализации.

Syntax
AddPlot(Brush brush, string name)
AddPlot(Stroke stroke, PlotStyle plotStyle, string name)
Предупреждение: этот метод должен вызываться ТОЛЬКО в методе OnStateChange () во время
State.SetDefaults или State.Configure

Parameters

brush Объект Brush, используемый для построения


графика.

name Строка, представляющая название сюжета.

plotStyle Объект PlotStyle, используемый для создания


стиля графика.

Возможные значения:

PlotStyle.Bar
PlotStyle.Block
PlotStyle.Cross
PlotStyle.Dot
PlotStyle.Hash
PlotStyle.HLine
PlotStyle.Line
PlotStyle.PriceBox
PlotStyle.Square
PlotStyle.TriangleDown
PlotStyle.TriangleLeft
PlotStyle.TriangleRight
PlotStyle.TriangleUp
stroke Объект Stroke, используемый для построения
графика

Советы:

1. Мы предлагаем использовать мастер NinjaScript для создания ваших сюжетов.

2. Объекты графика НЕ содержат фактических значений скрипта. Они просто определяют, как
значения скрипта отображаются на диаграмме.

3. Сценарий может вычислять несколько значений и, следовательно, содержать несколько


графиков для определения отображения каждого рассчитанного значения. Значения скрипта
хранятся в коллекции Values скрипта.

4. Если сценарий вызывает AddPlot () несколько раз, то добавляются несколько серий значений
в соответствии с примером «серии из трех значений» ниже.

5. Для скриптов MultiSeries графики синхронизируются с первичной серией объекта NinjaScript.

6. Графики станут видимыми после того, как будет выполнено значение BarsRequiredToPlot
скрипта. По умолчанию значение 20.

Examples
Индикатор, использующий различные сигнатуры AddPlot ()
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "Examples Indicator";

// Добавляет график в стиле синей линии


AddPlot(Brushes.Blue, "MyPlot");

// Добавляет график в стиле синей гистограммы


AddPlot(new Stroke(Brushes.Blue), PlotStyle.Bar, "MyPlot");

// Ensures that the width of the PlotStyle.Bar plot matches the width of the data series
Plots[0].AutoWidth = true;
}
}
Индикатор, использующий публичную серию <double> для отображения
графика с понятным именем.

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "Examples Indicator";

// Добавляет график в стиле синей линии


AddPlot(Brushes.Blue, "MyPlot");

// Добавляет график в стиле синей гистограммы


AddPlot(new Stroke(Brushes.Blue), PlotStyle.Bar, "MyPlot");
}
}

[Browsable(false)]
[XmlIgnore]
public Series<double> MyPlot
{
get { return Values[0]; }
}

Индикатор, складывающий три ряда значений


protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "Examples Indicator";

// Добавляем три графика и связанные объекты Series <double>


AddPlot(Brushes.Blue, "PlotA"); // Определяет график для значений [0]
AddPlot(Brushes.Red, "PlotB"); // Определяет график для значений [1]
AddPlot(Brushes.Green, "PlotC"); // Определяет график для значений [2]
}
}
protected override void OnBarUpdate()
{
Values[0][0] = Median[0]; // Blue "Plot A"
Values[1][0] = Low[0]; // Red "Plot B"
Values[2][0] = High[0]; // Green "Plot C"
}

Индикатор, который динамически добавляет график в State.Configure


protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "Examples Indicator";
// в противном случае использовать выбранную кисть по умолчанию и обычное имя
графика
// логическое свойство, которое может установить пользователь
UseSpecialMode = false;
// Выбор кисти по умолчанию передан в пользовательский интерфейс
MyBrush = Brushes.Red;
}
else if (State == State.Configure)
{
// если пользователь разрешает логическое свойство
if (UseSpecialMode)
{
// добавляем график, используя выбранную по умолчанию кисть и специальное имя
графика
AddPlot(MyBrush, "My Special Plot");
}
else
{
// в противном случае использовать выбранную кисть по умолчанию и обычное имя
графика
AddPlot(MyBrush, "My Regular Plot");
}
}
}

protected override void OnBarUpdate()


{
if (UseSpecialMode)
Value[0] = Close[0] + High[0] / 2;

else Value[0] = Close[0] * TickSize / 2;


}

[XmlIgnore]
public Brush MyBrush { get; set; }

public bool UseSpecialMode { get; set; }

ArePlotsConfigurable
Определение
Определяет, можно ли настроить графики, используемые в индикаторе, в диалоговом окне
индикатора.

Стоимость имущества
Логическое значение, которое возвращает истину, если любой индикаторный график можно
настроить; в противном случае - ложь. По умолчанию установлено значение true.
Syntax
ArePlotsConfigurable

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
AddPlot(Brushes.Orange, "SMA");
ArePlotsConfigurable = false;// Графики не настраиваются в диалоге индикатора
}
}

Displacement
Определение
Значение смещения, которое сдвигает визуально отображаемое значение индикатора.

Стоимость имущества
Значение типа int, представляющее количество баров назад, на которое нужно смещаться.
Syntax
Displacement
Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Displacement = 2;// Строит значение индикатора 2 бара назад на текущем баре
AddPlot(Brushes.Orange, "SMA");
}
}

PlotBrushes
Определение
Содержит массив объектов цветовой серии, содержащих исторические цвета столбцов. Объект
цветовой серии добавляется к этому массиву при вызове метода AddPlot () в настраиваемом
индикаторе для графиков. Его цель - предоставить доступ к свойству цвета всех полос.

Стоимость имущества
Массив объектов цветовой серии.
Syntax
PlotBrushes[int PlotIndex][int barsAgo]
Examples
protected override void OnStateChange()
{
if(State == State.SetDefaults)
{
Name = "Example Indicator";
// Добавляем два графика
AddPlot(Brushes.Blue, "Upper");
AddPlot(Brushes.Orange, "Lower");
}
}

protected override void OnBarUpdate()


{
// Устанавливаем значения для наших двух графиков
Upper[0] = SMA(High, 20)[0];
Lower[0] = SMA(Low, 20)[0];

// Раскрашиваем верхний график в зависимости от условий значения графика


if (IsRising(Upper))
PlotBrushes[0][0] = Brushes.Blue;
else if (IsFalling(Upper))
PlotBrushes[0][0] = Brushes.Red;
else
PlotBrushes[0][0] = Brushes.Yellow;

// Раскрашиваем нижний график в зависимости от условий значения графика


if (IsRising(Lower))
PlotBrushes[1][0] = Brushes.Blue;
else if (IsFalling(Lower))
PlotBrushes[1][0] = Brushes.Red;
else
PlotBrushes[1][0] = Brushes.Yellow;
}

public Series<double> Upper


{
get { return Values[0]; }
}

public Series<double> Lower


{
get { return Values[1]; }
}
Plots
Определение
Коллекция, содержащая все объекты Plot, определяющие их характеристики визуализации.

Стоимость имущества
Коллекция объектов Plot.

Syntax
Plots[int index]
Примечание. В приведенном ниже примере кода изменится цвет всей серии графиков. См.
PlotBrushes для получения информации об изменении вместо этого только определенных
сегментов графика.

Example

protected override void OnStateChange()


{
if(State == State.SetDefaults)
{
Name = "Examples Indicator";
// Строки добавляются в коллекцию Lines по порядку
AddPlot(Brushes.Orange, "Plot1"); // Сохраняется в Plots [0]
AddPlot(Brushes.Blue, "Plot2"); // Сохраняется в Plots [1]
}
}

// Динамически меняем цвет основного графика в зависимости от значения индикатора


protected override void OnBarUpdate()
{
if (Value[0] > 70)
{
Plots[0].Brush = Brushes.Blue;
Plots[0].Width = 2;
}
else
{
Plots[0].Brush = Brushes.Red;
Plots[0].Width = 2;
}
}
BarsRequiredToPlot
Определение
Количество столбцов на графике, необходимое перед построением скрипта. По умолчанию
значение составляет 20 баров.

Примечание. Это свойство НЕ совпадает с минимальным количеством столбцов, необходимых


для расчета значений скрипта. OnBarUpdate всегда начинает вычисление для первого бара на
графике (CurrentBar 0)

Стоимость имущества
Значение типа int, представляющее минимальное количество необходимых столбцов.
Syntax
BarsRequiredToPlot

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
BarsRequiredToPlot = 10; // Не строить до 11-го бара на графике
AddPlot(Brushes.Orange, "SMA");
}
}

DisplayInDataBox
Определение
Определяет, отображаются ли графики в поле данных диаграммы.

Стоимость имущества
Это свойство возвращает истину, если значения графика (графиков) индикатора отображаются
в поле данных диаграммы; в противном случае - ложь. По умолчанию установлено значение
true.
Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()
во время State.SetDefaults или State.Configure

Syntax
DisplayInDataBox
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DisplayInDataBox = false;
AddPlot(Brushes.Orange, "SMA");
}
}

DrawHorizontalGridLines
Определение
Строит горизонтальные линии сетки на панели индикатора.

Примечание. На родительском графике панели индикатора есть аналогичная опция «Линия


сетки - горизонтальная», которая, если для свойства Visible установлено значение false,
переопределит локальную настройку индикатора, если она установлена.

Стоимость имущества
Это свойство возвращает истину, если на панели индикатора нанесены горизонтальные линии
сетки; в противном случае - ложь. По умолчанию установлено значение true.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure
Syntax
DrawHorizontalGridLines
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DrawHorizontalGridLines = false; // Горизонтальные линии сетки не будут отображаться
на панели индикатора
AddPlot(Brushes.Orange, "SMA");
}
}

DrawOnPricePanel
Определение
Определяет панель диаграммы, отображаемую рисованными объектами.

Стоимость имущества
Это свойство возвращает истину, если индикатор рисует рисованные объекты на ценовой
панели; в противном случае, если установлено значение false, рисованные объекты рисуются
на самой панели индикатора. По умолчанию установлено значение true.

Предупреждение: это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults. Динамическое использование DrawOnPricePanel в индикаторе за
пределами State.SetDefaults может отображать проблемы при работе с этим индикатором через
стратегию хостинга через AddChartIndicator ().
Syntax
DrawOnPricePanel
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DrawOnPricePanel = false; // Рисуем объекты теперь рисуют на самой панели
индикатора
AddPlot(Brushes.Orange, "SMA");
}

DrawVerticalGridLines
Определение
Строит вертикальные линии сетки на панели индикатора.

Примечание. На родительском графике панели индикатора есть аналогичная опция «Линия


сетки - вертикальная», которая, если для свойства Visible установлено значение false,
переопределит локальную настройку индикатора, если она истинна.

Стоимость имущества
Это свойство возвращает истину, если на панели индикатора нанесены вертикальные линии
сетки; в противном случае - ложь. По умолчанию установлено значение true.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
DrawVerticalGridLines

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DrawVerticalGridLines = false;// Вертикальные линии сетки не будут отображаться на
панели индикатора
AddPlot(Brushes.Orange, "SMA");
}
}

IndicatorBaseConverter Class
Определение
Пользовательский класс TypeConverter, обрабатывающий разработанное поведение коллекции
дескрипторов свойств индикатора. Используйте его как базовый класс для любого
настраиваемого TypeConverter, который вы применяете к классу индикатора.

Примечания:

• Работающую демонстрацию NinjaScript можно найти в справочном образце «Использование


TypeConverter для настройки поведения сетки свойств»

• При применении специального конвертера вы должны полностью указать имя (например,


«NinjaTrader.NinjaScript.Indicators.MyCustomConveter»)

• Дополнительную информацию о TypeConverter можно найти в документации MSDN.

• См. Также TypeConverterAttribute.

• Информацию о стратегиях см. В классе StrategyBaseConverter.


Соответствующие базовые методы

TypeConverter.GetProperties() При переопределении GetProperties () вызов


base.GetProperties () гарантирует, что все
поведение сетки свойств по умолчанию
работает так, как задумано.

TypeConverter.GetPropertiesSupported() В вашем пользовательском классе


конвертера вы должны переопределить
GetPropertiesSupported () и вернуть значение
true, чтобы ваш пользовательский
преобразователь типов работал.

Syntax
public class IndicatorBaseConverter : TypeConverter
Предупреждение. Неспособность применить тип IndicatorBaseConverter к классу индикатора
может привести к непредсказуемому поведению стандартной сетки свойств NinjaTrader WPF.

Совет: общие индикаторные функции, такие как Print (), недоступны для экземпляра
преобразователя типов. Чтобы отладить класс преобразователя типов, вы можете
использовать AddOn Debug Concepts или присоединиться к отладчику (рекомендуется)
Examples
// Это пространство имен содержит индикаторы в этой папке и является обязательным. Не
меняйте это.
namespace NinjaTrader.NinjaScript.Indicators
{
// При применении преобразователя типов вы должны полностью указать имя
[TypeConverter("NinjaTrader.NinjaScript.Indicators.MyCustomConveter")]
public class MyCustomIndicator : Indicator
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "MyCustomIndicator";
}
}

protected override void OnBarUpdate()


{
// Добавьте сюда свою логику пользовательского индикатора.
}
}

public class MyCustomConveter : IndicatorBaseConverter


{
// Общий метод TypeConveter, используемый для преобразования типов
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,
object component, Attribute[] attrs)
{
// иногда может понадобиться экземпляр индикатора, который действительно существует в
сетке
MyCustomIndicator indicator = component as MyCustomIndicator;

// base.GetProperties гарантирует, что у нас есть все свойства (и связанные редакторы


сетки свойств)
// Внутренняя логика NinjaTrader обрабатывает данный индикатор

PropertyDescriptorCollection propertyDescriptorCollection =
base.GetPropertiesSupported(context)
? base.GetProperties(context, component, attrs) :
TypeDescriptor.GetProperties(component, attrs);

if (indicator == null || propertyDescriptorCollection == null)


return propertyDescriptorCollection;
// пример того, почему вам может понадобиться экземпляр, который существует в сетке ....
if (indicator.EntryHandling == EntryHandling.UniqueEntries)
{
// делаем что-нибудь, если свойство содержит какое-то значение ...
}

// Зацикливаем все свойства индикатора


foreach (PropertyDescriptor property in propertyDescriptorCollection)
{
// делаем что-то с определенным свойством

// здесь нельзя вызвать Print ()


// но вы можете вызвать статическое окно вывода "Process ()"

NinjaTrader.Code.Output.Process(property.Name, PrintTo.OutputTab1);
}

// должен вернуть коллекцию после внесения изменений


return propertyDescriptorCollection;
}

// Важно: это должно возвращать истину, иначе преобразователь типов не будет вызываться
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{ return true; }
}
}
}

IsChartOnly

Определение
Если установлено значение true, любой индикатор будет доступен только для построения
графиков - индикаторы с включенным этим свойством, например, не должны отображаться при
вызове в окне SuperDOM или MarketAnalyzer.

Стоимость имущества
Это свойство возвращает истину, если индикатор можно использовать только на графике; в
противном случае - ложь. По умолчанию установлено значение false.
Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()
во время State.SetDefaults или State.Configure

Syntax
IsChartOnly

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IsChartOnly = true; // Разрешить индикатору работать только в графической среде
}
}

IsSuspendedWhileInactive
Определение
Предотвращает запуск OnBarUpdate, когда отображение индикаторов не используется.
Включение этого свойства в вашем индикаторе помогает сэкономить циклы ЦП, пока индикатор
приостановлен и не используется пользователем. Как только индикатор перейдет в состояние,
которое больше не будет считаться приостановленным, будут запущены исторические события
OnBarUpdate (), позволяющие индикатору догнать текущие значения в реальном времени.

Приостановка происходит в следующих случаях:

• Минимизированная диаграмма

• Минимизированный анализатор рынка

• Минимизированный анализатор горячих списков

• Свернутый SuperDOM

• Фоновые вкладки вышеуказанных функций считаются «свернутыми».

• Неактивные рабочие области в фоновом режиме

Примечание: поскольку события в OnBarUpdate () не будут обрабатываться, пока индикатор


приостановлен, внутренние функции NinjaScript, такие как Alert (), PlaySound (), Share (), Print ()
и т. Д. - или любой другой метод, который может использоваться для Уведомление
пользователя о действиях НЕ будет обрабатываться, пока индикатор не будет отключен.
Сценарии, при которых приостановка не произойдет
Свойство IsSuspendedWhileInactive будет проигнорировано, и события в реальном времени
будут обрабатываться как обычно в следующих случаях:

• Индикаторы, работающие в автоматизированных стратегиях NinjaScript

• Индикаторы, для которых настроены оповещения вручную

• Индикаторы, которые были вручную прикреплены к заявкам.

Стоимость имущества
Это свойство возвращает истину, если индикатор может использовать оптимизацию
приостановки; в противном случае - ложь. По умолчанию установлено значение false.

Примечание. Это свойство автоматически переопределяется мастером кода NinjaScript на


«true». Вам нужно будет удалить свойство, чтобы вернуться к значению по умолчанию, или
вручную установить для него значение false, чтобы отключить это поведение.

Предупреждение: это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure
Syntax
IsSuspendedWhileInactive

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IsSuspendedWhileInactive = true;
}
}
PaintPriceMarkers

Определение
Если true, любые значения графиков индикатора отображают ценовые маркеры по оси Y.

Стоимость имущества
Это свойство возвращает истину, если значения графика индикатора отображаются по оси Y; в
противном случае - ложь. По умолчанию установлено значение true.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
PaintPriceMarkers

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
PaintPriceMarkers = true;// Индикатор отображает значения по оси Y
AddPlot(Brushes.Orange, "SMA");
}
}

ShowTransparentPlotsInDataBox

Определение
Определяет, отображаются ли значения графиков, для которых установлена прозрачная кисть,
в поле данных диаграммы. Поведение по умолчанию - скрыть все графики, которые были
настроены как прозрачная кисть, однако это поведение можно изменить, установив для
ShowTransparentPlotsInDataBox значение true на индикаторе.

Стоимость имущества
Это свойство возвращает значение true, если значения прозрачных графиков индикаторов
отображаются в поле данных графика; в противном случае - ложь. По умолчанию установлено
значение false.
Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()
во время State.SetDefaults или State.Configure

Syntax
ShowTransparentPlotsInDataBox
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
ShowTransparentPlotsInDataBox = true;
AddPlot(Brushes.Transparent, "MyPlot");
}
}

Market Analyzer Column


Столбцы Custom Market Analyzer можно использовать для дальнейшего расширения
возможностей Market Analyzer, предоставляя настраиваемые столбцы, отображающие
значения по вашему выбору. Методы и свойства, описанные в этом разделе, уникальны для
разработки пользовательских столбцов Market Analyzer.

В этой секции

CurrentText Задает текст, который будет отображаться в


столбце Market Analyzer.

CurrentValue Значение, которое будет отображаться в


столбце Market Analyzer.

DataType Определяет тип данных, отображаемых в


столбце Market Analyzer.

FormatDecimals Округляет значение, содержащееся в


CurrentValue, до указанного количества
десятичных знаков перед отображением его в
столбце Market Analyzer.

IsEditable Определяет, доступен ли столбец Market


Analyzer для редактирования.

PriorValue Содержит последнее значение CurrentValue.


PriorValue присваивается значение
CurrentValue непосредственно перед
обновлением CurrentValue.
CurrentText
Определение
Задает текст, который будет отображаться в столбце Market Analyzer.

Примечание. CurrentText имеет приоритет над любым значением, установленным для


CurrentValue. Если и CurrentValue, и CurrentText имеют присвоенные значения, значение
CurrentText будет отображаться в столбце.

Стоимость имущества
Строка, представляющая текст для отображения в столбце
Syntax
CurrentText

Example

protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)


{
// Вывести "Ask" в столбец, если получено обновление цены Ask
if(marketDataUpdate.MarketDataType == MarketDataType.Ask)
CurrentText = "Ask";
}

CurrentValue
Определение
Значение, которое будет отображаться в столбце Market Analyzer.

Стоимость имущества
Двойное значение, представляющее значение, которое будет отображаться в столбце

Syntax
CurrentValue

Example

protected override void OnMarketData(Data.MarketDataEventArgs marketDataUpdate)


{
CurrentValue = marketDataUpdate.Price;
}

DataType
Определение
Определяет тип данных, отображаемых в столбце Market Analyzer.

Syntax
DataType

Example

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DataType = typeof(string);
IsEditable = true;
}
}

FormatDecimals
Определение
Округляет значение, содержащееся в CurrentValue, до указанного количества десятичных
знаков перед отображением его в столбце Market Analyzer.

Стоимость имущества
Тип int, представляющий количество десятичных знаков, до которых округляется CurrentValue.
Syntax
FormatDecimals
Example

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Округляем CurrentValue до одного десятичного знака
FormatDecimals = 1;
}
}

protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)


{
CurrentValue = marketDataUpdate.Price;
}

IsEditable
Определение
Определяет, доступен ли столбец Market Analyzer для редактирования.

Стоимость имущества
Это свойство возвращает true, если столбец Market Analyzer можно редактировать; в противном
случае - ложь.
Syntax
IsEditable

Example

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DataType = typeof(string);
IsEditable = true;
}
}

OnRender()
Определение
Используется для рисования настраиваемого содержимого в столбце анализатора рынка,
например графика.

Этот метод вызывается при следующих условиях:

• Анализатор рынка прокручивается

• Пользователь изменяет свойства Market Analyzer через меню «Свойства».

• Анализатор рынка сначала загружается (например, восстановление из рабочей области)

• Высота / ширина окна Market Analyzer изменяется.

• Пользователь изменяет размер области содержимого, перетаскивая разделитель между


столбцами.
Примечание. Хотя столбец Market Analyzer похож на метод OnRender () индикатора диаграммы,
он использует класс контекста рисования WPF, а не библиотеку SharpDX, используемую для
отрисовки диаграмм. Принципы между этими двумя методами гарантированно различны.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в столбце Market Analyzer, используя следующий синтаксис:
protected override void OnRender(DrawingContext dc, System.Windows.Size renderSize)
{

Method Parameters

dc Контекст рисования для столбца

renderSize Размер отрисовки для столбца

Совет: чтобы принудительно вызвать OnRender () при определенном условии, вызовите метод
OnPropertyChanged (), который заставит перерисовать весь столбец. Этот подход следует
использовать вместо прямого вызова OnRender ().
Examples

protected override void OnRender(DrawingContext dc, System.Windows.Size renderSize)


{
// Логика рендеринга для нашей колонки Market Analyzer
}

PriorValue
Определение
Содержит последнее значение CurrentValue. PriorValue присваивается значение CurrentValue
непосредственно перед обновлением CurrentValue.
Стоимость имущества
Двойное значение, содержащее последнее значение, содержащееся в CurrentValue перед его
последним обновлением.
Syntax
PriorValue
Example

protected override void OnMarketData(MarketDataEventArgs marketDataUpdate)


{
if (marketDataUpdate.MarketDataType == MarketDataType.Last)
{
CurrentValue = marketDataUpdate.Price;

// Запускаем оповещение, если текущее последнее обновление цены больше предыдущего


if(CurrentValue > PriorValue)
Alert("MA Alert", Priority.High, "Check Market Analyzer", "", 30, Brushes.Black,
Brushes.White);
}
}

Optimization Fitness
При оптимизации можно использовать настраиваемые параметры оптимизации, чтобы помочь
вам выбрать настраиваемые показатели, по которым может быть измерена ваша стратегия.
Методы и свойства, описанные в этом разделе, уникальны для пользовательской разработки
Optimization Fitness.
В этой секции

OnCalculatePerformanceValue() Этот метод вычисляет значение пригодности


для оптимизации.

Value Значение, по которому будет рассчитываться


оптимизация при использовании этого
приспособления для оптимизации.

OnCalculatePerformanceValue()
Определение
Этот метод вычисляет значение пригодности для оптимизации.
Syntax
protected override void OnCalculatePerformanceValue(StrategyBase strategy)
{
}
Examples

protected override void OnCalculatePerformanceValue(StrategyBase strategy)


{
Value = strategy.SystemPerformance.AllTrades.TradesPerformance.Percent.Drawdown;
}

Value
Определение
Значение, по которому будет рассчитываться оптимизация при использовании этого
приспособления для оптимизации.
Стоимость имущества
Двойное значение.
Syntax
Value

Examples

protected override void OnCalculatePerformanceValue(StrategyBase strategy)


{
Value = strategy.SystemPerformance.AllTrades.TradesPerformance.Percent.Drawdown;
}

Optimizer
Пользовательские оптимизаторы можно использовать для оптимизации вашей стратегии с
помощью различных алгоритмов. Это может позволить вам пойти на компромисс, например,
возможность быстро найти адекватные результаты, а не пытаться найти абсолютно лучший
результат, но с помощью трудоемкого процесса. Методы и свойства, описанные в этом
разделе, уникальны для разработки пользовательского оптимизатора.

В этой секции

NumberOfIterations Сообщает анализатору стратегии, сколько


итераций оптимизации ему необходимо
сделать.

OnOptimize() Этот метод необходимо переопределить,


чтобы оптимизировать стратегию.

OptimizationParameters Параметры оптимизации, выбранные для


прогона оптимизации.
RunIteration() Выполняет итерацию тестирования на
истории для оптимизатора.

SupportsMultiObjectiveOptimization Сообщает анализатору стратегии, может ли


этот оптимизатор выполнять многоцелевые
оптимизации.

NumberOfIterations
Определение
Сообщает анализатору стратегии, сколько итераций оптимизации ему необходимо сделать.

Стоимость имущества
Значение типа int.
Syntax
NumberOfIterations
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
Name = "MyOptimizer";
else if (State == State.Configure && Strategies.Count > 0)
NumberOfIterations = 1;
}

OnOptimize()
Определение
Этот метод необходимо переопределить, чтобы оптимизировать стратегию. Этот метод
вызывается один раз за прогон оптимизации (не один раз за итерацию).

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в оптимизаторе, используя следующий синтаксис.

protected override void OnOptimize()


{

}
Examples

protected override void OnOptimize()


{
// Если цели оптимизации нет, возвращаем
if (Strategies[0].OptimizationParameters.Count == 0)
return;

// Логика оптимизатора
}

OptimizationParameters
Определение
Параметры оптимизации, выбранные для прогона оптимизации. (например, параметры
пользователя или ряд данных)

Стоимость имущества
Логическое значение.

Syntax
Strategies[0].OptimizationParameters

Examples

protected override void OnOptimize()


{
// Если нет параметров оптимизации для оптимизации, возвращаем
if (Strategies[0].OptimizationParameters.Count == 0)
return;

// Что-то делаем с параметром оптимизации


Parameter parameter = Strategies[0].OptimizationParameters[0];
}

RunIteration()
Определение
Выполняет итерацию тестирования на истории для оптимизатора.
Возвращаемое значение метода
Этот метод не возвращает значения.
Syntax
RunIteration()
Examples

protected override void OnOptimize()


{
// Логика оптимизатора
RunIteration();
}

SupportsMultiObjectiveOptimization
Определение
Сообщает анализатору стратегии, может ли этот оптимизатор выполнять многоцелевые
оптимизации.

Стоимость имущества
Логическое значение.
Syntax
SupportsMultiObjectiveOptimization

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "MyOptimizer";
SupportsMultiObjectiveOptimization = true;
}
}

Performance Metrics
Пользовательские показатели эффективности можно использовать при создании статистики
эффективности торговли.
После создания настраиваемых показателей производительности обязательно разрешите их
использование в меню «Инструменты»> «Параметры»> «Общие», иначе они не будут доступны
в окнах «Анализатор стратегий» или «Эффективность торговли».

В этой секции

Format() Этот метод позволяет вам настроить


отображение значения производительности в
итоговой сетке.

OnAddTrade() Этот метод вызывается при добавлении


каждой сделки.

OnCopyTo() Вызывается при сохранении значений


торговой метрики.

OnMergePerformanceMetric() Этот метод вызывается, когда показатели


производительности будут агрегированы и
объединены.

PerformanceUnit Перечисление, определяющее каждый тип


PerformanceUnit, вычисляемый NinjaTrader.
Используется для хранения значения этого
типа производительности в
PerformanceMetrics.

Values Массив Values содержит 5 значений,


соответствующих каждому
Cbi.PerformanceUnit.

Format()
Определение
Этот метод позволяет вам настроить отображение значения производительности в итоговой
сетке.
Syntax
public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)
{

}
Examples

public override string Format(object value, Cbi.PerformanceUnit unit, string propertyName)


{
double[] tmp = value as double[];
if (tmp != null && tmp.Length == 5)
switch (unit)
{
case Cbi.PerformanceUnit.Currency : return Core.Globals.FormatCurrency(tmp[0], denomination);
case Cbi.PerformanceUnit.Percent : return tmp[1].ToString("P");
caseCbi.PerformanceUnit.Pips:return
Math.Round(tmp[2]).ToString(Core.Globals.GeneralOptions.CurrentCulture);
caseCbi.PerformanceUnit.Points:return
Math.Round(tmp[3]).ToString(Core.Globals.GeneralOptions.CurrentCulture);
caseCbi.PerformanceUnit.Ticks:return
Math.Round(tmp[4]).ToString(Core.Globals.GeneralOptions.CurrentCulture);
}
return value.ToString();
}

OnAddTrade()
Определение
Этот метод вызывается при добавлении каждой сделки. Вы можете добавить сюда любую
произвольную математику, которую захотите.

Примечание. Если метрике производительности требуется только итерация по всем сделкам


в конце для выполнения ее расчета, и ее не нужно рассчитывать для каждой сделки, то
использование подхода на основе свойств (пример по запросу) будет иметь меньшее влияние
на производительность.
Syntax
protected override void OnAddTrade(Cbi.Trade trade)
{

Examples

protected override void OnAddTrade(Cbi.Trade trade)


{
Values[(int)Cbi.PerformanceUnit.Currency] += trade.ProfitCurrency;
Values[(int)Cbi.PerformanceUnit.Percent] += trade.ProfitPercent;
Values[(int)Cbi.PerformanceUnit.Pips] += trade.ProfitPips;
Values[(int)Cbi.PerformanceUnit.Points] += trade.ProfitPoints;
Values[(int)Cbi.PerformanceUnit.Ticks] += trade.ProfitTicks;
}
OnCopyTo()
Определение
Вызывается при сохранении значений торговой метрики.
Syntax
protected override void OnCopyTo(PerformanceMetricBase target)
{

Examples
protected override void OnCopyTo(PerformanceMetricBase target)
{
// Вам нужно преобразовать, чтобы получить доступ к нужному типу
SampleCumProfit targetMetrics = (target as SampleCumProfit);

if (targetMetrics != null)
Array.Copy(Values, targetMetrics.Values, Values.Length);
}

OnMergePerformanceMetric()
Определение
Этот метод вызывается, когда показатели производительности будут агрегированы и
объединены (например, в итоговой строке анализатора стратегий).
Syntax
protected override void OnMergePerformanceMetric(PerformanceMetricBase merge)
{

Examples

protected override void OnMergePerformanceMetric(PerformanceMetricBase target)


{
// Вам нужно преобразовать, чтобы получить доступ к нужному типу
SampleCumProfit targetMetrics = (target as SampleCumProfit);

// Это всего лишь простая средневзвешенная выборка


if (targetMetrics != null && TradesPerformance.TradesCount +
targetMetrics.TradesPerformance.TradesCount > 0)
for (int i = 0; i < Values.Length; i++)
targetMetrics.Values[i] = (targetMetrics.Values[i] *
targetMetrics.TradesPerformance.TradesCount + Values[i] * TradesPerformance.TradesCount) /
(TradesPerformance.TradesCount + targetMetrics.TradesPerformance.TradesCount);
}

PerformanceUnit
Определение
Перечисление, определяющее каждый тип PerformanceUnit, вычисляемый NinjaTrader.
Используется для хранения значения этого типа производительности в PerformanceMetrics.

Syntax
PerformanceUnit.Currency
PerformanceUnit.Percent
PerformanceUnit.Pips
PerformanceUnit.Points
PerformanceUnit.Ticks
Examples

// Выводит нереализованный PnL в тиках на закрытие каждого бара


Print(Position.GetUnrealizedProfitLoss(PerformanceUnit.Ticks, Close[0]));

Values
Определение
Массив Values содержит 5 значений, соответствующих каждому Cbi.PerformanceUnit. Затем
NinjaTrader получит доступ к свойству Values, чтобы отобразить рассчитанную метрику
производительности в пользовательском интерфейсе. Вы также можете получить доступ к этим
показателям производительности для стратегии NinjaScript.
Syntax
public double[] Values
{ get; private set; }
Расчет значений на примере OnAddTrade
protected override void OnAddTrade(Cbi.Trade trade)
{
Values[(int)Cbi.PerformanceUnit.Currency] += trade.ProfitCurrency;
Values[(int)Cbi.PerformanceUnit.Percent] = (1.0 + Values[(int)Cbi.PerformanceUnit.Percent])
* (1.0 + trade.ProfitPercent) - 1;
Values[(int)Cbi.PerformanceUnit.Pips] += trade.ProfitPips;
Values[(int)Cbi.PerformanceUnit.Points] += trade.ProfitPoints;
Values[(int)Cbi.PerformanceUnit.Ticks] += trade.ProfitTicks;
}

// Атрибут определяет имя значения производительности в сетке


[Display("MyPerformanceMetric", Order = 0)]
public double[] Values
{ get; private set; }

Пример расчета значений по запросу

// Атрибут определяет имя значения производительности в сетке


[Display("MyPerformanceMetric", Order = 0)]
public double[] Values
{
get
{
return /*Your custom math here*/
}

private set;
}

Share Service

Пользовательские службы общего доступа могут быть разработаны для того, чтобы
пользователи могли обмениваться контентом из приложения NinjaTrader на различных веб-
сайтах и в социальных сетях через диалоговое окно «Службы совместного использования».
NinjaTrader 8 поставляется с предварительно настроенными службами обмена для Twitter,
StockTwits и адаптером электронной почты, однако пользовательский адаптер может быть
разработан для любого веб-сайта, форума или сети социальных сетей, следуя их
общедоступной документации и руководствам по API.
В этой секции

CharacterLimit Определяет максимальное количество


символов, разрешенное социальной сетью.

CharactersReservedPerMedia Устанавливает допустимое количество


символов при прикреплении изображения,
чтобы обеспечить правильное вычисление
количества символов.

Icon Форма, которая отображается в окне


«Поделиться» при публикации содержимого.

UseOAuth Если для этого свойства установлено


значение true, в диалоговом окне для
настройки адаптера появится кнопка
«Подключить», которая будет вызывать
OnAuthorizeAccount (), когда пользователь
щелкает ее.

IsConfigured Устанавливается, когда служба общего


доступа настроена правильно.

IsDefault Устанавливает службу общего доступа по


умолчанию, используемую при выборе типа
службы общего доступа (электронная почта,
Twitter и т. Д.).

IsImageAttachmentSupported Определяет, разрешает ли служба общего


доступа использовать изображения в
качестве вложений.

OnAuthorizeAccount() Если для свойства UseOAuth установлено


значение true, этот метод будет вызываться,
когда пользователь нажимает кнопку
«Подключиться» в диалоговом окне «Общие
службы» в разделе «Инструменты» ->
«Параметры».

OnShare() Этот метод вызывается, когда пользователь


нажимает кнопку «ОК» в окне «Поделиться» в
NinjaTrader. Этот метод также может
вызываться предупреждениями и общими
объектами NinjaScript.

Signature Задает текст, добавляемый в конец


сообщения пользователя.

CharacterLimit
Определение
Определяет максимальное количество символов, разрешенное социальной сетью. Подпись,
текст и ссылки вносят вклад в это количество символов, отображаемое в окне общего доступа.
Значение int.MaxValue не определяет практического ограничения и заставляет счетчик
символов не отображаться в окне общего доступа.

Стоимость имущества
Значение типа int, которое представляет максимальное количество символов, разрешенное
социальной сетью.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
CharacterLimit
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
CharacterLimit = 280;
}
}

CharactersReservedPerMedia
Определение
Устанавливает допустимое количество символов при прикреплении изображения, чтобы
обеспечить правильное вычисление количества символов.

Примечание. Социальные сети, такие как Twitter или StockTwits, которые ограничивают
количество символов для каждого сообщения, будут иметь определенное количество
символов, которые зарезервированы при прикреплении изображения или другого носителя.

Стоимость имущества
Значение типа int, представляющее количество символов, зарезервированных при
прикреплении изображения или другого носителя.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure
Syntax
CharactersReservedPerMedia
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
CharactersReservedPerMedia = 40;
}
}

Icon
Определение
Форма, которая отображается в окне «Поделиться» при публикации содержимого. Поскольку
это стандартный объект, можно использовать любой тип значка (символы Юникода,
пользовательский ресурс файла изображения, путь геометрии и т. Д.). Дополнительные
сведения об использовании изображений для создания значков см. На странице
«Использование изображений с настраиваемыми значками».

Примечание. При использовании символов UniCode сначала убедитесь, что нужные символы
существуют в пакете значков для семейства шрифтов, используемого в NinjaTrader.

Стоимость имущества
Общий виртуальный объект, представляющий значок меню инструментов рисования. Это
свойство доступно только для чтения.

Синтаксис
Вы должны переопределить это свойство, используя следующий синтаксис:

public override object Icon


Examples

public override object Icon


{
get
{
// используем символ Юникода в качестве нашей строки, которая будет отображать стрелку
string uniCodeArrow = "\u279A";
return uniCodeArrow;
}
}

UseOAuth
Определение
Если для этого свойства установлено значение true, в диалоговом окне для настройки адаптера
появится кнопка «Подключить», которая будет вызывать OnAuthorizeAccount (), когда
пользователь щелкает ее.

Стоимость имущества
Логическое значение, определяющее, следует ли вызывать метод OnAuthorizeAccount () для
авторизации учетной записи в социальной службе.

Предупреждение: это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults.

Syntax
UseOAuth

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
UseOAuth = true;
}
}

IsConfigured
Определение
Устанавливается, когда служба общего доступа настроена правильно. Обычно это
устанавливается после авторизации учетной записи, после чего адаптер позволяет
пользователю обмениваться контентом с службой совместного использования.

Примечание. Службе общего доступа не требуется авторизовывать пользователя, поэтому


можно установить IsConfigured в значение true в State.SetDefaults, что позволит обойти любые
виды авторизации или дополнительных настроек, которые могут потребоваться для адаптера
общего доступа.
Стоимость имущества
Значение bool, когда оно истинно, определяет, правильно ли настроен адаптер общего доступа.
Syntax
IsConfigured
Examples

public override void OnAuthorizeAccount()


{
// Логика авторизации будет здесь, после успеха установите IsConfigured в значение true.

IsConfigured = true;
}

IsDefault
Определение
Устанавливает службу общего доступа по умолчанию, используемую при выборе типа службы
общего доступа (электронная почта, Twitter и т. Д.).

Например, если вы используете два разных адаптера Twitter, вы можете установить один из
них по умолчанию, когда пользователь выбирает службу общего доступа Twitter. Установка
этого свойства по умолчанию будет применяться только к любым адаптерам Twitter и не будет
применяться к другим типам служб общего доступа, у которых есть собственный
соответствующий адаптер по умолчанию.

Стоимость имущества
Логическое значение, указывающее, является ли текущий адаптер службой общего доступа по
умолчанию, используемой для этого типа службы общего доступа.

Предупреждение: это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults.
Syntax
Default
Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Default = false;
}
}

IsImageAttachmentSupported
Определение
Определяет, разрешает ли служба общего доступа использовать изображения в качестве
вложений.

Стоимость имущества
Если значение типа bool равно false, скриншоты нельзя будет отправить в социальную сеть.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
IsImageAttachmentSupported

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IsImageAttachmentSupported = false;
}
}

OnAuthorizeAccount()
Определение
Если для свойства IsAuthorizationRequired установлено значение true, этот метод будет
вызываться, когда пользователь нажимает кнопку «Подключиться» в диалоговом окне «Общие
службы» в разделе «Инструменты» -> «Параметры». Когда этот метод вызывается, он позволит
вам пройти процесс рукопожатия для авторизации учетной записи в службе совместного
использования. Например, вы можете получить токены пользователей для публикации от их
имени в социальных сетях с использованием аутентификации OAuth.

Документацию по процессу установления связи OAuth можно найти на официальном веб-сайте


OAuth: http://oauth.net/code/
Конкретную документацию по процессу авторизации для конкретной службы совместного
использования можно найти на общедоступных ресурсах API, расположенных на их веб-сайтах.

Возвращаемое значение метода


Асинхронная задача

Параметры
Этот метод не требует никаких параметров

Синтаксис
Этот метод не требуется переопределять. При необходимости вы можете переопределить
метод в вашей службе общего доступа, используя следующий синтаксис:
public override async Task OnAuthorizeAccount()
{

Examples

public override async Task OnAuthorizeAccount()


{
// MyShareServices Token () - это заполнитель для фактического метода токена API
string result = await MyShareServicesToken("myToken");

// result is also a place holder


if(result == "APIErrorCode123")
{
Print("Unable to authorize token");
return;
}

// Пожалуйста, ознакомьтесь с документацией OAUTH вашего API для правильного


использования рукопожатия
else Print("Success!");
}

OnShare()
Определение
Этот метод вызывается, когда пользователь нажимает кнопку «ОК» в окне «Поделиться» в
NinjaTrader. Этот метод также может вызываться предупреждениями и общими объектами
NinjaScript.

Возвращаемое значение метода


Этот метод не возвращает значение
Parameters

text Сообщение, отправляемое в социальную


сеть или другого поставщика Share. Это то,
что отображается в текстовом поле в окне
«Поделиться».

imageFilePath Необязательный путь к снимку экрана или


другому изображению для отправки в
социальную сеть или другому провайдеру
обмена

Syntax

Вы должны переопределить метод в своей службе общего доступа,


используя следующий синтаксис.

public override void OnShare(string text, string imageFilePath)


{

Examples

public override void OnShare(string text, string imgFilePath)


{
// разместите здесь логику службы общего доступа
}

Signature
Определение
Задает текст, добавляемый в конец сообщения пользователя. Он не редактируется
пользователем и влияет на количество символов в общем сообщении.
Вы можете установить для него пустую строку, если это не относится к вашему адаптеру. В
этом случае метка «Подпись» не появится в окне «Поделиться».

Стоимость имущества

Строковое значение, добавляемое в конец сообщения пользователя.


Syntax
Signature
Examples

// пример №1, в конец сообщения добавляется текст «Это сообщение было отправлено из
NinjaTrader 8».
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Signature = "This message was sent from NinjaTrader 8";
}
}

// пример # 2, используется пустая строка, которая не добавляет никакого дополнительного


текста к сообщению
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Signature = string.Empty;
}
}

Strategy
Методы и свойства, описанные в этом разделе, уникальны для разработки пользовательской
стратегии.

В этой секции

Account Представляет реальную учетную запись или


учетную запись моделирования, настроенную
для стратегии.
AddChartIndicator() Добавляет индикатор в стратегию только для
отображения на графике.

AddPerformanceMetric() Добавляет экземпляр настраиваемой


метрики производительности в стратегию,
используемую в расчетах стратегии.

ATM Strategy Methods Добавляет стратегии банкоматов для


управления вашей позицией

BarsRequiredToTrade Количество исторических баров,


необходимое до того, как стратегия начнет
обрабатывать методы заказа, вызываемые в
методе OnBarUpdate ().

BarsSinceEntryExecution() Возвращает количество баров, прошедших с


момента последней указанной записи.

BarsSinceExitExecution() Возвращает количество баров, прошедших с


момента последнего указанного выхода.

ChartIndicators Содержит коллекцию индикаторов, которые


были добавлены в экземпляр стратегии с
помощью AddChartIndicator ().

CloseStrategy() Отменяет все рабочие ордера, закрывает все


существующие позиции и, наконец,
отключает стратегию.

ConnectionLossHandling Устанавливает способ поведения вашей


стратегии при обнаружении потери
соединения.

DaysToLoad Определяет количество торговых дней,


которое будет настроено при загрузке
стратегии из таблицы стратегий.

DefaultQuantity Переменная размера ордера, которая может


быть установлена программно или
переопределена с помощью стратегии,
которая определяет количество ордера на
вход.

DisconnectDelaySeconds Определяет количество времени, которое


должно длиться отключение, прежде чем
обработка потери соединения начнет
действовать.

EntriesPerDirection Определяет максимальное количество


записей, разрешенных для каждого
направления, пока позиция активна, на
основе свойства EntryHandling.

EntryHandling Устанавливает способ обработки ордеров на


вход.

Execution Представляет интерфейс только для чтения,


который предоставляет информацию о
выполнении (заполненном заказе),
являющемся результатом заказа, и
передается как параметр в методе
OnExecutionUpdate ().

ExitOnSessionCloseSeconds Количество секунд до фактического времени


окончания сеанса, которое вызовет функция
IsExitOnSessionCloseStrategy.

IncludeCommission Определяет, будут ли результаты


эффективности стратегии включать комиссию
на историческом бэктесте.

IncludeTradeHistoryInBacktest Определяет, будет ли стратегия сохранять


ордера, сделки и историю исполнения.

IsAdoptAccountPositionAware Определяет, запрограммирована ли


стратегия способом, позволяющим
обрабатывать реальные позиции на счетах.

IsExitOnSessionCloseStrategy Определяет, будет ли стратегия отменять


все созданные стратегией ордера и
закрывать все открытые позиции стратегии в
конце сеанса.

IsFillLimitOnTouch Определяет, будет ли стратегия


использовать более либеральный алгоритм
заполнения только для целей обратного
тестирования.

IsInstantiatedOnEachOptimizationIteration Определяет, следует ли повторно создавать


(воссоздавать) стратегию после каждого
прогона оптимизации при использовании
оптимизатора Strategy Analyzer.

IsInStrategyAnalyzer Определяет, запускается ли текущая


стратегия NinjaScript из диаграммы
Анализатора стратегий.

IsTradingHoursBreakLineVisible Наносит на индикаторную панель линии


излома торговых часов.

IsWaitUntilFlat Указывает, что стратегия в настоящее


время ожидает обнаружения плоской
позиции перед отправкой живых ордеров.

NumberRestartAttempts Определяет максимальное количество


попыток перезапуска, разрешенное в
течение последних x минут,
определенных в RestartsWithinMinutes,
когда стратегия испытывает потерю
соединения.

OnAccountItemUpdate() Управляемый событиями метод,


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

OnExecutionUpdate() Управляемый событиями метод, который


вызывается при поступлении выполнения
заказа, управляемого стратегией.

OnOrderTrace() Управляемый событиями метод,


используемый для стратегий, который
позволит вам настроить вывод
TraceOrders.

OnOrderUpdate() Управляемый событиями метод, который


вызывается каждый раз, когда заказ,
управляемый стратегией, меняет
состояние.

OnPositionUpdate() Управляемый событиями метод, который


вызывается каждый раз, когда позиция
стратегии меняет состояние.

OptimizationPeriod Зарезервированное для пошаговой


оптимизации, это свойство определяет
количество дней, используемых для
периода тестирования на исторических
данных «в выборке» для данной
стратегии. См. Также TestPeriod.

Order Представляет интерфейс только для


чтения, который предоставляет
информацию о заказе.

Order Methods NinjaScript предоставляет несколько


подходов, которые вы можете
использовать для размещения заказа в
рамках своей стратегии NinjaScript.

OrderFillResolution Определяет, как заказы стратегии


заполняются во время исторических
состояний.

OrderFillResolutionType Определяет тип столбцов, которые будут


использоваться для обработки
исторического заполнения.

OrderFillResolutionValue Определяет значение интервала


периода баров, которое будет
использоваться для обработки
исторического заполнения.

PerformanceMetrics Содержит массив объектов


PerformanceMetrics, представляющих
настраиваемые метрики, которые можно
использовать для расчета стратегии.

Plots Коллекция, содержащая все объекты


Plot, определяющие их характеристики
визуализации.
Position Представляет информацию о позиции,
которая относится к экземпляру
стратегии.

PositionAccount Представляет информацию о положении,


относящуюся к реальной учетной записи
(в реальном времени или в
моделировании).

Positions Содержит массив объектов Position,


которые представляют позиции,
управляемые стратегией.

PositionsAccount Содержит массив объектов


PositionAccount, которые представляют
позиции, управляемые учетной записью
стратегии.

RealtimeErrorHandling Определяет поведение стратегии, когда


сгенерированный стратегией ордер
возвращается с сервера брокера в
состоянии «Отклонено».

RestartsWithinMinutes Определяет, через сколько минут


стратегия будет пытаться
перезапуститься.

SetOrderQuantity Определяет, как рассчитываются


размеры ордеров для данной стратегии.

Slippage Устанавливает величину


проскальзывания в тиках за выполнение,
используемую при расчетах
производительности во время
тестирования на истории.

StartBehavior Устанавливает начальное поведение


стратегии. См. Раздел «Синхронизация
позиций на счете» для получения
дополнительной информации.

StopTargetHandling Определяет, как подаются стоп-ордера и


целевые ордера во время исполнения
ордера на вход.

StrategyBaseConverter Пользовательский класс TypeConverter,


обрабатывающий разработанное
поведение коллекции дескрипторов
свойств стратегии.

SystemPerformance Объект SystemPerformance содержит все


сделки и данные об их эффективности,
сгенерированные стратегией.

TestPeriod Зарезервированное для пошаговой


оптимизации, это свойство определяет
количество дней, используемых для
периода бэктестирования «вне выборки»
для данной стратегии.

TimeInForce Устанавливает свойство времени


действия для всех ордеров,
сгенерированных стратегией.

TraceOrders Определяет, будет ли вызываться


OnOrderTrace () для данной стратегии.

Trade Сделка - это завершенная сделка


покупки / продажи или продажи / покупки.
Он состоит из выполнения входа и
выхода.

TradeCollection Коллекция торговых объектов.

TradesPerformanceValues Значения производительности коллекции


объектов Trade.

WaitForOcoClosingBracket Определяет, будет ли стратегия


предоставлять обе стороны брекета ОСО
перед отправкой пары брокеру.

Account
Определение
Представляет реальную учетную запись или учетную запись моделирования, настроенную для
стратегии.

Стоимость имущества
Объект Account, настроенный для стратегии
Syntax
Account

Examples

// Отображает текст на графике, указывающий, к какому счету применяется стратегия


Draw.TextFixed(this, "tag1", "Strategy is applied to " + Account.Name, TextPosition.BottomRight);

AddChartIndicator()
Определение
Добавляет индикатор в стратегию только для отображения на графике.

Примечания:

• Только свойства графика индикатора, добавленного с помощью AddChartIndicator (), будут


доступны в диалоге индикаторов на графиках. Другие свойства должны быть установлены в
коде.

• Чтобы добавить объекты Bars в вашу стратегию для целей расчета, см. Метод AddDataSeries
().

• Индикатор, добавляемый через AddChartIndicator (), не может использовать какие-либо


дополнительные ряды данных, размещенные в вызывающей стратегии, но может использовать
только первичные ряды данных стратегии. Если вы хотите использовать другую серию данных
для ввода индикатора, вы можете добавить серию в сам индикатор и явно ссылаться на нее в
коде индикатора (убедитесь, что в стратегии хостинга также включен тот же вызов
AddDataSeries ())

o Если вызывающая стратегия указывает вторичную или нулевую серию Bars (а не сам
индикатор), вместо нее будет подставлена первичная серия стратегии.

• Динамическое использование DrawOnPricePanel в индикаторе за пределами State.SetDefaults


может отображать проблемы при работе с этим индикатором через стратегию хостинга через
AddChartIndicator ().

Возвращаемое значение метода


Этот метод не возвращает значения.
Syntax
AddChartIndicator(IndicatorBase indicator)

Предупреждение: этот метод должен вызываться ТОЛЬКО из метода OnStateChange () во


время State.DataLoaded

Parameters

indicator Индикаторный объект

Examples
protected override void OnStateChange()
{
if (State == State.DataLoaded)
{
// Наносит на график 20-периодную простую скользящую среднюю
AddChartIndicator(SMA(20));
}
}

Совет: если вы добавляете индикатор, который зависит от правильного состояния индикатора,


вам необходимо убедиться, что вы также вызываете индикатор из стратегии в OnBarUpdate (),
иначе ваш индикатор будет обрабатываться только в State.RealTime для оптимизация
производительности.

protected override void OnStateChange()


{
if (State == State.DataLoaded)
{
// Наносит на график 20-периодную простую скользящую среднюю
AddChartIndicator(SMA(20));
}
}

protected override void OnBarUpdate()


{
// исторически вызываем SMA (), чтобы индикатор также обрабатывал свои исторические
состояния
double sma = SMA(20)[0];
}

AddPerformanceMetric()
Определение
Добавляет экземпляр настраиваемой метрики производительности в стратегию, используемую
в расчетах стратегии.

Возвращаемое значение метода


Этот метод не возвращает значения.
Syntax
AddPerformanceMetric(PerformanceMetricBase performanceMetric)

Предупреждение: этот метод следует вызывать ТОЛЬКО из метода OnStateChange () во время


State.Configure

Parameters

performanceMetric `Добавляемый объект метрики


производительности

Examples

protected override void OnStateChange()


{
if (State == State.Configure)
{
AddPerformanceMetric(new NinjaTrader.NinjaScript.PerformanceMetrics.SampleCumProfit());
}
}

ATM Strategy Methods


Методы стратегии ATM

Из стратегии NinjaScript можно использовать стратегии ATM для управления своими


позициями. Преимущество такого подхода заключается в том, что вы можете использовать
стратегию NinjaScript для генерации автоматических сигналов входа, а после входа вы можете
делегировать управление выходом стратегии ATM, которая позволяет вам вручную
контролировать, как закрыть сделку.

Для получения дополнительной информации см. Раздел “Использование ATM.”

Расширенное Управление стратегией

AtmStrategyCancelEntryOrder()
Определение
Отменяет указанный порядок входа, определенный строковым параметром orderId.

Примечания:

1. Этот метод предназначен ТОЛЬКО для заказов, представленных как заказы на вход через
банкомат, и предполагает, что OrderState НЕ является терминальным (т. Е. Отменен, исполнен,
отклонен, неизвестен).

2. Если указанный заказ не существует, метод возвращает false и регистрируется ошибка.


Возвращаемое значение метода
Возвращает истину, если указанный заказ был найден; в противном случае - ложь.

Syntax
AtmStrategyCancelEntryOrder(string orderId)
Предупреждение: этот метод следует вызывать ТОЛЬКО после того, как состояние стратегии
достигло состояния State.Realtime

Parameters

orderId Уникальный идентификатор заявки на вход

Examples

protected override void OnBarUpdate()


{
// Методы стратегии банкомата работают только в режиме реального времени
if (State != State.Realtime)
return;

string[] entryOrder = GetAtmStrategyEntryOrderStatus("orderId");

// проверяет, существует ли порядок входа


// и состояние ордера еще не отменено / заполнено / отклонено
if (entryOrder.Length > 0 && entryOrder[2] == "Working")
{
AtmStrategyCancelEntryOrder("orderId");
}
}

AtmStrategyChangeEntryOrder()
Определение
Изменяет цену указанного ордера на вход.

Возвращаемое значение метода


Возвращает истину, если указанный заказ был найден; в противном случае - ложь.

Syntax
AtmStrategyChangeEntryOrder(double limitPrice, double stopPrice, string orderId)
Parameters

limitPrice Лимитная цена ордера


stopPrice Стоп-цена ордера

orderId Уникальный идентификатор заявки на вход

Examples

protected override void OnBarUpdate()


{
AtmStrategyChangeEntryOrder(GetCurrentBid(), 0, "orderIdValue");
}

AtmStrategyChangeStopTarget()
Определение
Изменяет цену указанного ордера указанной стратегии ATM.

Возвращаемое значение метода


Возвращает истину, если указанный заказ был найден; в противном случае - ложь.

Syntax
AtmStrategyChangeStopTarget(double limitPrice, double stopPrice, string orderName, string
atmStrategyId)
Parameters

limitPrice Лимитная цена ордера

stopPrice Стоп-цена ордера

orderName Название ордера, например "Stop1" или


"Target2".

atmStrategyId Уникальный идентификатор стратегии


банкомата

Examples

protected override void OnBarUpdate()


{
AtmStrategyChangeStopTarget(0, SMA(10)[0], "Stop1", "AtmIdValue");
}

AtmStrategyClose()
Определение
Отменяет все рабочие ордера и закрывает любую открытую позицию стратегии, используя
поведение закрытия стратегии ATM по умолчанию.

Возвращаемое значение метода


Возвращает истину, если указанная стратегия банкомата была найдена; в противном случае -
ложь.

Примечание. Возвращаемое методом значение true НИ В КОЕМ СЛУЧАЕ означает, что


стратегия фактически закрыта. Это указывает на то, что указанная стратегия банкомата была
найдена и была запущена процедура внутреннего закрытия.
Syntax
AtmStrategyClose(string atmStrategyId)
Parameters

atmStrategyId Уникальный идентификатор стратегии


банкомата
Examples

protected override void OnBarUpdate()


{
// Проверяем допустимое условие и создаем стратегию банкомата
if (GetAtmStrategyUnrealizedProfitLoss("idValue") > 500)
AtmStrategyClose("idValue");
}

AtmStrategyCreate()
Определение
Отправляет ордер на вход, который будет выполнять указанную стратегию банкомата.

Примечания:

• Ознакомьтесь с разделом об использовании стратегий банкоматов.

• Этот метод НЕ ПОДЛЕЖИТ тестированию и НЕ будет выполняться на исторических данных.

• См. AtmStrategyCancelEntryOrder (), чтобы отменить порядок входа.

• См. AtmStrategyChangeEntryOrder (), чтобы изменить цену ордера на вход.


• Стратегия ATM будет создана асинхронно на хосте NinjaScripts UI Thread, обратный вызов
предоставляется исключительно для проверки того, когда стратегия ATM запускается в этом
потоке - доступ, например, к ценовым данным в этом внешнем контексте OnBarUpdate ()
невозможен.

• Пожалуйста, посмотрите пример использования SampleATMStrategy в NinjaTrader.

Возвращаемое значение метода


Этот метод не возвращает значение

Syntax
AtmStrategyCreate(OrderAction action, OrderType orderType, double limitPrice, double stopPrice,
TimeInForce timeInForce, string orderId, string strategyTemplateName, string atmStrategyId,
Action<Cbi.ErrorCode, string> callback)
Parameters

action Устанавливает, является ли входной ордер


ордером на покупку или продажу

Возможные значения:
-OrderAction.Buy
-OrderAction.Sell

orderType Устанавливает тип заявки на вход

Возможные значения:

•OrderType.Limit
•OrderType.Market
•OrderType.MIT
•OrderType.StopMarket
•OrderType.StopLimit

limitPrice Лимитная цена заказа

stopPrice Стоп-цена ордера

timeInForce Устанавливает время действия заявки на


вход
Возможные значения:

•TimeInForce.Day
•TimeInForce.Gtc
orderId Уникальный идентификатор заявки на вход

strategyTemplateName Определяет, какой шаблон стратегии будет


использоваться

atmStrategyId Уникальный идентификатор стратегии ATM

callback Действие обратного вызова используется для


проверки того, что стратегия ATM успешно
запущена.

Совет: В отличие от заказов стратегии NinjaScript (как управляемых, так и неуправляемых),


стратегиями ATM, созданными методом AtmStrategyCreate (), можно управлять вручную с
помощью любого окна ввода ордеров, такого как SuperDOM, или в рамках вашей стратегии
NinjaScript.

Examples

private string atmStrategyId;


private string atmStrategyOrderId;
private bool isAtmStrategyCreated = false;

protected override void OnBarUpdate()


{
if (State < State.Realtime)
return;

if (Close[0] > SMA(20)[0])


{
atmStrategyId = GetAtmStrategyUniqueId();
atmStrategyOrderId = GetAtmStrategyUniqueId();

AtmStrategyCreate(OrderAction.Buy, OrderType.Market, 0, 0, TimeInForce.Day,


atmStrategyOrderId, "MyTemplate", atmStrategyId, (atmCallbackErrorCode, atmCallbackId)
=> {

// проверяет, что обратный вызов возвращен для текущего сохраненного atmStrategyId


if (atmCallbackId == atmStrategyId)
{
// проверяем обратный вызов банкомата на наличие кодов ошибок
if (atmCallbackErrorCode == Cbi.ErrorCode.NoError)
{
// если ошибок нет, установите для private bool значение true, чтобы указать, что
стратегия atm создана
isAtmStrategyCreated = true;
}
}
});
}

if(isAtmStrategyCreated)
{
// atm логика
}

else if(!isAtmStrategyCreated)
{
// настраиваемая обработка неудачной стратегии банкомата
}
}

GetAtmStrategyEntryOrderStatus()
Определение
Получает текущее состояние указанного порядка входа.

Примечание. Если метод не может найти указанный порядок, возвращается пустой массив.

Возвращаемое значение метода


Массив string [], содержащий три элемента, которые представляют среднюю цену заполнения,
заполненную сумму и состояние ордера.
Syntax
GetAtmStrategyEntryOrderStatus(string orderId)

Parameters

orderId Уникальный идентификатор заявки на вход

Examples
protected override void OnBarUpdate()
{
string[] entryOrder = GetAtmStrategyEntryOrderStatus("orderId");

// Проверяем длину, чтобы убедиться, что возвращаемый массив содержит информацию о


заказе
if (entryOrder.Length > 0)
{
Print("Average fill price is " + entryOrder[0].ToString());
Print("Filled amount is " + entryOrder[1].ToString());
Print("Current state is " + entryOrder[2].ToString());
}
}

GetAtmStrategyMarketPosition()
Определение
Получает текущую рыночную позицию указанной стратегии банкомата.

Примечания:

1. Изменения позиций не будут отражены, по крайней мере, до следующего события


OnBarUpdate () после заполнения ордера.

2. Если стратегии банкомата не существует, то MarketPosition.Flat возвращается.

3. Обратите внимание, что это обеспечивает доступ к текущей позиции стратегии банкомата,
которую не следует путать с позицией стратегии NinjaScript или позицией счета. Для получения
дополнительной информации см. Раздел «Использование банкоматов».

Method Return Value


MarketPosition.Flat
MarketPosition.Long
MarketPosition.Short
Syntax
GetAtmStrategyMarketPosition(string atmStrategyId)
Parameters

atmStrategyId Уникальный идентификатор стратегии ATM

Examples
protected override void OnBarUpdate()
{
// Проверяем, плоский ли
if (GetAtmStrategyMarketPosition("id") == MarketPosition.Flat)
Print("ATM Strategy position is currently flat");
}

GetAtmStrategyPositionAveragePrice()
Определение
Получает среднюю цену текущей позиции для указанной стратегии банкомата.

Примечание: изменения позиций не будут отражены, по крайней мере, до следующего события


OnBarUpdate () после заполнения ордера.

Возвращаемое значение метода


Двойное значение, представляющее среднюю цену.
Syntax
GetAtmStrategyPositionAveragePrice(string atmStrategyId)
Parameters

atmStrategyId Уникальный идентификатор стратегии ATM

Examples

protected override void OnBarUpdate()


{
// Проверяем, плоский ли
if (GetAtmStrategyMarketPosition("id") != MarketPosition.Flat)
Print("Average price is " + GetAtmStrategyPositionAveragePrice("id").ToString());
}

GetAtmStrategyPositionQuantity()
Определение
Получает текущее количество позиций указанной стратегии банкомата.
Примечание: изменения позиций не будут отражены, по крайней мере, до следующего события
OnBarUpdate () после заполнения ордера.

Возвращаемое значение метода


Значение типа int, представляющее количество.
Syntax
GetAtmStrategyPositionQuantity(string atmStrategyId)
Parameters

atmStrategyId Уникальный идентификатор стратегии ATM

Examples

protected override void OnBarUpdate()


{
// Проверяем, плоский ли
if (GetAtmStrategyMarketPosition("idValue") != MarketPosition.Flat)
Print("Position size is " + GetAtmStrategyPositionQuantity("id").ToString());
}

GetAtmStrategyRealizedProfitLoss()
Определение
Получает значение реализованной прибыли и убытка для указанной стратегии банкомата.

Возвращаемое значение метода


Двойное значение, представляющее реализованную прибыль и убыток.
Syntax
GetAtmStrategyRealizedProfitLoss(string atmStrategyId)
Parameters

atmStrategyId Уникальный идентификатор стратегии ATM

Examples

protected override void OnBarUpdate()


{
Print("PnL is " + GetAtmStrategyRealizedProfitLoss("id").ToString());
}
GetAtmStrategyStopTargetOrderStatus()
Определение
Получает текущее состояние (состояний) указанного стоп-ордера или целевого ордера все еще
активной стратегии банкомата.

Примечания:

1. Если метод не может найти указанный порядок (а), возвращается пустой массив.

2. Указанный стоп или цель в стратегии банкомата может фактически удерживать несколько
ордеров. Например, если ваша стратегия банкомата отправляет стоп и цель, и вы получаете
несколько частичных заполнений при входе с задержкой в несколько секунд или более между
заполнениями входа, стратегия банкомата будет отправлять стоповые и целевые ордера для
каждого частичного заполнения одним и тем же цена и вид заказа.

Возвращаемое значение метода


Строковый [,] многомерный массив, содержащий три измерения, которые представляют
среднюю цену заполнения, объем заполнения и состояние заказа. Длина (количество
элементов) представляет собой количество заказов, представляющих указанное имя.

Syntax
GetAtmStrategyStopTargetOrderStatus(string orderName, string atmStrategyId)
Parameters

orderName Название ордера, например "Stop1" или


"Target2".

atmStrategyId Уникальный идентификатор стратегии


банкомата

Examples
protected override void OnBarUpdate()
{
string[,] orders = GetAtmStrategyStopTargetOrderStatus("Target1", "idValue");

// Проверяем длину, чтобы убедиться, что возвращаемый массив содержит информацию о


заказе
if (orders.Length > 0)
{
for (int i = 0; i < orders.GetLength(0); i++)
{
Print("Average fill price is " + orders[i, 0].ToString());
Print("Filled amount is " + orders[i, 1].ToString());
Print("Current state is " + orders[i, 2].ToString());
}
}
}

GetAtmStrategyUnrealizedProfitLoss()
Определение
Получает значение нереализованной прибыли и убытка по указанной стратегии банкомата.

Возвращаемое значение метода


Двойное значение, представляющее нереализованную прибыль и убыток.

Syntax
GetAtmStrategyUnrealizedProfitLoss(string atmStrategyId)
Parameters

atmStrategyId Уникальный идентификатор стратегии


банкомата

Examples

protected override void OnBarUpdate()


{
Print("Unrealized PnL is " + GetAtmStrategyUnrealizedProfitLoss("id").ToString());
}

GetAtmStrategyUniqueId()
Определение
Создает уникальное значение идентификатора стратегии банкомата.

Возвращаемое значение метода


Строковое значение, представляющее уникальное значение идентификатора.
Syntax
GetAtmStrategyUniqueId()

Параметры
Этот метод использует любые параметры.
Примеры

protected override void OnBarUpdate()


{
string orderId = GetAtmStrategyUniqueId();
}

BarsRequiredToTrade
Определение
Количество исторических баров, необходимое для того, чтобы стратегия начала обрабатывать
методы заказа, вызываемые в методе OnBarUpdate (). Это свойство обычно устанавливается
через пользовательский интерфейс при запуске стратегии.

Примечание. В стратегии с несколькими сериями это ограничение применяется только для


основного объекта Bars. Это означает, что вы можете столкнуться с ситуациями, когда
основные бары, необходимые для торговли, были достигнуты, а требуемые дополнительные
бары - нет. Если логика вашей стратегии переплетает вычисления между разными объектами
Bars, перед продолжением убедитесь, что все объекты Bars соответствуют требованию
BarsRequiredToTrade. Это можно сделать с помощью проверки массива CurrentBars.

Стоимость имущества
Значение типа int, представляющее количество исторических баров. Значение по умолчанию -
20.

Предупреждение: это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax

BarsRequiredToTrade

Совет: при работе с многосерийной стратегией события обновления бара в реальном времени
для конкретного объекта Bars принимаются только тогда, когда этот объект Bars удовлетворяет
требованию BarsRequiredToTrade. Чтобы обеспечить выполнение этого требования,
используйте массив CurrentBars.

Examples
Установка значения BarsRequiredToTrade по умолчанию
protected override void OnStateChange()
{
if (State == State.Configure)
{
BarsRequiredToTrade = 20;
}
}
Проверка BarsRequiredToTrade по массиву CurrentBars
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
BarsRequiredToTrade = 20;
}
else if (State == State.Configure)
{
// добавляем 30-минутный ряд для логики расчета
AddDataSeries(BarsPeriodType.Minute, 30);
}
}

protected override void OnBarUpdate()


{
// не обрабатываем логику ордера, пока не встретятся бары, необходимые для торговли
// и для первичной, и для 30-минутной серии достигли своих баров, необходимых для
торговли

if (CurrentBars[0] < BarsRequiredToTrade || CurrentBars[1] < BarsRequiredToTrade)


return;

// логика заказа
}

BarsSinceEntryExecution()
Определение
Возвращает количество баров, прошедших с момента последней записи. Если указано имя
сигнала, будет возвращено количество баров, прошедших с момента последней конкретной
записи.

Возвращаемое значение метода


Значение типа int, представляющее количество полос. Если предыдущая запись не существует,
будет возвращено значение -1.

Syntax
BarsSinceEntryExecution()
BarsSinceEntryExecution(string signalName)

При работе с мультитаймфреймовыми и инструментальными стратегиями следует


использовать следующую сигнатуру метода:
BarsSinceEntryExecution(int barsInProgressIndex, string signalName, int entryExecutionsAgo)

Примечание: при работе с многосерийной стратегией BarsSinceEntryExecution () вернет вам


прошедшие бары, как определено первым объектом Bars для инструмента, указанного в
barsInProgressIndex.

Parameters

signalName Имя сигнала заявки на вход, указанное в


методе ввода заявки.

barsInProgressIndex Индекс объекта Bars, против которого был


выставлен ордер на вход.

Примечание. См. Свойство BarsInProgress.

entryExecutionsAgo Количество выполнений записи назад.


Передайте 0 для количества баров с момента
последнего входа.

Examples
protected override void OnBarUpdate()
{
if (CurrentBar < BarsRequiredToTrade)
return;

// Входим только в том случае, если с момента последнего входа прошло не менее 10 баров
if ((BarsSinceEntryExecution() > 10 || BarsSinceEntryExecution() == -1) && CrossAbove(SMA(10),
SMA(20), 1))
EnterLong();

BarsSinceExitExecution()
Определение
Возвращает количество баров, прошедших с момента последнего выхода. Если указано имя
сигнала, будет возвращено количество баров, прошедших с момента последнего конкретного
выхода.

Возвращаемое значение метода


Значение типа int, представляющее количество полос. Если предыдущий выход не существует,
будет возвращено значение -1.

Syntax
BarsSinceExitExecution()
BarsSinceExitExecution(string signalName)

При работе с мультитаймфреймовыми и инструментальными стратегиями следует


использовать следующую сигнатуру метода.

BarsSinceExitExecution(int barsInProgressIndex, string signalName, int exitExecutionsAgo)

Примечание: при работе с многосерийной стратегией BarsSinceExitExecution () вернет вам


прошедшие бары, как определено первым объектом Bars для инструмента, указанного в
barsInProgressIndex.

Parameters

signalName Имя сигнала порядка выхода, указанное в


методе выхода из ордера.

barsInProgressIndex Индекс объекта Bars, против которого был


выставлен ордер на вход.

Примечание. См. Свойство BarsInProgress.

exitExecutionsAgo Количество казней выхода назад. Передайте


0 для количества баров с момента
последнего выполнения выхода.

Совет: пожалуйста, смотрите SetStopLoss (), SetProfitTarget () или SetTrailStop () для их


соответствующего имени сигнала.

Examples

protected override void OnBarUpdate()


{
if (CurrentBar < BarsRequiredToTrade)
return;

// Входить только в том случае, если с момента нашего последнего выхода прошло не менее
10 баров или мы еще не торговали
if ((BarsSinceExitExecution() > 10 || BarsSinceExitExecution() == -1) && CrossAbove(SMA(10),
SMA(20), 1))
EnterLong();
}
ChartIndicators
Определение
Содержит коллекцию индикаторов, которые были добавлены в экземпляр стратегии с помощью
AddChartIndicator ().

Свойство стоимости
Индикаторный объект

Syntax
ChartIndicators[int index]

Examples

if (State == State.DataLoaded)
{
AddChartIndicator(SMA(20));

// Устанавливаем цвет графиков для добавляемого индикатора


ChartIndicators[0].Plots[0].Brush = Brushes.Blue;

// Устанавливаем добавленный индикатор на новую панель


ChartIndicators[0].Panel = 1;
}

CloseStrategy()

Определение
Отменяет все рабочие ордера, закрывает все существующие позиции и, наконец, отключает
стратегию. При желании это поведение также можно изменить для данной стратегии.

Примечания:

• Если вы решите переопределить этот метод с использованием настраиваемой логики,


поведение по умолчанию метода CloseStrategy () НЕ будет выполняться. По этой причине
предлагается вызвать базовую реализацию метода CloseStrategy () в виртуальном
переопределении, чтобы гарантировать, что стратегия завершена, как задумано, в противном
случае вы обязаны правильно управлять любыми рабочими ордерами или позициями.
• CloseStrategy () будет работать с текущей позицией стратегии и не будет влиять на какие-либо
настройки StartBehavior, т.е. вызов CloseStrategy (), когда скрипт находится в виртуальной
исторической позиции, может привести к нежелательной позиции

• Обработка CloseStrategy () по умолчанию будет применяться только к основной серии


стратегии MultiSeries NinjaScript.

Возвращаемое значение метода


Этот метод не возвращает значения.

Syntax
CloseStrategy(string signalName)

Предупреждение: этот метод можно вызвать только до того, как State достигнет
State.Terminated

Вы можете переопределить этот метод, используя следующий синтаксис:

public override void CloseStrategy(string signalName)


{

}
Parameters

signalName Название сигнала, которое будет


использоваться для идентификации приказа
закрытия. Если имя сигнала не существует
или имеет значение null, вместо него будет
подставлено «Close».

Examples
Базовое использование CloseStrategy
DateTime StartTime = new DateTime();
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "ExampleStrategy";
}

else if (State == State.Transition)


StartTime = Core.Globals.Now;
}

protected override void OnBarUpdate()


{
// если мы все еще находимся в позиции через 45 минут после времени начала, закрываем
стратегию
if(Position.MarketPosition != MarketPosition.Flat && Time[0] >= StartTime.AddMinutes(45))
CloseStrategy("My Custom Close");
}

Overriding the Default CloseStrategy logic


public override void CloseStrategy(string signalName)
{
Print("Executing Custom Close Logic");
// настраиваемая логика закрытия

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


base.CloseStrategy(signalName);
}

ConnectionLossHandling
Определение
Устанавливает способ поведения вашей стратегии при обнаружении потери соединения.

При использовании ConnectionLossHandling.Recalculate перерасчеты будут происходить только


в том случае, если стратегия была остановлена на основании условий ниже. Если соединение
будет восстановлено до того, как стратегия была остановлена, стратегия продолжит работу без
перерасчета, как если бы не было отключения.

• Если поток данных отключается на время, превышающее время, указанное в


DisconnectDelaySeconds, стратегия останавливается.

• Если поток ордеров отключается, и стратегия размещает действие ордера при отключении,
стратегия останавливается.

• Если и поток данных, и поток заказов отключаются на время, превышающее время, указанное
в DisconnectDelaySeconds, стратегия останавливается.

ConnectionLossHandling.KeepRunning Поддерживает выполнение стратегии. Когда


соединение будет восстановлено, стратегия
возобновится, как если бы не было
отключения.

ConnectionLossHandling.Recalculate Стратегии будут пытаться пересчитать свою


стратегическую позицию при восстановлении
соединения.

ConnectionLossHandling.StopStrategy Автоматически останавливает стратегию при


отключении более чем на Disconnect
DelaySeconds. При восстановлении
соединения никаких действий
предприниматься не будет.

Syntax
ConnectionLossHandling
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Поддерживает работу стратегии, как если бы не было отключения
ConnectionLossHandling = ConnectionLossHandling.KeepRunning;
}
}

DaysToLoad
Определение
Определяет количество торговых дней, которое будет настроено при загрузке стратегии из
таблицы стратегий.

Примечания:

1. Это свойство НЕ влияет на стратегию, настроенную для диаграммы или анализатора


стратегий.

2. торговый день определяется шаблоном торгового часа.

Стоимость имущества
Значение типа int, определяющее количество торговых дней, загружаемых для обработки
исторических данных. Значение по умолчанию - 5, но его можно настроить и переопределить из
пользовательского интерфейса.
Syntax
DaysToLoad
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DaysToLoad = 15;
}
}

DefaultQuantity
Определение
Переменная размера ордера, которая может быть установлена программно или
переопределена с помощью стратегии, которая определяет количество ордера на вход.

Стоимость имущества
Значение типа int представляет количество контрактов или акций для входа в позицию.
Значение по умолчанию - 1.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure
Syntax
DefaultQuantity
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
DefaultQuantity = 1;
}
}

DisconnectDelaySeconds
Определение
Определяет количество времени, которое должно длиться отключение, прежде чем обработка
потери соединения начнет действовать.

Стоимость имущества
Значение типа int представляет время, необходимое для того, чтобы отключение продлилось
до того, как произойдут действия по обработке потери соединения. Значение по умолчанию -
10.
Syntax
DisconnectDelaySeconds
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Отключение должно быть не менее 10 секунд
DisconnectDelaySeconds = 10;
}
}

EntriesPerDirection
Определение
Определяет максимальное количество записей, разрешенных для каждого направления, пока
позиция активна, на основе свойства EntryHandling.

Примечание. Это свойство применяется ТОЛЬКО к методам управляемого заказа. Если для
IsUnmanaged установлено значение true, свойства обработки входа будут скрыты в
пользовательском интерфейсе.

Стоимость имущества
Значение типа int представляет максимально допустимое количество записей. Значение по
умолчанию - 1.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
EntriesPerDirection

Examples
Если открытая позиция уже существует, последующие вызовы EnterLong
() игнорируются.
// Example #1
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
}
}

protected override void OnBarUpdate()


{
if (CrossAbove(SMA(10), SMA(20), 1)
EnterLong("SMA Cross Entry");

if (CrossAbove(RSI(14, 3), 30, 1)


EnterLong("RSI Cross Entry);
}

EnterLong () будет обрабатываться один раз для каждой записи с


уникальным именем.
// Example #2
protected override void OnStateChange()
{
EntriesPerDirection = 1;
EntryHandling = EntryHandling.UniqueEntries;
}

protected override void OnBarUpdate()


{
if (CrossAbove(SMA(10), SMA(20), 1)
EnterLong("SMA Cross Entry");

if (CrossAbove(RSI(14, 3), 30, 1)


EnterLong("RSI Cross Entry);
}

EntryHandling
Определение
Устанавливает способ обработки ордеров на вход.
Примечание. Это свойство применяется ТОЛЬКО к методам управляемого заказа. Если для
IsUnmanaged установлено значение true, свойства обработки входа будут скрыты в
пользовательском интерфейсе.

Стоимость имущества
Перечисление, которое устанавливает, как обрабатываются заказы на вход. Значение по
умолчанию - EntryHandling.AllEntries. Возможные значения включают:

EntryHandling.AllEntries NinjaScript будет обрабатывать все методы


ввода ордеров до тех пор, пока не будут
достигнуты максимально допустимые
значения, установленные свойством
EntriesPerDirection в открытой позиции.

EntryHandling.UniqueEntries NinjaScript будет обрабатывать методы ввода


заказа до тех пор, пока не будут установлены
максимально допустимые записи,
установленные свойством EntriesPerDirection
для каждой записи с уникальным именем.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
EntryHandling
Examples
Разрешить максимум два входа, пока позиция открыта
// Example #1
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
EntriesPerDirection = 2;
EntryHandling = EntryHandling.AllEntries;
}
}

protected override void OnBarUpdate()


{
if (CrossAbove(SMA(10), SMA(20), 1)
EnterLong("SMA Cross Entry");
}

EnterLong () будет обрабатываться один раз для каждой записи с


уникальным именем.
// Example #2
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
EntriesPerDirection = 1;
EntryHandling = EntryHandling.UniqueEntries;
}
}

protected override void OnBarUpdate()


{
if (CrossAbove(SMA(10), SMA(20), 1)
EnterLong("SMA Cross Entry");

if (CrossAbove(RSI(14, 3), 30, 1)


EnterLong("RSI Cross Entry");
}

Execution
Определение
Представляет интерфейс только для чтения, который предоставляет информацию о
выполнении (заполненном заказе), являющемся результатом заказа, и передается как
параметр в Definition
Represents a read only interface that exposes information regarding an execution (filled order)
resulting from an order and is passed as a parameter in the OnExecutionUpdate() method.

Note: Not all executions will have associated Order objects (e.g ExitOnSessionClose executions or
AtmStrategyCreate() executions)методе OnExecutionUpdate ().

Примечание. Не все исполнения будут иметь связанные объекты Order (например, выполнение
ExitOnSessionClose или выполнение AtmStrategyCreate ())

Methods and Properties


Account Аккаунт, на котором произошло исполнение

BarsInProgress Значение типа int, представляющее


BarsArray, в котором произошло выполнение.

Commission bool значение, обозначающее комиссию за


исполнение.

ExecutionId Строковое значение, представляющее


идентификатор выполнения,
сгенерированный обменом.

Instrument Стоимость инструмента, представляющая


инструмент ордера.

MarketPosition Положение исполнения.

Возможные значения:

•MarketPosition.Long
•MarketPosition.Short

Name Строка, представляющая имя ордера,


которое может быть предоставлено именем
сигнала входа или выхода.

Order Значение заказа, представляющее заказ,


связанный с исполнением.

OrderId Строка, представляющая уникальный


идентификатор выполненного заказа.

Position Значение типа int представляет текущее


количество позиций на счете на момент
выполнения.

PositionStrategy Значение типа int представляет текущее


количество позиций стратегии на момент
выполнения.

Price Двойное значение, представляющее цену


исполнения.

Quantity Значение типа int, представляющее


количество выполнений

Rate Двойное значение, представляющее


обменный курс, рассчитанный для базовых
продуктов, отличных от долларов США (1,
если курс не применялся).

Slippage Двойное значение, представляющее


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

Time Структура DateTime, представляющая время


выполнения.
ToString() Строковое представление выполнения

Examples
Поиск выполнения определенного объекта Order
// Example #1
private Order entryOrder = null;

protected override void OnBarUpdate()


{
if (entryOrder == null && Close[0] > Open[0])
EnterLong("myEntryOrder");
}

protected override void OnExecutionUpdate(Execution execution, string executionId, double price,


int quantity, MarketPosition marketPosition, string orderId, DateTime time)
{
// Назначьте entryOrder в OnExecutionUpdate (), чтобы гарантировать, что назначение
происходит, когда ожидалось.
// Это более надежно, чем присвоение объектов Order в OnBarUpdate, так как не
гарантируется, что назначение будет завершено, если на него сделана ссылка сразу после
отправки

if (execution.Order.Name == "myEntryOrder" && execution.Order.OrderState == OrderState.Filled)


entryOrder = order;

if (entryOrder != null && entryOrder == execution.Order)


Print(execution.ToString());
}

Общая логика выполнения, не относящаяся к конкретному объекту Order

// Example #2
protected override void OnExecutionUpdate(Execution execution, string executionId, double price,
int quantity, MarketPosition marketPosition, string orderId, DateTime time)
{
// Не забудьте проверить базовый объект Order на null, прежде чем пытаться получить
доступ к его свойствам
if (execution.Order != null && execution.Order.OrderState == OrderState.Filled)
Print(execution.ToString());
}
ExitOnSessionCloseSeconds
Определение
Количество секунд до фактического времени окончания сеанса, которое вызовет функция
IsExitOnSessionCloseStrategy.

Время, от которого будет вычисляться это свойство, берется из свойства EOD торговых часов,
установленного в шаблоне торговых часов стратегии. Свойство ExitOnSessionCloseSeconds
может быть установлено программно в методе OnStateChange () или управляться
пользовательским интерфейсом во время выполнения.

Примечание. Это свойство работает только в реальном времени, оно не повлияет на время
ExitOnSessionClose при тестировании обработки исторических данных на исторических данных.

Стоимость имущества
Тип int, представляющий количество секунд. Значение по умолчанию - 30.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure
Syntax
ExitOnSessionCloseSeconds

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Запускает выход по функции закрытия за 30 секунд до конца торгового дня
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
}
}

IncludeCommission
Определение
Определяет, будут ли результаты эффективности стратегии включать комиссию на
историческом бэктесте. Если задано значение true, будет использоваться шаблон комиссии,
примененный к учетной записи, на которой работает стратегия.
Стоимость имущества
Логическое значение, которое возвращает истину, если стратегия включает комиссию на
историческом бэктесте; в противном случае - ложь. По умолчанию установлено значение false.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
IncludeCommission
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IncludeCommission = true;
}
}

IncludeTradeHistoryInBacktest
Определение
Определяет, будет ли стратегия сохранять ордера, сделки и историю исполнения. Если для
этого свойства установлено значение false, вы увидите значительную экономию памяти за счет
доступа к подробной торговой информации.

Примечания:

• Поскольку торговая информация не сохраняется, на графике будут отображаться только


операции входа / выхода без соединительных торговых линий PnL.

• В 32-битной среде для этого свойства всегда по умолчанию установлено значение false, за
исключением случаев, когда стратегия работает на графике или при тестировании на истории
одного инструмента.

• В 64-битной среде для этого свойства всегда установлено значение true, за исключением
случаев, когда стратегия выполняется на вкладке стратегии.

Стоимость имущества
Это свойство возвращает истину, если стратегия будет включать торговую историю; в
противном случае - ложь. По умолчанию установлено значение true.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.Configure (или State.SetDefaults при добавлении скрипта из вкладки стратегии)

Syntax
IncludeTradeHistoryInBacktest
Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Явно включаем торговую историю в бэктест
IncludeTradeHistoryInBacktest = true;
}
}

protected override void OnBarUpdate()


{
// Прекращаем открытие сделок после того, как было совершено 10 сделок с момента
включения стратегии
if(SystemPerformance.AllTrades.Count >= 10)
return;
}

IsAdoptAccountPositionAware
Определение
Определяет, запрограммирована ли стратегия способом, позволяющим обрабатывать
реальные позиции на счетах. Если установлено значение true, параметры «Начальное
поведение» вашей стратегии будут включать дополнительный параметр с именем «Принять
позицию на счете», который можно установить во время выполнения. Устанавливайте значение
true только в том случае, если вы специально запрограммировали свою стратегию на
использование позиций на счете.

Стоимость имущества
Это свойство возвращает истину, если стратегия может принимать позиции счета; в противном
случае - ложь. По умолчанию установлено значение false.
Примечание. Это свойство следует устанавливать ТОЛЬКО из метода OnStateChange () во
время State.SetDefaults.
Syntax
IsAdoptAccountPositionAware

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IsAdoptAccountPositionAware = true;
}
}

IsExitOnSessionCloseStrategy
Определение
Определяет, будет ли стратегия отменять все созданные стратегией ордера на всех
стратегических инструментах и закрывать все открытые стратегические позиции при закрытии
ЛЮБОГО сеанса для мульти-таймфреймов / мультиинструментальных стратегий. Это свойство
может быть установлено программно в методе OnStateChange () или управляться
пользовательским интерфейсом во время выполнения. См. Также
«ExitOnSessionCloseSeconds».

Стоимость имущества
Это свойство возвращает истину, если стратегия завершается при закрытии; в противном
случае - ложь. По умолчанию установлено значение true.

Предупреждения:

• Это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange () во время


State.SetDefaults или State.Configure.

• На исторических данных IsExitOnSessionCloseStrategy приведет к закрытию позиций при


закрытии последнего бара сессии. Если вы используете тип столбца без временной привязки,
такой как Renko, и для параметра «Разрыв в EOD» установлено значение False в серии
данных, это означает, что IsExitOnSessionCloseStrategy может сработать после закрытия
сеанса, поскольку последний столбец сеанса может в этом сценарии выходят за рамки времени
закрытия сеанса.

• Даже если вы проводите бэктестинг с заданным разрешением заполнения исторического


ордера более детальным, чем базовый первичный ряд, ExitOnSessionCloseSeconds все равно
будет привязан к полосе первичного ряда более высокого таймфрейма.
IsExitOnSessionCloseStrategy не следует использовать в сочетании с Daily Bars и High Order Fill
Resolution, так как это приведет к закрытию позиции в то же время, что и обновление дневного
бара (при закрытии сеанса).
• Это свойство предназначено для использования только во внутридневных стратегиях.

Syntax
IsExitOnSessionCloseStrategy

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// Запускает выход при закрытии сессии за 30 секунд до окончания торгового дня в
реальном времени
IsExitOnSessionCloseStrategy = true;
ExitOnSessionCloseSeconds = 30;
}
}

IsFillLimitOnTouch
Определение
Определяет, будет ли стратегия использовать более либеральный алгоритм заполнения только
для целей обратного тестирования. По умолчанию алгоритм исполнения стратегии исполняет
лимитный ордер после того, как цена превысила лимитную цену. Однако это поведение можно
изменить, установив для IsFillLimitOnTouch значение true, и в этом случае алгоритм заполнения
стратегии будет считать лимитный ордер исполненным, как только цена достигнет лимитной
цены, но не обязательно торговать по лимитной цене.

Стоимость имущества
Это свойство возвращает истину, если стратегия будет заполнять лимитные ордера при
касании; в противном случае - ложь. По умолчанию установлено значение false.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure

Syntax
IsFillLimitOnTouch

Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
IsFillLimitOnTouch = true;
}
}

IsInstantiatedOnEachOptimizationIteration
Определение
Определяет, следует ли повторно создавать (воссоздавать) стратегию после каждого прогона
оптимизации при использовании оптимизатора Strategy Analyzer.

Поведение по умолчанию заключается в повторном создании экземпляра стратегии для


каждого прогона бэктеста оптимизации. Однако процесс повторного создания стратегии
требует больше времени и компьютерных ресурсов для получения результатов, что может
повлиять на количество времени, необходимое для выполнения оптимизации. Если
установлено значение false, стратегия используется повторно для экономии времени и
ресурсов компьютера. Согласно этой схеме внутренние свойства сбрасываются до значений по
умолчанию после каждой итерации, но возможно, что определенные пользователем свойства и
другие настраиваемые ресурсы могут перенести свое состояние из предыдущей итерации в
новый прогон бэктеста. Чтобы воспользоваться преимуществами оптимизации
производительности, разработчикам может потребоваться сбросить переменные уровня класса
в стратегии, иначе могут возникнуть неожиданные результаты.

Примечание. Если вы решили воспользоваться преимуществами производительности во время


оптимизации стратегии, установив для свойства IsInstantiatedOnEachOptimizationIteration
значение false, любые объекты, которые вы создаете в своем коде, ДОЛЖНЫ быть сброшены
во время соответствующего состояния в методе OnStateChange (). См. Пример ниже в разделе
«Ручной сброс переменных уровня класса, чтобы воспользоваться преимуществами
производительности оптимизатора Strategy Analyzer».

Стоимость имущества
Это свойство возвращает истину, если стратегия не используется повторно; в противном
случае - ложь. По умолчанию установлено значение true.

Предупреждение: это свойство должно устанавливаться ТОЛЬКО из метода OnStateChange ()


во время State.SetDefaults или State.Configure
Syntax
IsInstantiatedOnEachOptimizationIteration

Совет: индикаторы и стратегии NinjaTrader по умолчанию были оптимизированы для


использования преимуществ оптимизации производительности, поскольку их ресурсы
настроены> = State.Configure. Пожалуйста, просмотрите системные индикаторы и стратегии по
умолчанию, чтобы узнать, как вы можете улучшить свою стратегию и эффективность
индикаторов, или вы также можете сослаться на пример кода ниже.

Examples

Использование IsInstantiatedOnEachOptimizationIteration для сброса


переменных уровня класса
// Пользовательский словарь сделок создается при создании стратегии
// поскольку позже мы установили для IsInstantiatedOnEachOptimizationIteration значение true,
// мы гарантированно начинаем с нового объекта при каждом запуске оптимизации

private Dictionary<DateTime, string> myTrades = new Dictionary<DateTime, string>();

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "My Optimization Test 1";
Description = "Demonstrates using IsInstantiatedOnEachOptimizationIteration to reset a class
level variable";
Fast = 10;
Slow = 25;
// устанавливаем значение true, чтобы наш словарь пользовательских сделок сбрасывался
при каждом запуске оптимизации (влечет за собой снижение производительности)
// Это поведение по умолчанию.

IsInstantiatedOnEachOptimizationIteration = true;
}

else if (State == State.Terminated)


{
// Выводим количество сделок по окончании оптимизации
if (myTrades != null)
{
/ если мы установим для IsInstantiatedOnEachOptimizationIteration значение false (то есть
не будем использовать значение по умолчанию true), значения здесь будут неожиданными
// поскольку пользовательский торговый словарь никогда явно не сбрасывался в конце
каждой оптимизации

Print(myTrades.Count);
}
}
}

protected override void OnBarUpdate()


{
if (CurrentBar < BarsRequiredToTrade)
return;

if (CrossAbove(SMA(Fast), SMA(Slow), 1))


{
EnterLong();
myTrades.Add(Time[0], "long");

}
else if (CrossBelow(SMA(Fast), SMA(Slow), 1))
{
EnterShort();
myTrades.Add(Time[0], "short");
}
}

[Range(1, int.MaxValue), NinjaScriptProperty]


[Display(Name = "Fast", GroupName = "NinjaScriptStrategyParameters", Order = 0)]
public int Fast
{ get; set; }

[Range(1, int.MaxValue), NinjaScriptProperty]


[Display(Name = "Slow", GroupName = "NinjaScriptStrategyParameters", Order = 1)]
public int Slow
{ get; set; }

Ручной сброс переменных уровня класса, чтобы воспользоваться


преимуществами оптимизатора Strategy Analyzer
// Пользовательский словарь сделок объявляется при первой оптимизации стратегии,
// но не создается позже в State.DataLoaded,

private Dictionary<DateTime, string> myTrades;

// примеры других полей, которые нужно сбросить


private double myDouble;
private bool myBool;
private DateTime myDateTime;
private Order myOrderObject;
private Brush myBrushObject;
private SMA mySMAIndicator;
private Array myIntArray;
private List<object> myList;
private Series<double> mySeries;

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
Name = "My Optimization Test 2";
Description = "Demonstrates manually resetting a class level variable without re-instantiating the
strategy";
Fast = 10;
Slow = 25;

// в этом случае нам не нужно повторно создавать экземпляр стратегии после каждой
оптимизации
// потому что мы явно сбрасываем пользовательский торговый словарь в State.DataLoaded
// Этот вариант повторного использования экземпляра стратегии дает преимущества в
производительности

IsInstantiatedOnEachOptimizationIteration = false;
}

else if (State == State.DataLoaded)


{
// воссоздаем пользовательский торговый словарь при каждом запуске оптимизации
// мы гарантированно начинаем с нового объекта при каждом запуске оптимизации

if (myTrades != null)
myTrades.Clear();
else
myTrades = new Dictionary<DateTime, string>();
// Любые поддерживаемые значения стратегии по умолчанию не нужно сбрасывать, если
они не изменяются во время выполнения стратегии.
// Любое состояние стратегии, которое может быть изменено после State.SetDefaults,
необходимо сбросить для следующего запуска.

myDouble = double.MinValue;
myBool = false;
myDateTime = DateTime.MinValue;
myOrderObject = null;
myBrushObject = null;
mySMAIndicator = SMA(14);

if (myIntArray != null)
Array.Clear(myIntArray, 0, myIntArray.Length);
else
myIntArray = new int[20];

if (myList != null)
myList.Clear();
else
myList = new List<object>();

mySeries = new Series<double>(this);


}
}

protected override void OnBarUpdate()


{
if (CurrentBar < BarsRequiredToTrade)
return;

if (CrossAbove(SMA(Fast), SMA(Slow), 1))


{
EnterLong();
myTrades.Add(Time[0], "long");

}
else if (CrossBelow(SMA(Fast), SMA(Slow), 1))
{
EnterShort();
myTrades.Add(Time[0], "short");
}
}

[Range(1, int.MaxValue), NinjaScriptProperty]


[Display(Name = "Fast", GroupName = "NinjaScriptStrategyParameters", Order = 0)]
public int Fast
{ get; set; }

[Range(1, int.MaxValue), NinjaScriptProperty]


[Display(Name = "Slow", GroupName = "NinjaScriptStrategyParameters", Order = 1)]
public int Slow
{ get; set; }

IsInStrategyAnalyzer
Определение
Определяет, запускается ли текущая стратегия NinjaScript из диаграммы Анализатора
стратегий.

Стоимость имущества
Логическое значение, если истинно, стратегия запускается из диаграммы Анализатора
стратегий; в противном случае вернет false.

Syntax
IsInStrategyAnalyzer

Examples

protected override void OnBarUpdate()


{
// Рисуем ArrowUp только для нашего условия, если мы не находимся на графике
анализатора стратегий
if (Close[0] > SMA(High, 14)[0] && !IsInStrategyAnalyzer)
Draw.ArrowUp(this, CurrentBar.ToString(), true, 0, High[0] + TickSize, Brushes.Blue);
}

IsTradingHoursBreakLineVisible
Определение
Наносит на индикаторную панель линии излома торговых часов.

Примечание. Родительский график панели индикатора имеет аналогичное свойство


«Построить линию разрыва сеанса», которое, если установлено значение false,
переопределит локальную настройку индикатора, если оно истинно.

Стоимость имущества
Это свойство возвращает истину, если на панели индикатора нанесены линии разрыва
торговых часов; в противном случае - ложь. По умолчанию установлено значение true.

Предупреждение: это свойство должно быть установлено ТОЛЬКО из метода


OnStateChange () во время State.SetDefaults или State.Configure
Syntax
IsTradingHoursBreakLineVisible

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
IsTradingHoursBreakLineVisible = true;
AddPlot(Brushes.Orange, "SMA");
}
}

IsWaitUntilFlat
Определение
Указывает, что стратегия в настоящее время ожидает обнаружения плоской позиции перед
отправкой живых ордеров.
Примечание. Это свойство будет применяться только в том случае, если для стратегии
StartBehavior задано значение StartBehavior.WaitUntilFlat или
StartBehavior.WaitUntilFlatSynchronizeAccount.

Стоимость имущества
Это свойство возвращает истину, если стратегия обнаружила, что она находится в длинной или
короткой позиции во время State.Transition; в противном случае - ложь. По умолчанию
установлено значение false.
Syntax
IsWaitUntilFlat
Examples

// Если стратегия ожидает флетовой позиции, возвращаемся и печатаем сообщение


if (!IsWaitUntilFlat)
{
Print("This strategy is currently waiting for a flat account position to begin placing trades");
return;
}

NumberRestartAttempts

Определение
Определяет максимальное количество попыток перезапуска, разрешенное в течение
последних x минут, определенных в RestartsWithinMinutes, когда стратегия испытывает потерю
соединения. Если количество попыток перезапуска превышает это свойство в течение периода
времени, меньшего или равного RestartsWithinMinutes, то стратегия будет остановлена и
дальнейших попыток не будет. Цель этих настроек - остановить стратегию, если ваше
соединение нестабильно и не может поддерживать согласованное состояние подключения.

Стоимость имущества
Значение типа int представляет максимальное количество попыток перезапуска. По умолчанию
установлено значение 4.

Syntax
NumberRestartAttempts
Examples
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
// Разрешить перезапуск стратегии только 4 раза в промежутке времени MaxRestartMinutes
// При отключении более 4 раз за этот промежуток времени остановите стратегию и не
// пытаемся перезапустить дальше.

NumberRestartAttempts = 4;
}
}

OnAccountItemUpdate()
Определение
Управляемый событиями метод, используемый для стратегий, который вызывается для
каждого обновления AccountItem для учетной записи, на которой выполняется стратегия.

Примечание. OnAccountItemUpdate () будет вызываться постоянно в реальном времени, если


на счете, на котором работает стратегия, существует позиция. Это необходимо для обновления
текущих значений нереализованной прибыли и убытков и связанных с ними рисков.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис

Вы должны переопределить метод в своей стратегии, используя следующий синтаксис:

protected override void OnAccountItemUpdate(Account account, AccountItem accountItem, double


value)
{

}
Method Parameters

account Аккаунт обновлен

accountItem AccountItem обновлен

value Значение AccountItem обновлено.

Examples
protected override void OnAccountItemUpdate(Account account, AccountItem accountItem, double
value)
{
Print(string.Format("{0} {1} {2}", account.Name, accountItem, value));
// output:
// Sim101 BuyingPower 103962.5
// Sim101 CashValue 103962.5
// Sim101 GrossRealizedProfitLoss 3962.5
// Sim101 RealizedProfitLoss 3962.5
}

AccountItemEventArgs
Определение
AccountItemEventArgs содержит информацию об учетной записи, которая должна быть
передана в качестве аргумента событию OnAccountItemUpdate ().

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

Перечисленные ниже свойства доступны из экземпляра AccountItemEventArgs:

Account Учетная запись, для которой был вызван


OnAccountItemUpdate ()

AccountItem AccountItem, который обновился, что привело


к вызову OnAccountItemUpdate ()

Currency Валюта рассматриваемого Счета

Time Объект DateTime, представляющий время,


когда произошло изменение

Value Новое значение обновленных AccountItems

Example
// Этот метод запускается при любом изменении AccountItem
private void OnAccountItemUpdate(object sender, AccountItemEventArgs e)
{
/ * Dispatcher.InvokeAsync () необходим для многопоточности. При обработке
событий вне потока пользовательского интерфейса, и мы хотим
влиять на пользовательский интерфейс .InvokeAsync () позволяет нам это делать.
Это также может помочь предотвратить блокировку потока пользовательского
интерфейса при длительных операциях. * /

Dispatcher.InvokeAsync(() =>
{
/ Распечатываем, какой AccountItem изменился, для какой учетной записи и новое
значение, используя
outputBox.AppendText(string.Format("{0}Account: {1}{0}AccountItem: {2}{0}Value: {3}",
Environment.NewLine,
e.Account.Name,
e.AccountItem,
e.Value));
});

OnExecutionUpdate()
Определение
Управляемый событиями метод, который вызывается при поступлении выполнения заказа,
управляемого стратегией. Исполнение - это другое название исполнения заказа.

• Ордер может генерировать несколько исполнений (частичное исполнение)

• OnExecutionUpdate обычно вызывается после вызова OnOrderUpdate ().

• OnExecutionUpdate () будет вызывать только заказы, которые были отправлены и


управляются с помощью стратегии.

Примечания:

• Программирование в этой среде зарезервировано для более опытных пользователей.


Например, если вы хотите защитить позицию, управляемую стратегией, с помощью базового
стопа и цели, то методы Set () будут более удобными.

• При подключении к соединению воспроизведения OnExecutionUpdate () может срабатывать в


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

• Также ознакомьтесь с рекомендациями по многопоточности для NinjaScript.

• Лучше всего работать только с параметрами, переданными по значению, а не со ссылочными


параметрами. Это гарантирует, что вы обрабатываете каждое изменение базового состояния.

• Пользователи Rithmic и Interactive Brokers: из-за конструкции API провайдера эти адаптеры не
гарантируют последовательность событий OnOrderUpdate, OnExecution и OnPositionUpdate.
Поэтому при работе над стратегией, которая будет работать в этих соединениях,
рекомендуется работать только с данными, передаваемыми по значению из этого обратного
вызова, чтобы устранить зависимость от последовательности событий.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в своей стратегии, используя следующий синтаксис:
protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int
quantity, MarketPosition marketPosition, string orderId, DateTime time)
{

}
Parameters

execution Объект Execution, переданный по ссылке,


представляющий выполнение

executionId Строковое значение, представляющее


идентификатор выполнения

price Двойное значение, представляющее цену


исполнения

quantity Значение типа int, представляющее


количество выполнения

marketPosition Объект MarketPosition, представляющий


позицию исполнения. Возможные значения:

• MarketPosition.Long

• MarketPosition.Short

orderId Строка, представляющая идентификатор


заказа.
time Значение DateTime, представляющее время
выполнения

Пример OnExecutionUpdate

// Пример
protected override void OnExecutionUpdate(Execution execution, string executionId, double price,
int quantity, MarketPosition marketPosition, string orderId, DateTime time)
{
Print(execution.ToString());
}
Дополнительные эталонные образцы
Дополнительные образцы кода доступны в разделе «Образовательные ресурсы NinjaScript» на
нашем форуме поддержки.

OnOrderTrace()
Определение
Управляемый событиями метод, используемый для стратегий, который позволит вам настроить
вывод TraceOrders.

Предупреждение: переопределите этот метод, отключив отслеживание ордеров по умолчанию,


которое генерируется ядром NinjaTrader. Затем вы должны передать сгенерированное
сообщение в окно вывода NinjaTrader с помощью метода Print (). Как правило,
переопределение этого метода не требуется.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в своей стратегии, используя следующий синтаксис:
protected override void OnOrderTrace(DateTime timestamp, string message)
{

Method Parameters

timestamp `Время создания трассировки заказа

message Сообщение, которое создается


Examples
protected override void OnOrderTrace(DateTime timestamp, string message)
{
// Приведенный ниже вывод даст нам трассировку по умолчанию
Print(string.Format("{0} {1}", timestamp, message));

// Расширенный пример также будет включать полное имя инструмента из нашего объекта
первичных баров
if (BarsArray[0] != null)
Print(string.Format("{0} {1} {2}", timestamp, message, BarsArray[0].Instrument.FullName));
}

Дополнительные эталонные образцы


Дополнительные образцы кода доступны в разделе «Образовательные ресурсы NinjaScript» на
нашем форуме поддержки.

OnOrderUpdate()
Определение
Управляемый событиями метод, который вызывается каждый раз, когда заказ, управляемый
стратегией, меняет состояние. Заказ изменит состояние, когда произойдет изменение
количества, цены или состояния заказа (от рабочего до выполненного). Вы можете
использовать этот метод для программирования собственной обработки отклонения заказа.

Примечания:

• OnOrderUpdate () будет вызывать только заказы, которые были отправлены и управляются


стратегией.

• Программирование в этой среде зарезервировано для более опытных пользователей.


Например, если вы хотите защитить позицию, управляемую стратегией, с помощью базового
стопа и цели, то методы Set () будут более удобными.

• Для запуска таких действий, как отправка стоп-лосса и целевого ордера с использованием
настраиваемой логики ОСО, когда ваш ордер на вход заполнен, мы рекомендуем вместо этого
работать непосредственно в OnExecutionUpdate ().

• OnOrderUpdate () будет запускаться внутри методов заказа, таких как EnterLong () или
SubmitOrderUnmanaged (), поэтому попытка назначить объект заказа вне OnOrderUpdate ()
может не вернуть, как ожидалось. Если ваша стратегия зависит от отслеживания объекта
заказа с самого первого обновления, вам следует попытаться сопоставить объекты заказа по
order.Name (имя сигнала) во время OnOrderUpdate (), поскольку заказ обновляется впервые.

• Пользователи Rithmic и Interactive Brokers: из-за конструкции API провайдера эти адаптеры не
гарантируют последовательность событий OnOrderUpdate, OnExecution и OnPositionUpdate.
Поэтому при работе над стратегией, которая будет работать в этих соединениях,
рекомендуется работать только с данными, передаваемыми по значению из этого обратного
вызова, чтобы устранить зависимость от последовательности событий.
Критично: если вы хотите управлять логикой своей стратегии на основе выполнения заказов,
вы должны использовать OnExecutionUpdate () вместо OnOrderUpdate (). OnExecutionUpdate ()
всегда запускается после OnOrderUpdate (). Существует внутренняя логика стратегии, которая
запускается после вызова OnOrderUpdate (), но до OnExecutionUpdate (), что может
отрицательно повлиять на вашу стратегию, если вы полагаетесь на отслеживание заполнения
в OnOrderUpdate ().

Подключение к воспроизведению
При подключении к Playback Connection вызов методов на основе рыночного ордера, таких как
EnterLong () и EnterShort (), приведет к запуску событий состояния ордера до того, как метод
ордера вернет объект ордера. Это сделано для того, чтобы все события были
синхронизированы при высокоскоростном воспроизведении.

Возвращаемое значение метода


Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в своей стратегии, используя следующий синтаксис:
protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity,
int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string
comment)
{

Method Parameters

order Объект заказа, переданный по ссылке,


представляющий объект заказа

limitPrice Двойное значение, представляющее


лимитную цену обновления ордера.

stopPrice Двойное значение, представляющее стоп-


цену обновления ордера.

quantity Значение типа int, представляющее


количество обновлений заказа.

filled Значение типа int, представляющее


заполненную сумму обновления заказа.

averageFillPrice Двойное значение, представляющее


среднюю цену исполнения обновления
заказа.
orderState Значение OrderState, представляющее
состояние заказа (например, заполнен,
отменен, отклонен и т. Д.).

Примечание. См. Таблицу значений


состояния заказа ниже.

time Структура DateTime, представляющая время


последнего изменения состояния заказа.

error Значение ErrorCode, которое классифицирует


ошибку, полученную от брокера.

Возможные значения:

ErrorCode.LoginExpired
ErrorCode.LogOnFailed
ErrorCode.NoError
ErrorCode.OrderRejected
ErrorCode.OrderRejectedByRisk
ErrorCode.Panic
ErrorCode.UnableToCancelOrder
ErrorCode.UnableToChangeOrder
ErrorCode.UnableToSubmitOrder
ErrorCode.UserAbort

comment Строка, представляющая сообщение об


ошибке, предоставленное непосредственно
брокером.

OrderState Values

OrderState.Initialized Ордер инициализируется в NinjaTrader

OrderState.Submitted Ордер передан брокеру

OrderState.Accepted Ордер принят брокером или биржей

OrderState.TriggerPending Заказ ожидает отправки

OrderState.Working Ордер работает в очереди на обмен

OrderState.ChangePending Изменение ордера ожидается в


NinjaTrader

OrderState.ChangeSubmitted Изменение заявки отправляется


брокеру

OrderState.CancelPending Отмена ордера ожидается в


NinjaTrader

OrderState.CancelSubmitted Отмена заявки отправляется брокеру.

OrderState.Cancelled Подтверждение отмены заказа


получено от брокера

OrderState.Rejected Заказ отклонен

OrderState.PartFilled Заказ выполнен частично

OrderState.Filled Заказ полностью выполнен

OrderState.Unknown Неизвестное состояние заказа. По


умолчанию, если брокер не сообщает
о текущем состоянии ордера.

Examples
Понимание параметра объекта заказа и параметра обновления значения
(соображения многопоточности для NinjaScript)
protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice,
int quantity, int filled, double averageFillPrice,
Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string
comment)
{
Print("The most current order state is: " + order.OrderState); // OrderState.PartFilled
Print("This particular order update state is: " + orderState); // OrderState.Working
}

Properly assigning order object values


private Order entryOrder = null;

protected override void OnBarUpdate()


{
if (entryOrder == null && Close[0] > Open[0])
EnterLong("entryOrder");
}

protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int
quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode
error, string nativeError)
{
// проверяем, совпадает ли текущий ордер с orderName, переданным в "EnterLong" ()
// Назначьте entryOrder в OnOrderUpdate (), чтобы гарантировать, что назначение
происходит, когда ожидалось.
// Это более надежно, чем присвоение объектов Order в OnBarUpdate, так как не
гарантируется, что назначение будет завершено, если на него сделана ссылка сразу
после отправки

if (order.Name == "entryOrder")
entryOrder = order;

// если существует порядок входа


if (entryOrder != null && entryOrder == order)
{
Print(order.ToString());
if (order.OrderState == OrderState.Cancelled)
{
// Здесь что-нибудь делаем
entryOrder = null;
}
}
}

OnPositionUpdate()
Определение
Управляемый событиями метод, который вызывается каждый раз, когда позиция
стратегии меняет состояние.

• Этот метод обычно вызывается после OnExecutionUpdate ()


• OnPositionUpdate () вызывается при каждом изменении позиции стратегии.

Примечания:

• Вы НЕ будете получать обновления позиций для размещенных вручную ордеров или


ордеров, управляемых другими стратегиями (включая любые стратегии банкоматов) в
OnPositionUpdate (). Класс Account содержит предварительно созданный обработчик
событий (PositionUpdate), который можно использовать для фильтрации обновлений
позиции в указанной учетной записи.

• Лучше всего работать только с параметрами, переданными по значению, а не со


ссылочными параметрами. Это гарантирует, что вы обрабатываете каждое изменение
базового состояния.

• Пользователи Rithmic и Interactive Brokers: из-за конструкции API провайдера эти


адаптеры не гарантируют последовательность событий OnOrderUpdate, OnExecution и
OnPositionUpdate. Поэтому при работе над стратегией, которая будет работать в этих
соединениях, рекомендуется работать только с данными, передаваемыми по значению
из этого обратного вызова, чтобы устранить зависимость от последовательности
событий.
Возвращаемое значение метода
Этот метод не возвращает значения.

Синтаксис
Вы должны переопределить метод в своей стратегии, используя следующий синтаксис:

protected override void OnPositionUpdate(Position position, double averagePrice, int quantity,


MarketPosition marketPosition)
{

}
Method Parameters

positionposition Объект Position, переданный по ссылке,


представляющий текущий объект позиции

averageFillPrice Двойное значение, представляющее


обновленную среднюю цену исполнения
позиции.

quantity Значение типа int, представляющее


количество обновлений позиции

marketPosition Объект MarketPosition, представляющий


обновленное обновление позиции,
предоставленное непосредственно от
брокера. Это не фактический объект
основной позиции Position, а последнее
изменение рыночной позиции.
Возможные значения:

• MarketPosition.Flat

• MarketPosition.Long

• MarketPosition.Short

Examples

protected override void OnPositionUpdate(Cbi.Position position, double averagePrice,


int quantity, Cbi.MarketPosition marketPosition)
{
if (position.MarketPosition == MarketPosition.Flat)
{
// Сделаем что-то вроде сброса некоторых переменных здесь
}
}

Понимание параметра объекта заказа и параметра обновления значения


(соображения многопоточности для NinjaScript)
protected override void OnPositionUpdate(Cbi.Position position, double averagePrice,
int quantity, Cbi.MarketPosition marketPosition)
{
Print("The most current MarketPosition is: " + position.MarketPosition); // Flat
Print("This particular position update marketPosition is: " + marketPosition); // Long
}

OptimizationPeriod
Определение
Зарезервированное для пошаговой оптимизации, это свойство определяет количество дней,
используемых для периода тестирования на исторических данных «в выборке» для данной
стратегии. См. Также TestPeriod.

Примечание. Это свойство должно вызываться ТОЛЬКО из метода OnStateChange () во время


State.SetDefaults.

Стоимость имущества
Значение типа int, представляющее количество дней "в выборке", используемых для прямой
оптимизации; По умолчанию установлено 10.
Syntax
OptimizationPeriod

Examples

protected override void OnStateChange()


{
if (State == State.SetDefaults)
{
// устанавливаем период оптимизации по умолчанию на 20 дней для WFO
OptimizationPeriod = 20;
}
}

Order
Определение
Представляет интерфейс только для чтения, который предоставляет информацию о заказе.

• Объект Order, возвращаемый при вызове метода заказа, является динамическим в том
смысле, что его свойства всегда отражают текущее состояние заказа.

• Свойство <Order> .OrderId НЕ является уникальным значением, так как оно может изменяться
в течение всего срока действия заказа. Пожалуйста, см. Раздел «Обработка авансовых
заказов» «Переход от исторических ссылок к текущим заказам», чтобы узнать, как это делать.

• К свойству <Order> .Oco БУДЕТ добавлен суффикс, когда стратегия переходит из истории в
режим реального времени, чтобы гарантировать, что идентификатор OCO является
уникальным для нескольких стратегий для текущих заказов.

• Чтобы проверить равенство, вы можете напрямую сравнить объекты Order.


Methods and Properties

Account Учетная запись, в которой находится заказ

AverageFillPrice Двойное значение, представляющее


среднюю цену исполнения заказа.

Filled Значение типа int, представляющее


заполненную сумму заказа.

FromEntrySignal Строка, представляющая определяемый


пользователем параметр fromEntrySignal в
заказе.
Gtd Структура DateTime, представляющая, когда
заказ будет отменен

HasOverfill Логическое значение, указывающее,


является ли заказ переполненным. Для
использования при использовании
неуправляемых заказов и IgnoreOverFill

Instrument Стоимость инструмента, представляющая


инструмент ордера.

IsLiveUntilCancelled Логическое значение, когда истина,


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

IsTerminalState() Статический метод, используемый для


определения того, находится ли OrderState
ордера в рассматриваемом терминале и
больше не активен.

LimitPrice Двойное значение, представляющее


лимитную цену ордера.

Name Строка, представляющая имя ордера,


которое может быть предоставлено именем
сигнала входа или выхода.

Oco Строка, представляющая идентификатор


OCO (один отменяет другой) ордера.

OrderAction Представляет действие заказа. Возможные


значения:

OrderAction.Buy

OrderAction.BuyToCover

OrderAction.Sell

OrderAction.SellShort

OrderId Строка, представляющая значение


идентификатора ордера, выданного
брокером (это значение может изменяться).

OrderState Текущее состояние заказа. См. Таблицу


значений состояния заказа ниже

OrderType Тип отправленного заказа. Возможные


значения:

OrderType.Limit

OrderType.Market
OrderType.MIT
OrderType.StopMarket

OrderType.StopLimit

Quantity Значение типа int, представляющее


количество заказа.

StopPrice Двойное значение, представляющее стоп-


цену ордера.

Time Структура DateTime, представляющая время


последнего изменения состояния заказа.

TimeInForce Определяет срок жизни заказа. Возможные


значения:

TimeInForce.Day

TimeInForce.Gtc

ToString() Строковое представление заказа

OrderState Values

OrderState.Initialized Ордер инициализируется в NinjaTrader

OrderState.Submitted Ордер передан брокеру

OrderState.Accepted Ордер принят брокером или биржей

OrderState.TriggerPending Заказ ожидает отправки

OrderState.Working Ордер работает в очереди на обмен

OrderState.ChangePending Изменение ордера ожидается в NinjaTrader

OrderState.ChangeSubmitted Изменение заявки отправляется брокеру

OrderState.CancelPending Отмена ордера ожидается в NinjaTrader

OrderState.CancelSubmitted Отмена заявки отправляется брокеру.

OrderState.Cancelled Отмена заказа подтверждается обменом

OrderState.Rejected Заказ отклонен

OrderState.PartFilled Заказ выполнен частично

OrderState.Filled Заказ полностью выполнен

OrderState.Unknown Неизвестное состояние заказа. По


умолчанию, если брокер не сообщает о
текущем состоянии ордера.
Критично: при историческом бэктестировании заказы всегда достигают состояния «Работает».
В режиме реального времени некоторые стоп-приказы могут достичь состояния «Принято»
только в том случае, если они имитируются / удерживаются на сервере брокера.

Examples

private Order entryOrder = null;

protected override void OnBarUpdate()


{
if (entryOrder == null && Close[0] > Open[0])
EnterLong("myEntryOrder");
}

protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int
quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error,
string nativeError)
{
// Назначьте entryOrder в OnOrderUpdate (), чтобы гарантировать, что назначение
происходит, когда ожидалось.
// Это более надежно, чем присвоение объектов Order в OnBarUpdate, так как не
гарантируется, что назначение будет завершено, если на него сделана ссылка сразу после
отправки

if (order.Name == "myEntryOrder")
entryOrder = order;

if (entryOrder != null && entryOrder == order)


{
Print(order.ToString());
if (order.OrderState == OrderState.Filled)
entryOrder = null;
}
}

IsTerminalState()
Определение
Статический метод, используемый для определения того, считается ли OrderState заказа
терминальным и больше не активным.
Примечание. Это статический метод, который сравнивается с состоянием заказа, а НЕ с самим
заказом. Пожалуйста, посмотрите пример ниже для правильного использования синтаксиса.

Возвращаемое значение метода


Значение типа bool, которое вернет истину, если OrderState равен OrderState.Cancelled,
OrderState.Filled, OrderState.Rejected, OrderState.Unknown; в противном случае ложно.

Syntax
IsTerminalState(OrderState orderState)

Parameters

orderState OrderState для сравнения

Examples

private Order entryOrder = null;

protected override void OnBarUpdate()


{
// отправляем заказ при правильном условии
// обратите внимание, что назначение и обработка заказа выполняется в OnOrderUpdate ()

if (entryOrder == null && Close[0] > Open[0])


EnterLongLimit(Close[0] - 1, "myEntryOrder");
}

protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int
quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error,
string nativeError)
{
// назначаем входящий ордер
if (entryOrder == null)
{
// проверяем соответствие порядка по имени сигнала, что порядок не находится в
состоянии терминала
if (order.Name == "myEntryOrder" && !Order.IsTerminalState(order.OrderState))
entryOrder = order;
}

if (entryOrder != null && entryOrder == order)


{
// устанавливаем для "entryOrder" значение null, если оно отменено, заполнено, отклонено,
неизвестно
if (Order.IsTerminalState(entryOrder.OrderState))
entryOrder = null;
}
}

Order Methods
Примечание: вы не сможете смешивать и сочетать два подхода. Если вы решите использовать
управляемый подход, вы сможете использовать только методы управляемого заказа. Если вы
решите использовать неуправляемый подход, вы сможете использовать только неуправляемые
методы заказа.

Обзор методов заказа

NinjaScript предоставляет несколько подходов, которые вы можете использовать для


размещения заказа в рамках своей стратегии NinjaScript. Основные подходы можно разделить
на управляемый подход и неуправляемый подход.

Managed

Управляемый подход предлагает вам методы ордеров, которые обернуты невидимым удобным
слоем, который позволяет вам сосредоточиться на торговых правилах вашей системы,
оставляя основную механику управления ордерами и отношения между ордерами на вход и
выход и позициями для NinjaTrader. Плата за использование уровня удобства заключается в
том, что существуют правила обработки заказов, которые необходимо соблюдать, чтобы
предотвратить ошибки в заказе.

Managed Approach
Управляемый подход в NinjaScript разработан, чтобы предложить максимальную
простоту использования для начинающих и программистов среднего уровня. Методы
ордеров обернуты в удобный слой, который позволяет вам сосредоточиться на
торговых правилах вашей системы, оставляя основную механику управления ордерами
и отношения между ордерами на вход, выходом и позициями на NinjaTrader. Этот подход
лучше всего подходит для простых и средних заказов и может быть далее разбит на
базовый / общий управляемый подход и более продвинутый управляемый подход. В
следующем разделе будет обсуждаться использование базового / общего подхода.

Следует иметь в виду несколько ключевых моментов:

• Ордера отправляются как живые и работающие, когда стратегия работает в режиме


реального времени.
• Целевая прибыль, стоп-лосс и трейл-стоп-ордера отправляются сразу после
заполнения ордера на вход и связываются вместе через OCO (один отменяет другой)

• Изменения и отмены заказов ставятся в очередь в том случае, если заказ находится в
состоянии, в котором его нельзя отменить или изменить.

• По умолчанию заказы, отправленные с помощью методов Entry () и Exit (),


автоматически отменяются в конце бара, если не отправлены повторно.

• Методы Entry () автоматически меняют положение. Например, если вы находитесь в


длинной позиции по 1 контракту и теперь вызываете EnterShort () ->, вы увидите 2
исполнения: одно для закрытия предыдущей длинной позиции, а другое - для открытия
желаемой короткой позиции по 1 контракту.

* С помощью методов SetProfitTarget (), SetStopLoss (), SetTrailStop () и SetParabolicStop

Подача заявки на методы входа и выхода - базовая операция

Заказы в основном отправляются из метода OnBarUpdate (), когда вызывается конкретный


метод заказа. По умолчанию заказы сохраняются при условии, что они повторно отправляются
при каждом вызове метода OnBarUpdate (). Если заказ не будет отправлен повторно, он будет
отменен. Ордера можно изменить, повторно отправив их с измененными параметрами
(например, с новой лимитной ценой).

В приведенном ниже примере ордер Buy Limit работает по цене предложения, при условии, что
цена закрытия текущего бара больше, чем текущее значение 20-периодной простой
скользящей средней. Если условие входа больше не выполняется и ордер по-прежнему
активен, он будет немедленно отменен.
protected override void OnBarUpdate()
{
// Условие входа
if (Close[0] > SMA(20)[0])
EnterLongLimit(GetCurrentBid());
}

Этот метод позволяет вам максимально быстро и просто отправлять заказы, подходящие для
программистов всех уровней. Если вы хотите отправить заказ и не должны повторно
отправлять его, чтобы поддерживать его в рабочем состоянии, вы можете использовать
расширенный подход, предназначенный для опытных программистов, который включает в себя
возможность поддерживать заказы до тех пор, пока они не будут отменены в коде.

Способы ввода заказа


Способы ввода заказа
Способы ввода заявок используются для подачи заявок разных типов. Существуют методы
подачи рыночных, рыночных, лимитных, стоп-рыночных и стоп-лимитных ордеров. См.
Страницы, посвященные методам ввода заказов, перечисленные в содержании справочного
руководства на этой странице для получения дополнительной информации о конкретном
методе.

Имена сигналов о методах входа


При желании вы можете пометить ордер на вход именем сигнала. Имена сигналов
используются для идентификации выполнения в результате заказа на графике и в отчетах о
производительности. Рыночные позиции, созданные с помощью тегированного метода входа,
помечаются именем сигнала, которое служит двум целям:

• Используется для привязки метода выхода к определенной позиции

• Используется для идентификации уникальных записей в стратегии.

Ниже приведен пример размещения ордера на вход в рынок и связанного с ним лимитного
ордера на выход, связанных вместе именем сигнала ордера на вход.
protected override void OnBarUpdate()
{
if (CurrentBar < 1) return;

if (Close[0] > Close[1])


{
// Размещение рыночного ордера для входа в длинную позицию
EnterLong("longEntry");

// Вручную устанавливаем цель прибыли на 10 тиков выше текущей цены, привязанную к


SignalName ордера входа
ExitLongLimit(Close[0] + (10 * TickSize), "longEntry");
}
}
Определение того, как методы входа обрабатываются в стратегии
Вы можете ограничить количество обрабатываемых методов входа, определив максимальное
количество входов в одном направлении для всех методов входа или для уникальных имен
сигналов. Следующие свойства можно установить в окне «Стратегии» при добавлении
стратегии на диаграмму или на вкладке «Стратегии» окна «Центр управления».
• Свойство EntriesPerDirection - устанавливает максимальное количество записей в одном
направлении.

• Свойство EntryHandling - определяет, применяется ли EntriesPerDirection ко всем записям или


к записям с указанными именами сигналов.
В приведенном ниже примере кода показано, как указанные выше свойства управляют
обработкой методов входа. Код содержит два условия входа и два метода