Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Для того чтобы написать скрипт на TSLab API необходимо создать класс наследованный от интерфейса IExternalScript.
Данный интерфейс имеет следующую реализацию:
Как видим, интерфейс имеет всего один метод Execute, который принимает два параметра.
IContext - содержит общий контекст скрипта, нужен для рисования графиков, кеширования.
ISecurity - позволяет работать с инструментом, содержит свечи, тики, можно работать с позициями.
Метод Execute вызывается каждый раз когда TSLab запускает пересчет скрипта.
Также можно использовать другие интерфейсы, они различаются только количеством инструментов в параметрах:
IExternalScript2 – на входе два инструмента (ISecurity)
IExternalScript3 – на входе три инструменты (ISecurity)
IExternalScript4 – на входе четыре инструмента (ISecurity)
IExternalScriptMultiSec – на входе массив инструментов (ISecurity)
Для написания скриптов можно использовать следующий шаблон:
Основный свойства и методы:
Интерфейс IContext
IsLastBarClosed
IsLastBarUsed
IsFixedBarsCount
Для определения количества баров в расчете.
IsOptimization
Показывает, что идет процесс оптимизации.
TradeFromBar
Указывает с какого бара начинать торговлю.
ScriptResult
Выводит результат в таблицу оптимизации.
GetData(...)
Работа с кешем. Используется для расчета индикаторов.
LoadObject(...)
StoreObject(...)
Работа с кешем скрипта, который не стирается между расчетами.
LoadGlobalObject(...)
StoreGlobalObject(...)
Работа с глобальным кешем, который является общим между различными агентами и скриптами.
Данные в кеше могут быть стерты, если программе не хватает памяти.
Log(...)
Вывод логов.
Recalc(...)
Запустить заново скрипт.
Интерфейс ISecurity
FinInfo
Текущие данные по ценной бумаге (bid, ask, цена последней сделки, открытый интерес и т.д.).
Bars
Список свечей.
OpenPrices
HighPrices
LowPrices
ClosePrices
Volumes
Список цен открытия.
Список максимумов.
Список минимумов.
Список цен закрытия.
Список объемов.
Interval
IntervalBase
IntervalInstance
Интервал ценной бумаги.
LotSize
LotTick
Margin
Tick
Decimals
Размер лота для ценной бумаги.
Размер изменения лота для ценной бумаги.
Коэффициент маржи для ценной бумаги.
Минимально возможное изменение цены.
Количество десятичных знаков для цены ценной бумаги.
Positions
Список позиций.
Commission
Делегат для расчета комиссии.
InitDeposit
Начальный депозит.
IsRealtime
Показывает находится ли агент в режиме реальной торговли.
Symbol
Символ ценной бумаги.
CompressTo(...)
CompressToPriceRange(...)
CompressToVolume(...)
Decompress(...)
Сжатие и разжатие свечей.
GetBuyQueue(...)
GetSellQueue(...)
UpdateQueueData(...)
Получить очередь заявок.
GetTrades(...)
Получить список сделок.
RoundPrice(...)
RoundShares(...)
Округление входящей цены до минимального тика.
Округление входящего количества до минимального шага лота.
В TSLab API есть стандартные часто используемые индикаторы. Их можно без труда использовать в своих скрипта. Эти индикаторы находятся в двух местах:
TSLab.Script.Helpers.Series - класс содержит статичные методы расчета индикаторов, например SMA, EMA, Highest, Lowest, ATR, BollingerBands и другие.
TSLab.Script.Handlers - пространство имен, в котором содержатся классы обработчиков, например MACD, ParabolicSAR, TrailStop. Все эти обработчики отображаются в визуальном редакторе TSLab в виде кубиков.
В классе Series содержатся некоторые индикаторы, например SMA, EMA, Highest, Lowest, ATR, BollingerBands и другие.
К примеру, если нужно посчитать индикатор SMA, то просто вызываем метод SMA и передаем первым параметром список цен по которым нужно считать (sec.ClosePrices), а вторым параметром будет период расчета:
Напишем скрипт, который выводит на график индикаторы SMA и EMA от цен закрытия:
Красная линия - это индикатор SMA, синяя линия - это EMA.
TSLab.Script.Handlers - пространство имен, в котором содержатся классы обработчиков, например MACD, ParabolicSAR, TrailStop. Все эти обработчики отображаются в визуальном редакторе TSLab в виде кубиков.
В отличии от индикаторов из Series, нужно сначала создать объект индикатора а потом вызвать метод Execute для расчета значений индикатора.
Исходные коды индикаторов:
https://github.com/TSLab-Dev/Handlers
Для примера напишем скрипт, который считает и выводит на график индикатор ParabolicSAR:
Еще для примера напишем скрипт, который покупает по рынку и выставляем трейл-стоп. Стоп будет считаться готовым классом TrailStop из TSLab.Script.Handlers:
Как видим, происходит сделка и сразу выставляется трейл-стоп (красная линия), которая подтягивается вслед за ценой:
При написании скриптов на TSLab API можно определить параметры, которые можно будет настраивать из TSLab вкладка Оптимизация. Также эти параметры используются при оптимизации скрипта.
Например, скрипт строит индикатор SMA. Для его расчета необходимо значение периода по которому рассчитывается индикатор. Чтобы это значение не записывать в коде, мы можем добавить параметр в скрипт и использовать его в качестве расчета.
Эта строка описывает свойство с типом OptimProperty. Свойство содержит тип double. По-умолчанию будет значение 100, при оптимизации будут перебираться значения от 10 до 200 с шагом 1.
Существуют разные типы параметров:
Типы параметров
OptimProperty
Число с плавающей точкой (double)
IntOptimProperty
Целое число (int) (Только положительное!)
BoolOptimProperty
Логическое значение (bool)
DateTimeOptimProperty
Дата и время (DateTime)
EnumOptimProperty
Перечисление (Enum)
StringOptimProperty
Строка (String)
TimeSpanOptimProperty
Интервал времени (TimeSpan)
Напишем скрипт, который рассчитывает два значения SMA, быстрое и медленное. Периоды SMA будем передавать через параметры скрипта:
На вкладке Оптимизация мы видим наши параметры, там их можно редактировать.
Доступ ко всем позициям скрипта осуществляется через свойство ISecurity.Positions. ISecurity.Positions - это список позиций.
Для каждой позиции назначается название сигнала. В один момент может быть активна только одна позиция с одним названием.
Например, если создали позицию "LE" и ее не закрыли, то нельзя создать вторую позицию с таким же названием.
Для открытия позиций используются методы sec.Positions.BuyXXX(...) для покупки и sec.Positions.SellXXX(...) для продажи.
Примеры покупок:
Примеры продаж:
Часто используемый метод для получения позиции GetLastActiveForSignal(...), пример:
Метод ищет активную позицию с названием "LE" и ее возвращает, если нету позиций, то метод вернет null.
Также существуют другие методы для получения позиций, все они пишутся так: sec.Positions.GetXXX(...).
Для изменении размера позиции используются методы pos.ChangeAtXXX(...), при этом передается размер новой позиции.
Например, чтобы увеличить длинную позицию на 2 контракта по рынку, надо написать pos.ChangeAtMarket(i + 1, pos.Shares + 2, "LX"); Тут pos.Shares показывает текущее количество контрактов позиции, а когда мы передаем pos.Shares + 2, это означает, что надо увеличить позицию на 2 контракта.
Если же передать отрицательное значение, например -3, то позиция перевернется в короткую с тремя контрактами.
Примеры:
Для закрытия позиции используются методы pos.CloseAtXXX(...).
Примеры:
Важно заметить, что методы которые закрывают позицию по условию (CloseAtPrice, CloseAtProfit, CloseAtStop) должны выставляться на каждом баре пока не закроется позиция, иначе TSLab снимет ордер закрытия на бирже.
Некоторые методы позиции:
Для примера напишем скрипт, который будет покупать после растущей свечи по рынку и выставлять стоп 200 пунктов и тейк 400 пунктов:
Свойство ISecurity.FinInfo предоставляет текущие данные по бумаге. Например, можно посмотреть текущие цены bid/ask, цену открытия, открытый интерес, дату экспирации если есть, гарантийные обязательства и многое другое.
Полный список можно посмотреть здесь.
Пример скрипта, который выводит в лог текущие цены bid и ask при каждом пересчете:
Свойство ISecurity.Bars предоставляет список свечей. Этот список состоит из объектов IDataBar, которые содержат время, цены, объем, открытый интерес.
Подробное описание текстовых файлов источников можно посмотреть здесь.
Пример скрипта, который рассчитывает и отображает на графике медианную цену по барам:
Для удобства, интерфейс ISecurity предоставляет различные списки цен:
OpenPrices
Список цен открытия
ClosePrices
Список цен закрытия
HighPrices
Список максимумов
LowPrices
Список минимумов
Volumes
Список объемов
Пример скрипта, который отображает на графике максимальные и минимальные цены:
Для кеширования результатов индикаторов существует методы IContext.GetData(...), которые могут работать с тремя типами списков: double, int, bool.
В прошлой статье мы рассчитывали индикатор SMA таким образом:
При проведении оптимизации расчет SMA с одинаковым периодом будет повторяться много раз. Чтобы убрать лишние расчеты и уменьшить время оптимизации существует кеширование. Предыдущий пример можно переписать так:
Метод GetData работает с кешем данных, кеш представляет из себя таблицу КЛЮЧ - ЗНАЧЕНИЕ, где:
КЛЮЧ - это строка, она всегда уникальная в таблице, не может существовать несколько одинаковых ключей.
ЗНАЧЕНИЕ - это список значений (double, int, bool).
Метод GetData принимает три параметра:
Первый параметр - префикс ключа. В данном примере это "SMA".
Второй параметр - это массив строк из которых строится окончание ключа. В данном примере передается значение периода в виде строки (PeriodFast.ToString()), например оно равно 100. Тогда полное название ключа будет таким "SMA:100". Если бы передавалось несколько значений, например 100, 20, 40, то ключ был бы таким "SMA:100:20:40".
Третий параметр - это делегат, который вызывается если нету в кеше данных по заданному ключу. То есть это и есть расчет значений индикатора. Делегат должен возвращать список значений double, int или bool.
Как это работает. Изначально кеш данных пустой. Когда мы запрашиваем расчет SMA с периодом 100, то формируется ключ "SMA:100". Этот ключ ищется в кеш таблице, но его там нету, так как таблица пустая. Тогда вызывается делегат, который рассчитывает значение SMA. Результат записывается в кеш таблицу с ключом "SMA:100" и метод GetData возвращает этот результат. Если мы снова запрашиваем расчет SMA с периодом 100, то в кеш таблице будет искаться ключ "SMA:100". Так как он есть, то метод GetData сразу вернет значение по этому ключу, при этом не будет вызываться делегат.
Кеш значений сбрасывается на каждом пересчете скрипта. В режиме оптимизации кеш не сбрасывается.
Пример скрипта с кеширированием двух скользящих средних:
Рассмотрим пример со сложным кешированием. К примеру, нам надо построить границу верхнего канала по максимальным ценам, а потом сгладить эту границу по SMA. Получается что расчет канала зависит от периода канала, а расчет SMA зависит от периода SMA и от периода канала. Поэтому при расчете SMA надо передавать два параметра, период SMA и период канала. Полный пример:
Помните, что если неверно задать параметры кеширования, то результаты оптимизации будут неверные.
Локальный кеш - сохраняемые данные, которые доступны только текущему скрипту.
Глобальный кеш - сохраняемы данные, которые доступны всем скриптам и агентам.
Методы для работы с локальным кешем:
IContext.StoreObject(...) - Записать объект в кеш
IContext.LoadObject(...) - Загрузить объект из кеша.
Методы для работы с глобальным кешем:
IContext.StoreGlobalObject(...) - Записать объект в глобальный кеш.
IContext.LoadGlobalObject(...) - Загрузить объект из глобального кеша
Важно: периодически кеш данных очищается для освобождения места. Для того чтобы при очередном сжатии не удалились данные их нужно обернуть в класс NotClearableContainer.
Пример с глобальным кешем:
Примечание: при кешировании на диск идет сериализация объекта через BinaryFormatter. Поэтому все классы объектов, которые кешируются должны иметь атрибут [Serializable].
Для работы с очередью заявок в интерфейсе ISecurity есть следующие методы:
GetBuyQueue(int barNum) - Получить очередь заявок для покупок.
GetSellQueue(int barNum) - Получить очередь заявок для продаж.
UpdateQueueData() - Обновить закешированный стакан (не влияет на FinInfo.Ask / FinInfo.Bid).
Методы GetBuyQueue и GetSellQueue выдают список объектов IQueueData. На данный момент эти методы всегда возвращают текущую очередь, т.е. не зависят от передаваемого параметра barNum.
Интерфейс IQueueData
IsBuyPart
LastUpdate
Время последнего обновления
Price
Цена
Quantity
Количество
HasOwnOrderContains
Есть ли наши ордеры
Security
Доступ к инструменту
Пример, выведем данные очередей в лог:
Информация из TSLab совпадает с данными из терминала.
Для получения списка сделок существует метод ISecurity.GetTrades(...). Он имеет две реализации:
GetTrades(int barNum) - Получить список сделок по номеру свечи.
GetTrades(int firstBarIndex, int lastBarIndex) - Получить список сделок по нескольким свечам.
В обоих случаях методы возвращают список объектов ITrade.
Интерфейс ITrade
Date
Дата и время
TradeNo
Номер сделки
Direction
Направление сделки (Buy, Sell)
Price
Цена
Quantity
Количество
OpenInterest
Открытый интерес
Пример, получаем последние 5 сделок и выводи их в лог:
Информация из TSLab полностью совпадает с данными из терминала.
Блок 'Внешний скрипт' может принимать несколько инструментов. В этом случае класс скрипта нужно наследовать от интерфейса IExternalScriptMultiSec.
Существует два варианта подключения блоков.
Вариант 1:
Для каждого инструмента добавить блок 'Торгуемый инструмент'. Каждый блок соединить с блоком 'Внешний скрипт'. Таким образом можно подключить до 50 источников к внешнему скрипту.
Вариант 2:
Добавить блок 'Мульти-источник', в нем выбрать необходимые инструменты. Двойным кликом по мультиисточнику открывается форма, инструменты выбираются списком. Мульти-источник соединить с блоком 'Внешний скрипт'. В примере добавлены блоки 'Инструмент по номеру'. Этот блок извлекает инструмент по указанному номеру из мульти-источника и подает его на панель графика. Данный блок можно не добавлять если скрипт (c#) сам выводит графики.
Пример скрипта:
В метод Execute приходит массив инструментов (ISecurity[]). Выведем в лог список названий инструментов.
Результат: