Перейти к содержанию

Как управлять сиБотами и индикаторами с помощью алгоритмов

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

В этой статье и соответствующем видео мы покажем вам, как создавать и работать с сиБотами, которые управляют другими алгоритмами.

Добавление индикатора с помощью сиБота

В приложении Algo откройте вкладку сиБоты. Найдите и выберите образец Sample Trend cBot, который использует скользящие средние.

Определите два индикатора.

1
2
ChartIndicator _indicator1;
ChartIndicator _indicator2;

Добавьте два индикатора на график.

1
2
_indicator1 = Chart.Indicators.Add("Simple Moving Average", SourceSeries, FastPeriods, MAType);
_indicator2 = Chart.Indicators.Add("Simple Moving Average", SourceSeries, SlowPeriods, MAType);

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

Мы сделаем линию для первого индикатора красной и толстой.

1
2
_indicator1.Lines[0].Color = Color.Red;
_indicator1.Lines[0].Thickness = 3;

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

1
2
3
4
5
protected override void OnBarClosed()
{
    Chart.Indicators.Remove(_indicator1);
    Chart.Indicators.Remove(_indicator2);
}

Вы можете скопировать полный код ниже:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
    public class SampleTrendcBot : Robot
    {
        [Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        [Parameter("MA Type", Group = "Moving Average")]
        public MovingAverageType MAType { get; set; }

        [Parameter("Source", Group = "Moving Average")]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Slow Periods", Group = "Moving Average", DefaultValue = 10)]
        public int SlowPeriods { get; set; }

        [Parameter("Fast Periods", Group = "Moving Average", DefaultValue = 5)]
        public int FastPeriods { get; set; }

        private MovingAverage slowMa;
        private MovingAverage fastMa;
        private const string label = "Sample Trend cBot";   

        ChartIndicator _indicator1;
        ChartIndicator _indicator2;

        protected override void OnStart()
        {
            fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
            slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);

            _indicator1 = Chart.Indicators.Add("Simple Moving Average", SourceSeries, FastPeriods, MAType);
            _indicator2 = Chart.Indicators.Add("Simple Moving Average", SourceSeries, SlowPeriods, MAType);

            _indicator1.Lines[0].Color = Color.Red;
            _indicator1.Lines[0].Thickness = 3;
        }

        protected override void OnBarClosed()
        {
            Chart.Indicators.Remove(_indicator1);
            Chart.Indicators.Remove(_indicator2);
        }

        protected override void OnTick()
        {
            var longPosition = Positions.Find(label, SymbolName, TradeType.Buy);
            var shortPosition = Positions.Find(label, SymbolName, TradeType.Sell);

            var currentSlowMa = slowMa.Result.Last(0);
            var currentFastMa = fastMa.Result.Last(0);
            var previousSlowMa = slowMa.Result.Last(1);
            var previousFastMa = fastMa.Result.Last(1);

            if (previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa && longPosition == null)
            {
                if (shortPosition != null)
                    ClosePosition(shortPosition);

                ExecuteMarketOrder(TradeType.Buy, SymbolName, VolumeInUnits, label);
            }
            else if (previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa && shortPosition == null)
            {
                if (longPosition != null)
                    ClosePosition(longPosition);

                ExecuteMarketOrder(TradeType.Sell, SymbolName, VolumeInUnits, label);
            }
        }

        private double VolumeInUnits
        {
            get { return Symbol.QuantityToVolumeInUnits(Quantity); }
        }
    }
}

Чтобы собрать сиБота, используйте горячую клавишу Ctrl+B или нажмите Собрать.

Перейдите в приложение Трейдинг. Выберите график EURUSD, нажмите на значок сиБот, найдите и выберите Sample Trend cBot.

Когда появится окно Добавить экземпляр, нажмите Применить, а затем запустите сиБота.

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

Запуск сиБота с помощью другого сиБота

Мы продемонстрируем, как управлять сиБотом через другого сиБота. На этот раз мы создадим новый пустой сиБот с нуля.

Перейдите в приложение Algo и нажмите кнопку Создать на вкладке сиБоты. Выберите опцию Пустой, введите имя, например Add cBots, а затем нажмите Создать.

Начнем с определения двух объектов графических роботов.

1
2
ChartRobot _robot1;
ChartRobot _robot2;

Затем добавим эти роботы на график в методе OnStart().

1
2
_robot1 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 10, 5);
_robot2 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 12, 7);

Мы также можем добавить обработчик событий для вывода сообщения при каждом запуске сиБота.

1
2
3
4
5
6
Chart.Robots.RobotStarted += ChartRobots_RobotStarted;

private void ChartRobots_RobotStarted(ChartRobotStartedEventArgs obj)
{
    Print ("Robot Started");
}

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
protected override void OnBarClosed()
{
    if (_robot1.State == RobotState.Stopped)
    {
        _robot1.Start();
        _robot2.Stop();
            }
    else if (_robot1.State == RobotState.Running)
    {
        _robot1.Stop();
        _robot2.Start();
    }
}

Вы можете скопировать полный код ниже:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class AddcBots : Robot
    {

        ChartRobot _robot1;
        ChartRobot _robot2;

        protected override void OnStart()
        {
            _robot1 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 10, 5);
            _robot2 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 12, 7);

            Chart.Robots.RobotStarted += ChartRobots_RobotStarted;
        }

        private void ChartRobots_RobotStarted(ChartRobotStartedEventArgs obj)
        {
            Print ("Robot Started");

        }

        protected override void OnBarClosed()
        {
            if (_robot1.State == RobotState.Stopped)
            {
                _robot1.Start();
                _robot2.Stop();
            }

            else if (_robot1.State == RobotState.Running)
            {
                _robot2.Start();
                _robot1.Stop();
            }
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

После того как вы соберете сиБота, вернитесь в приложение Трейдинг, найдите и выберите Add cBots, а затем запустите сиБота.

Когда появится диалоговое окно Запрос разрешения, нажмите Разрешить.

Два экземпляра Sample Trend cBot должны появиться на графике.

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

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

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

Изменение параметров сиБота во время выполнения

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

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

1
2
3
4
5
6
else if(_robot1.State == RobotState.Running)
{
_robot1.Stop();
_robot1.Parameters["SlowPeriods"].Value = (int)_robot2.Parameters["SlowPeriods"].Value + 1;
_robot1.Start();
}

Теперь мы пересоберем сиБота.

Вы можете скопировать полный код ниже:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class AddcBots : Robot
    {

        ChartRobot _robot1;
        ChartRobot _robot2;

        protected override void OnStart()
        {
            _robot1 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 10, 5);
            _robot2 = Chart.Robots.Add("Sample Trend cBot", 0.01, MovingAverageType.Simple, Bars.ClosePrices, 12, 7);

            Chart.Robots.RobotStarted += ChartRobots_RobotStarted;
        }

        private void ChartRobots_RobotStarted(ChartRobotStartedEventArgs obj)
        {
            Print ("Robot Started");

        }

        protected override void OnBarClosed()
        {
            if (_robot1.State == RobotState.Stopped)
            {
                _robot1.Start();
                _robot2.Stop();
            }

            else if (_robot1.State == RobotState.Running)
            {
                _robot1.Stop();
                _robot1.Parameters["SlowPeriods"].Value = (int)_robot2.Parameters["SlowPeriods"].Value + 1;
                _robot1.Start();
            }
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
    }
}

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

Обзор

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