Сценарии.
- Представим, что вас заинтересовал советник из Маркета или какой-то Сигнал. Вы можете результаты их торговли вывести на чарт и посмотреть, где и как открывались позиции. Чтобы проанализировать для оценки надежности и торговой идеи.
- Автор советника хочет проанализировать свои же бэктесты и посмотреть интересующие позиции на чарте.
- Подписчик на сигнал хочет проанализировать историю торговли без прямого доступа к ней.
- Трейдер/инвестор хочет проанализировать торговлю на своем счете.
Анализ позиций на чарте.
MT5 предоставляет такие возможности, но при анализе большого количества позиций штатный инструментарий крайне скуден. Поэтому ниже предложен код, который реализует быструю навигацию по нанесенным на чарт позициям любой природы: Account/Tester/Signal.
ChartPositions.
Ниже небольшой исходник для наглядности, он же и его скомпилированная версия прикреплены внизу.
#include <fxsaber\Keyboard\Keyboard.mqh> // https://www.mql5.com/ru/code/48393 input ENUM_KEYCODE inKeyPrevPosition = KEYCODE_OPEN_BRACKET; // Previous Position input ENUM_KEYCODE inKeyNextPosition = KEYCODE_CLOSE_BRACKET; // Next Position input double inOffset = 0.5; // Position show #include <fxsaber\ObjectsTrade\ObjectsTrade.mqh> // https://www.mql5.com/ru/code/39750 #include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577 string StrComment = ChartGetString(0, CHART_COMMENT) + "\nKeys (" + KEYBOARD::Language() + "):\n'" + KEYBOARD::Input(inKeyPrevPosition) + "' - Previous Position.\n'" + KEYBOARD::Input(inKeyNextPosition) + "' - Next Position.\n\n"; int OnInit() { if (VIRTUAL::SelectByHandle(VIRTUAL::Create(0.0))) { const OBJECTSTRADE ObjectsTrade(0); ORDER_BASE Orders[]; StrComment += ObjectsTrade.ToString() + " (Positions = " + (string)ObjectsTrade.Get(Orders) + "):\n"; VIRTUAL::AddOrder(Orders); } Comment(StrComment); return(!OrdersHistoryTotal()); } void OnDeinit( const int ) { Comment(""); } int SelectPosition( const bool Direct ) { static int Pos = OrdersHistoryTotal(); return(Pos = Direct ? MathMin(Pos + 1, OrdersHistoryTotal() - 1) : MathMax(Pos - 1, 0)); } string OrderToString( const int Pos, const bool Flag = false ) { return(OrderSelect(Pos, SELECT_BY_POS, MODE_HISTORY) ? "\n" + IntegerToString(Pos, 3, '0') + ": " + (Flag ? "***" : NULL) + VIRTUAL::GetOrder().ToString(0) : NULL); } string ToString( const int Pos, const int Offset = 2 ) { string Str = StrComment; const int To = MathMin(Pos + Offset, OrdersHistoryTotal() - 1); for (int i = MathMax(Pos - Offset, 0); i <= To; i++) Str += OrderToString(i, i == Pos); Str += "\n\n" + OrderToString(Pos); return(Str); } bool NavigateTo( const datetime time, const double Offset = 0.5 ) { return(ChartNavigate(0, CHART_END, (int)(ChartGetInteger(0, CHART_WIDTH_IN_BARS) * (1 - Offset - (ChartGetInteger(0, CHART_SHIFT) ? ChartGetDouble(0, CHART_SHIFT_SIZE) / 100 : 0))) - iBarShift(_Symbol, _Period, time))); } void OnChartEvent( const int id, const long &lparam, const double&, const string& ) { if ((id == CHARTEVENT_KEYDOWN) && ((lparam == inKeyPrevPosition) || (lparam == inKeyNextPosition))) { Comment(ToString(SelectPosition(lparam == inKeyNextPosition))); NavigateTo((OrderOpenTime() + OrderCloseTime()) / 2, inOffset); } }
Как пользоваться.
Как бесплатно вывести торговлю любого советника из Маркета на истории или его Сигнал - писалось. Будем считать, что это делается с легкостью.
В общем, имеются открытые чарты с нанесенными на них позициями нужной истории торговли.
Запускаем приведенный код на соответствующем чарте и переключаемся между его позициями горячими клавишами. Искать позиции (скроллить и всматриваться) больше не надо.
На скриншоте показана навигация по истории одного из Сигналов.
Нужно попробовать, чтобы понять удобство предложенной реализации.
Ссылка на блог автора.