background

Tradematic Support Center

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

Использование разных таймфреймов в одной стратегии

140402СТАТЬЯ РЕДАКТОР КОДА ПРЕОБРАЗОВАНИЕ ТАЙМФРЕЙМ BARSCALECONVERTER RESCALE SYNCHRONIZE TICK

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

Кроме того, таким способом можно решить еще одну очень важную задачу - создать пробойную систему.
Что это такое? Трейдматик совершает сделку по закрытию бара - это значит, что как бы ни двигалась цена, сигнал будет исполняться только на закрытии бара. У этого метода есть свои плюсы и минусы, но в любом случае должна быть возможность выбора - использование разных таймфреймов позволяет ее реализовать.
В качестве основы мы в который раз возьмем нашу любимую стратегию SMA-9, чтобы было нагляднее.
Мы будем оперировать с индикатором, построенным по часовым данным, но работать на 5-минутном таймфрейме (т.е. базовый таймфрейм для стратегии мы выставляем 5 минут).

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

Для получения преобразованного в нужный таймфрейм инструмента, используется функция ReScale(Symbol, BarScale, int) класса BarScaleConverter.
Кроме того, преобразованный инструмент нужно синхронизировать с текущим, чтобы бары и их даты полностью совпадали друг с другом - для этого используется функция Synchronize(Symbol).

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

// Получаем преобразованный в другой таймфрейм инструмент
Symbol newSymbol = BarScaleConverter.ReScale(Symbol, TradeMatic.BarScale.Minute, 60);

Важно! Индикаторы нужно строить обязательно на базе преобразованного в другой таймфрейм инструмента, но до синхронизации с основным инструментом (до использования функции Synchronize(), которая расстягивает новый массив на основной таймфрейм)
Не забывайте после всех преобразований перед выводом на график выполнять синхронизацию всех данных, имеющих другой таймфрейм.

Создаем новую панель на графике и на ней отображаем индикаторы SMA, построенные уже на основе преобразованного в другой таймфрейм инструмента:

//Отрисовка
//Создаем новую панель на графике
ChartPane anotherPane = CreatePane(50, false);
//Важно помнить, что индикатор нужно строить до функции Synchronize, на нерастянутых данных 
//и только потом, полученный индикатор синхронизировать с основным таймфреймом
PlotSeries(anotherPane, Synchronize(newSymbol.Close), Color.Green, LineStyle.Solid, 1);
PlotSeries(anotherPane, Synchronize(SMA.Series(newCloseMoved, parameter0.ValueInt)), Color.Red, LineStyle.Solid, 1);

Кроме того, уже в условиях на покупку и продажу нужно поменять все ссылки на текущий инструмент (Close, Open, High, и т.п.) на преобразованный инструмент. Можно сделать так: newSymbol.Close, newSymbol.Open, newSymbol.High. Но в таком случае нужно учитывать, что последняя свеча - несформирована. Т.е. фактически такая торговля будет, как торговля внутри бара. Алгоритм стратегии нужно прорабатывать так, чтобы использование несформировнной цены не изменяло указанную цену сигнала и тем более не рассасывала сам сигнал, при каждом следующем исполнении

    Есть два варианта:
  1. использовать текущие несформированные цены нового таймфрейма, но только High или Low для пробития или цену Open, которая уже зафиксирована.
  2. использовать цену предыдущего бара. В этом случае нужно сдвинать массив DataSeries перед использование функции Synchronize()

//Сдвиг на 1 бар вправо для того, чтобы далее читать сформированные бары
DataSeries newCloseMoved=newSymbol.Close>>1;
DataSeries newHighMoved=newSymbol.High>>1;
DataSeries newLowMoved=newSymbol.Low>>1;
//Синхронизация с основным таймфреймом или "растягивание" на основной
DataSeries newCloseSynchronized = Synchronize(newCloseMoved);
DataSeries newHighSynchronized = Synchronize(newHighMoved);
DataSeries newLowSynchronized = Synchronize(newLowMoved);
//Синхронизация обьекта типа Symbol
Symbol newSymbolSynchronized = Synchronize(newSymbol);

Итоговый код стратегии получается таким:

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;

		public MyScript()
		{
			parameter0 = CreateParameter("Период SMA", 9, 0, 100, 1);
		}

		public override void Execute()
		{
			// Получаем преобразованный в другой таймфрейм инструмент 
			Symbol newSymbol = BarScaleConverter.ReScale(Symbol, TradeMatic.BarScale.Minute, 60);

			//Сдвиг на 1 бар вправо для того, чтобы далее читать сформированные бары
			DataSeries newCloseMoved=newSymbol.Close>>1;
			DataSeries newHighMoved=newSymbol.Close>>1;
			DataSeries newLowMoved=newSymbol.Close>>1;
			//Синхронизация с основным таймфреймом или "растягивание" на основной
			DataSeries newCloseSynchronized = Synchronize(newCloseMoved);
			DataSeries newHighSynchronized = Synchronize(newHighMoved);
			DataSeries newLowSynchronized = Synchronize(newLowMoved);
			//Синхронизация обьекта типа Symbol
			Symbol newSymbolSynchronized = Synchronize(newSymbol);

         
			//Отрисовка
			//Создаем новую панель на графике
			ChartPane anotherPane = CreatePane(50, false);
			//Важно помнить, что индикатор нужно строить до функции Synchronize, на нерастянутых данных 
			//и только потом, полученный индикатор синхронизировать с основным таймфреймом
			PlotSeries(anotherPane, Synchronize(newCloseMoved), Color.Green, LineStyle.Solid, 1);
			PlotSeries(anotherPane, Synchronize(SMA.Series(newCloseMoved, parameter0.ValueInt)), Color.Red, LineStyle.Solid, 1);


			//SMA сдвигаем на 1 бар вперед
			DataSeries sma = Synchronize(SMA.Series(newCloseMoved, parameter0.ValueInt));
         
			// Основной цикл
			for (int bar = parameter0.ValueInt; bar < newSymbol.Count; bar++)
			{
				if (IsLastPositionActive)
				{
					//Проверяем пересечение на новом таймфрейме сверху вних цены Low с SMA
					if (CrossUnder(bar, newLowSynchronized, sma))
					{
						//В качестве цены сигнала берем цену пробоя - 1 пункт
						SellAtPrice(bar, sma[bar]-Symbol.SymbolInfo.Tick, LastPosition, "");
					}
				}
				else
				{
					//Проверяем пересечение на новом таймфрейме снизу вверх цены High с SMA
					if (CrossOver(bar, newHighSynchronized, sma))
					{
						//В качестве цены сигнала берем цену пробоя + 1 пункт
						BuyAtPrice(bar, sma[bar]+Symbol.SymbolInfo.Tick, "");
					}
				}
			}
		}
	}
}

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

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