background

Tradematic Support Center

Guides, articles, videos and links for Tradematic users and developers.

Пример использования новой функции Tradematic Trader — «мультипозиции» («пирамидинг»)

131763СТАТЬЯ РЕДАКТОР КОДА МУЛЬТИПОЗИЦИИ ПИРАМИДИНГ НАРАЩИВАНИЕ ПОЗИЦИИ 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");
				}

			}
		}
	}
}

Результат


This website uses cookies. By continuing to use this website, you consent to our Privacy Policy. OK