Секреты TSLab | Торговые роботы | События
13 Июн

Индикаторы TSLab с несколькими вЫходами.

Лаборатория торговых роботов TSLab позволяет создавать блоки визуального редактора (индикаторы) любой сложности, но, как обычно, есть небольшая проблема. Невозможно создавать индикаторы TSLab имеющие несколько выходов. С одним выходом – пожалуйста. Неоднократно вопрос про несколько выходов был задан на форуме, очевидно, что пользователям хочется иметь такую возможность. Собственно, для тех, кто умеет слегка программировать на TSLab API в этой статье я дам отличную инструкцию на этот счет.

Индикаторы TSLab с несколькими выходами. Зачем?

Статей на тему TSLab было мной написано уже немало, и чаще всего в комментариях начинается троллинг: “Да нафиг это все надо?”, “Ты ерундой страдаешь!”, “Да я все делаю на калькуляторе МК60 и прочитал пол книжки по трейдингу и заработал уже миллиарды!”. Ну и прочее, прочее.  Если вы считаете что вам это не нужно, значит вам это не нужно. Кто-то не может проснуться без стакана водки, а я не могу без стакана воды. Так что тут нет одного ответа для всех. Читайте дальше и определяйте для себя сами.

Индикаторы TSLab могут выполнять различную работу помимо типичных расчетов скользящих/плавающих/ползающих индикаторов. Например, могут обработать массив тиковых данных по инструменту и получить на выходе некий набор информации. Пусть это будут 3 числа. На входе блока у нас инструмент, а на выходе 3 числа. Это невозможно? И ДА и НЕТ. Невозможно сделать стандартным способом, возможно сделать благодаря небольшой хитрости.

А почему не сделать 3 блока, каждый из которых будет вычислять 1 число и возвращать его нам? Это обычный блок, и делается без всяких хитростей. А потому, что однократный обсчет массива тиков занимает 1-2 секунды, а троекратный обсчет займет уже 3-6 секунд. Если данных на выходе не 3 а больше, то получаем линейный рост времени выполнения вашего скрипта. Оно вам надо? Думаю нет. Способ описанный ниже, позволит производить расчет 1 раз вместо 3-х. При этом сложность индикатора увеличится незначительно.

Сразу скажу, что подобный механизм реализован в системе “RusAlgo.Storage“, которая позволяет сохранять историю стакана и доп. информацию по инструменту в базу данных и затем использовать это в своих скриптах. Так что, схема рабочая и позволяет промышленное применение.

Постановка задачи

Предваряя сидение за Visual Studio мы озаботимся четким формулированием исходной задачи. Итак, наш блок будет обрабатывать тиковые данные по инструменту. В результате работы на выходе должны быть 3 величины. Пусть это будет: Максимальный объем сделки, Минимальный объем сделки, Объем сделок больше 3 лотов. Общий объем сделок у нас уже содержится в каждой свече в виде Объема.

Вход: Инструмент

Выход: Максимальный объем сделки, Минимальный объем сделки, Объем сделок больше 3 лотов.

Дополнительно: объемы сделок вычисляем в валюте инструмента, то есть в пунктах для фьючерса и рублях для других активов котирующихся в рублях.

Почему выбраны такие данные для выхода? Потому, что внутри одной обработки исходного массива тиков можно получить все эти значения произведя только один перебор элементов. Проще говоря, эти три величины разом можно получить быстрее, чем если считать их по-отдельности. Отсюда Экономия времени, а следовательно нагрузка на ресурс вашего сервера меньше. Владельцы паркинга скриптов это оценят.

Секрет фирмы

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

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

Реализация

Сначала, напишем метод, производящий обработку тиков.

    struct Data
    {
        public double MaxTrade;
        public double MinTrade;
        public double Lot3Volume;
    }

    class Calc
    {
        public static IList<Data> Execute(ISecurity sec)
        {
            var values = new Data[sec.Bars.Count];
            for (var i = 0; i < sec.Bars.Count; i++)
            {
                var trades = sec.GetTrades(i);

                if (trades.Any())
                {
                    values[i].MinTrade = double.MaxValue;
                    values[i].MaxTrade = double.MinValue;
                }

                foreach (var trade in trades)
                {
                    // Объем сделок в валюте. А не в лотах
                    var tv = trade.Quantity * trade.Price;

                    if (tv > values[i].MaxTrade)
                        values[i].MaxTrade = tv;

                    if (tv < values[i].MinTrade)
                        values[i].MinTrade = tv;

                    if (trade.QuantityInLots > 3)
                        values[i].Lot3Volume += tv;
                }
            }

            return values;
        }
    }

Обратите внимание, что для возврата итогов расчета я использовал дополнительную структуру “Data”. Мне показалось так удобнее, я и сделал. Вообще, программирование достаточно развращающая штука. Вы все время делаете так, как вам кажется правильным, что в конце концов может внушить мысль что вы всегда делаете правильно :) . Программа не может обидеться или сказать что ей неприятен ваш стиль программирования :) . Будьте осторожны с программистами :) .

Теперь нам нужно нарисовать индикаторы TSLab в количестве трех штук, каждый из которых будет отвечать за определенное значение.  Приведу пример для кубика “Максимальный объем сделки”. Остальные придется вам додумать самим, иначе все будет уж слишком легко.

    [HandlerCategory("RusAlgo.Test")]
    [HandlerName("MaxTrade")]
    public class MaxTradeHnd : IOneSourceHandler, ISecurityInputs, IDoubleReturns, IStreamHandler, IContextUses
    {
        public IContext Context { set; private get; }

        public IList<double> Execute(ISecurity sec)
        {
            var ctx = Context;
            var aCache = ctx.LoadObject("DataCache");
            if (aCache == null)
            {
                var res = Calc.Execute(sec);
                ctx.StoreObject("DataCache", res);
                aCache = res;
            }

            var values = (IList<Data>)aCache;

            return values.Select(data => data.MaxTrade).ToArray();
        }
    }

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

ВАЖНО: в данном примере я не описывал все необходимые элементы для полноценной работы такой схеме в реальном времени. Необходимо проверять соответствие кэша текущим свечкам, и проверять возможные рассинхронизации данных в кэшэ и свечек. Это отдельный вопрос, и здесь рассматриваться не будет. Для режима тестирования подобный подход будет работать, а для реалтайма требует доработок.

Тестирование

Если вы уже устали читать, то тут самое вкусное. Будем тестировать наше поделие и смотреть, где допущены ошибки (если таковые есть конечно). Собрав кубик и подключив к TSLab слепим скрипт следующего содержания:

Индикаторы TSLab с несколькими выходами

Рисунок 1. Внешний вид получившегося скрипта.

Запустим сей скрипт и посмотрим итоги его работы:

Индикаторы TSLab с несколькими выходами.

Рисунок 2. Итоги работы скрипта.

Теперь, путем нехитрых манипуляций с кодом, можно легко находить точки, где в игру вступают большие дяди и проходят сделки больших объемов. Что с этим делать? Решать вам.

Итоги

В столь малом числе букв я постарался раскрыть еще одну сторону могущества кэша скриптов. Теперь вы сможете создавать достаточно сложные индикаторы не теряя в производительности. Как я выше уже упоминал, данный подход используется в наших разработках “RusAlgo.Storage”. Без описанных хитростей, работа наших индикаторов была бы очень медленной.

Есть еще одно полезное применение такого подхода, позволяющее централизовать хранение настроек в одном кубике, и использовать эти настройки в нескольких других. Опять же это реализовано в “RusAlgo.Storage”. Но это совсем другая история.

PS: А где же обещанный пирог?? Где ускорение работы? Как его пощупать? Предлагаю либо поверить мне :) , либо поиграть с этим тоже поиграть самостоятельно. Вы можете слегка изменить код кубиков и запустить скрипт не используя преимущества кэширования. Сравните 2 числа и получите разницу в скорости работы.


comments powered by HyperComments

Расима
2017-01-01 21:08:37
Казино Вулкан раздают деньги сегодня http://cenforce100.ru/casino-vulkan.php
8
Сен
2017

Доверительное управление. Результаты в августе 2017 года.

Доверительное управление. Результаты в августе 2017 года. Стратегия “Опционы” принесла в августе прибыль в размере… »

6
Авг
2017

Доверительное управление. Результаты в июле 2017 года.

Доверительное управление. Результаты в июле 2017 года. В июле индекс РТС вновь колебался в достаточно узком… »

14
Июл
2017

Доверительное управление. Результаты в июне 2017 года.

Доверительное управление. Результаты в июне 2017 года. Июнь индекс РТС вновь провел преимущественно в боковых движениях, а… »

11
Июн
2017

Доверительное управление. Результаты в мае 2017 года.

Доверительное управление. Результаты в мае 2017 года. В мае “болтанка” индекса РТС продолжилась, на паре… »

7
Май
2017

Доверительное управление. Результаты в апреле 2017 года.

Доверительное управление. Результаты в апреле 2017 года. В апреле мы наблюдали очередной месяц “боковика” по… »