
Tradematic Support Center
Guides, articles, videos and links for Tradematic users and developers.
Пример использования новой функции Tradematic Trader — «мультипозиции» («пирамидинг»)
146342СТАТЬЯ РЕДАКТОР КОДА МУЛЬТИПОЗИЦИИ ПИРАМИДИНГ НАРАЩИВАНИЕ ПОЗИЦИИ 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");
}
}
}
}
}
Результат

