Tradematic Support Center
Guides, articles, videos and links for Tradematic users and developers.
Пример использования новой функции Tradematic Trader — «мультипозиции» («пирамидинг»)
132480СТАТЬЯ РЕДАКТОР КОДА МУЛЬТИПОЗИЦИИ ПИРАМИДИНГ НАРАЩИВАНИЕ ПОЗИЦИИ ENTRYSIGNAL ACTIVEPOSITIONSСтатья посвящена появлению нового функционала в Tradematic Trader — возможности наращивать или уменьшать позицию по инструменту.
Мультипозиции — что это?
Иногда требуется открывать позицию не сразу на весь объем, а постепенно — наращивая размер позиции по мере срабатывания условий. Или закрывать позицию не полностью. Начиная с версии 1.7.3, Tradematic Trader поддерживает эту возможность.
Как реализовано?
Фактически, мультипозиции — это несколько открытых позиций по одному инструменту в одном направлении. При синхронизации счета с такой стратегией считается чистая позиция по всем активным позициям, и уже с ней выполняется синхронизация. На данный момент для использования мультипозиций требуется вносить изменения в исходный код скрипта через встроенный Редактор кода.
Пример использования мультипозиций
В нашем примере мы будем использовать три группы условий, каждая группа будет входить на 10% от капитала по одному инструменту. При срабатывании всех трех условий на вход суммарная позиция будет 30% по инструменту, при срабатывании всех трех условий на выход — позиция будет 0, при срабатывании части условий — 10% или 20%.
Группировать условия можно с помощью последнего параметра в функциях BuyAt.. и SellAt.. — названия сигнала:
BuyAtClose(bar, "SMA2");У нас будет три группы:
1) Группа «SMA1»:
вход, если Close > SMA(6),
выход — Close < SMA(6)
2) Группа «SMA2»:
вход, если Close > SMA(6),
выход — Стоп-лосс (1.1%) или Тэйк-профит (3.2%)
3) Группа «SMA3»:
вход, если Close > SMA(18),
выход — Close < SMA(18)
Итак, приступим.
Добавляем три параметра в конструктор:
public MyScript() { parameter0 = CreateParameter("Период SMA1 (LE)", 6, 0, 100, 1); parameter1 = CreateParameter("Период SMA2 (LE)", 9, 0, 100, 1); parameter2 = CreateParameter("Период SMA3 (LE)", 18, 0, 100, 1); }Первая группа условий:
// вход в позицию if (MarketPositionBySignal("SMA1") == 0) { if (Close[bar] > SMA.Value(bar, Close, parameter0.ValueInt)) BuyAtClose(bar, "SMA1"); } else if (MarketPositionBySignal("SMA1") == 1) { // Выход из длинной позиции if (Close[bar] < SMA.Value(bar, Close, parameter0.ValueInt)) SellAtClose(bar, GetPositionBySignal("SMA1"), "SMA1"); }Вторая группа условий:
// вход в позицию if (MarketPositionBySignal("SMA2") == 0) { if (Close[bar] > SMA.Value(bar, Close, parameter1.ValueInt)) BuyAtClose(bar, "SMA2"); } else if (MarketPositionBySignal("SMA2") == 1) { Position p = GetPositionBySignal("SMA2"); // Выход из длинной позиции if (p.NetProfitAsOfBarPercent(bar) < -1.1) { SellAtClose(bar, p, "SMA2 — SL"); } else if (p.NetProfitAsOfBarPercent(bar) > 3.2) { SellAtClose(bar, p, "SMA2 — TP"); } }Третья группа условий:
// вход в позицию if (MarketPositionBySignal("SMA3") == 0) { if (Close[bar] > SMA.Value(bar, Close, parameter2.ValueInt)) BuyAtClose(bar, "SMA3"); } else if (MarketPositionBySignal("SMA3") == 1) { // Выход из длинной позиции if (Close[bar] < SMA.Value(bar, Close, parameter2.ValueInt)) SellAtClose(bar, GetPositionBySignal("SMA3"), "SMA3"); }Как мы видим, используется немного другая логика проверки на текущую активную позицию. С помощью функции MarketPositionBySignal() мы проверяем, в каком состоянии находится позиция из определенной группы (это аналог функции MarketPosition для однопозиционных стратегий). С помощью функции GetPositionBySignal() мы получаем активную позицию из определенной группы (аналог функции LastPosition).
Итоговый код
using System; using System.Collections.Generic; using System.Text; using System.Drawing; using TradeMatic; using TradeMatic.Indicators; namespace ScriptNamespace { class MyScript : Script { private StrategyParameter parameter0; private StrategyParameter parameter1; private StrategyParameter parameter2; public MyScript() { parameter0 = CreateParameter("Период SMA1(LE)", 6, 0, 100, 1); parameter1 = CreateParameter("Период SMA2(LE)", 9, 0, 100, 1); parameter2 = CreateParameter("Период SMA3(LE)", 18, 0, 100, 1); } public int MarketPositionBySignal(string signal) { foreach (Position pos in ActivePositions) { if (pos.EntrySignal.Contains(signal)) { if (pos.PositionType == PositionType.Long) return 1; else if (pos.PositionType == PositionType.Short) return -1; } } return 0; } public Position GetPositionBySignal(string signal) { foreach (Position pos in ActivePositions) { if (pos.EntrySignal.Contains(signal)) { return pos; } } return null; } public override void Execute() { // Вывод индикаторов на график PlotSeries(PricePane, SMA.Series(Close, parameter0.ValueInt), Color.Blue, LineStyle.Solid, 1); PlotSeries(PricePane, SMA.Series(Close, parameter1.ValueInt), Color.Red, LineStyle.Solid, 1); PlotSeries(PricePane, SMA.Series(Close, parameter2.ValueInt), Color.Green, LineStyle.Solid, 1); // Основной цикл for (int bar = 19; bar < Symbol.Count; bar++) { // вход в позицию if (MarketPositionBySignal("SMA1") == 0) { if (Close[bar] > SMA.Value(bar, Close, parameter0.ValueInt)) BuyAtClose(bar, "SMA1"); } else if (MarketPositionBySignal("SMA1") == 1) { // Выход из длинной позиции if (Close[bar] < SMA.Value(bar, Close, parameter0.ValueInt)) SellAtClose(bar, GetPositionBySignal("SMA1"), "SMA1"); } // вход в позицию if (MarketPositionBySignal("SMA2") == 0) { if (Close[bar] > SMA.Value(bar, Close, parameter1.ValueInt)) BuyAtClose(bar, "SMA2"); } else if (MarketPositionBySignal("SMA2") == 1) { Position p = GetPositionBySignal("SMA2"); // Выход из длинной позиции if (p.NetProfitAsOfBarPercent(bar) < -1.1) { SellAtClose(bar, p, "SMA2 — SL"); } else if (p.NetProfitAsOfBarPercent(bar) > 3.2) { SellAtClose(bar, p, "SMA2 — TP"); } } // вход в позицию if (MarketPositionBySignal("SMA3") == 0) { if (Close[bar] > SMA.Value(bar, Close, parameter2.ValueInt)) BuyAtClose(bar, "SMA3"); } else if (MarketPositionBySignal("SMA3") == 1) { // Выход из длинной позиции if (Close[bar] < SMA.Value(bar, Close, parameter2.ValueInt)) SellAtClose(bar, GetPositionBySignal("SMA3"), "SMA3"); } } } } }
Результат