Секреты TSLab | Торговые роботы | События
26 Мар

Кэш скриптов для чайника. Часть 4.

В статье “Кэш скриптов для чайника. Часть 3” мы разобрались как сохранять информацию между пересчетами скрипта и какие из этого могут быть выгоды. В этой части мы разберем возможность обмена информацией между разными скриптами.

Кэш скриптов – доступен для всех

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

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

Работа с глобальным кэшэм производится совершенно так же, как мы делали в предыдущей части статьи. Единственно, названия методов отличаюся: StoreGlobalObject/LoadGlobalObject. Полные сигнатуры методов были описаны в первой части статьи. Давайте создадим простой алгоритм состоящий из двух скриптов. Один скрипт будет записывать число своих запусков в глобальный кэш, а другой скрипт будет считывать данное число и выводить его в окно сообщений.

using TSLab.Script;
using TSLab.Script.Handlers;

namespace test
{
    /// <summary>
    /// Скрипт является поставщиком данных для скрипта клиента.
    /// В качестве данных передается просто число запусков.
    /// </summary>
    public class StoreDataGlobalHost : IExternalScript
    {
        public void Execute(IContext ctx, ISecurity sec)
        {
            // Загружаем из глобального кэша данные. Если в кэшэ ничего нет, счетчик равен 0.
            var cache = ctx.LoadGlobalObject("counter");
            var counter = cache == null ? 0 : (int)cache ;
            counter++;

            // Сохраняем в кэш счетчик запусков.
            ctx.StoreGlobalObject("counter", counter);
        }
    }
}
using TSLab.Script;
using TSLab.Script.Handlers;

namespace test
{
    /// <summary>
    /// Скрипт является потребителем данных от хост скрипта.
    /// В качестве данных передается просто число запусков.
    /// </summary>
    public class StoreDataGlobalClient: IExternalScript
    {
        public void Execute(IContext ctx, ISecurity sec)
        {
            // Загружаем из глобального кэша данные. Если в кэшэ ничего нет, счетчик равен 0.
            var cache = ctx.LoadGlobalObject("counter");
            var counter = cache == null ? 0 : (int)cache ;

            var color = System.Drawing.Color.Green;
            ctx.Log("Скрипт StoreDataGlobalTestHost отработал {0} раз.".Put(counter), new Color(color.ToArgb()));
        }
    }
}

Теперь запустим хост скрипт с пересчетом раз в 5 секунд, а клиент скрипт с пересчетом раз в 15 секунд. Даже не обязательно использовать запуск агентов для этого, все можно посмотреть и в режиме лаборатории. Главное не забываем включить опцию “обновлять в реальном времени”.

Кэш скриптов для чайника. Часть 4.

Рисунок 1. Внешний вид хост скрипта.

Кэш скриптов для чайника. Часть 4.

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

Рисунок 3. Результат работы всей связки.

Как можно заметить, клиентский скрипт запускается реже чем хост скрипт, и естественно между его запусками хост скрипт успевает убежать на пару итераций. Это мы и наблюдаем. Иногда даже разница в 4 итерации набегает. Но это все цветочки! Давайте попробуем передать информацию о текущей позиции одного скрипта, в другой скрипт и воспользоваться данной информацией!

ВАЖНО: глобальный кэш никогда не сбрасывается. Только путем закрытия программы TSLab вы можете обнулить данный кэш. Как говорится: “Уж записал, так записал!”.

Передача информации о текущей позиции скрипта

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

using TSLab.Script;
using TSLab.Script.Handlers;

namespace test
{
    /// <summary>
    /// Скрипт является поставщиком данных для скрипта клиента.
    /// В качестве данных передается текущая позиция скрипта
    /// </summary>
    public class StoreDataGlobalPositionHost : IExternalScript
    {
        public void Execute(IContext ctx, ISecurity sec)
        {
            var le = sec.Positions.GetLastActiveForSignal("LE");

            // Сохраняем в кэш счетчик запусков.
            ctx.StoreGlobalObject("HostPosition", le);

            if (le == null)
            {
                sec.Positions.BuyAtMarket(ctx.BarsCount, 1, "LE");
            }
            else
            {
                if (ctx.BarsCount - le.EntryBarNum > 5)
                    le.CloseAtMarket(ctx.BarsCount, "LX");
            }
        }
    }
}
using TSLab.Script;
using TSLab.Script.Handlers;

namespace test
{
    /// <summary>
    /// Скрипт является потребителем данных от хост скрипта.
    /// В качестве данных принимается позиция из другого скрипта.
    /// </summary>
    public class StoreDataGlobalPositionClient: IExternalScript
    {
        public void Execute(IContext ctx, ISecurity sec)
        {
            // Загружаем из глобального кэша данные.
            var cache = ctx.LoadGlobalObject("HostPosition");

            if (cache != null)
            {
                var pos = cache as IPosition;

                var color = System.Drawing.Color.Green;
                var msg = string.Format("Скрипт StoreDataGlobalPositionHost имеет позицию. Цена входа: {0}.",pos.EntryPrice);
                ctx.Log(msg, new Color(color.ToArgb()), true);
            }
        }
    }
}

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

Кэш скриптов для чайника. Часть 4.

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

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

Вот, пожалуй и все. Все, что я знал о кэшэ скриптов я рассказал. Надеюсь вам это поможет в вашей работе!

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


comments powered by HyperComments

Андрей
2015-04-26 17:18:52
Родион, добрый день! К примеру, у меня около 15-20 агентов на Si, каждый качает себе историю. Но по факту, это совершенно идентичная история для всех агентов. Будет ли разумно скачивать историю один раз, загонять ее в кэш, а потом выдавать ее остальным агентам?
ra81
2015-04-26 20:37:11
Нет это даже усложнит жизнь. ТСлаб историю подгрузит сам, проведет необходимую обработку и передаст вашим агентам. Пытаться ее как то со стороны дергать не совсем хороший вариант. НО если у вас есть мегатяжелый расчет, то нет смысла его делать в каждом агенте. Сделайте центральный агент и раздавайте результаты другим потребителям. Через кэш конечно. Могут быть нюансы из за неопределенности порядка пересчета у агентов, то есть потребитель может запросить а данных новых расчетных еще нет. Тут придется подумать как проблему решить.
Андрей
2015-04-26 23:04:46
Да, тоже подумал про проблему синхронизации агентов... Собственно, МЕГАтяжелых расчетов нет, для i7 медиану из тысячи значений посчитать - это ерунда) И про центрального агента тоже была мысль. Но если это жизнь только усложнит, то не буду улучшать то, что и так работает))
Жора
2017-01-01 07:01:11
Казино Вулкан раздают деньги сегодня http://cenforce100.ru/casino-vulkan.php
6
Ноя
2017

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

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

7
Окт
2017

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

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

8
Сен
2017

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

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

6
Авг
2017

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

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

14
Июл
2017

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

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