Сообщество Экспертописателей - страница 4

 
Проверьте, пожалуйста, не в этом ли ошибка с попытками повторных установок стопа по той же цене?

3 человека смотрело =) пришёл Ренат и просто показал пальцем на ошибку =)))
сейчас проверю, конечно, но скорей всего дело именно в этом... я не нормализовал "bid - TrailingStop * point", а в модификации ордера участвует именно эта конструкция...
невнимательно мы как-то, господа ;)


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

Bid/Ask однозначно имеют стандартную точность символа. Другое дело, что вместо 1.6666 можно увидеть 1.6665999 (из-за особенностей погрешности в работе с числами с плавающей запятой).

Хочу отметить: проблемы сравнений таких чисел (тип double) есть _во всех_ языках и является следствием принципиальной ограниченной точности данного типа арифметики. Соответственно, не нужно никого обвинять, а знать о проблеме и писать защищенный код.
 
Даже я писал , что bid может иметь 5 знаков после запятой. Я сначала думал, что такое невозможно

Bid/Ask однозначно имеют стандартную точность символа. Другое дело, что вместо 1.6666 можно увидеть 1.6665999 (из-за особенностей погрешности в работе с числами с плавающей запятой).

Хочу отметить: проблемы сравнений таких чисел (тип double) есть _во всех_ языках и является следствием принципиальной ограниченной точности данного типа арифметики. Соответственно, не нужно никого обвинять, а знать о проблеме и писать защищенный код.


Так я и не обвиняю. Я же не зря спрашивал у komposter'а - на какой валюте у него неправильно работал трейлинг. Точно помню, что в МТ3 на Йене можно увидеть 3 знака после запятой. По крайней мере, я видел, и не раз.
 
3 человека смотрело =) пришёл Ренат и просто показал пальцем на ошибку =)))
сейчас проверю, конечно, но скорей всего дело именно в этом... я не нормализовал "bid - TrailingStop * point", а в модификации ордера участвует именно эта конструкция...
невнимательно мы как-то, господа ;)

не помогла нормализация =(
а точнее - ошибки по трейлингу (евро - позиция бай):
03:41
12:07
12:11
14:31
14:33
14:36
14:39
14:44
14:46
14:47
14:48
(время серверное)
 
Извиняюсь, имел в виду стандартную NormalizeDouble.

Ренат, и всё таки как поступать?
На данный момент варианта 3:
1. if ( orderstoploss < ( bid - TrailingStop * point )) ) заменить на if ( TrailingStop < ( bid -orderstoploss) / point )
2. сравнивать не double, а int с помощью ф-ций Begun-а
3. уредить предвижение стопа ( не каждый пункт, а через n спредов )
ну, и их комбинации, естесственно.

Поскольку софт достаточно ответственный, хотелось бы получить (!не гарантии!) рекомендации по написанию...
 

не помогла нормализация =(


Попробуй вместо:
if (orderstoploss < ( bid - TrailingStop * point ))


написать:

double newSL = NormalizeDouble(bid - TrailingStop * Point);
if (orderstoploss + Point < newSL)
   orderstoploss  = newSL;//OrderModify(... newSL...)



Тоже ошибки будут?

 
ну, если " + Point" не знаю... а вообще у меня сейчас так же...
понятно, что можно люфт сделать, но это же не серьёзно.... а если придётся люфт 10-20 пипсов делать, "для надёжности", да на М30, сказка просто =)
 
Ренат, и всё таки как поступать?

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


Если чесно, не знаю как уростить...
Но проверить, конечно, можно. Вот код в том виде, в котором он сейчас используется (по частям):

проверяем входящие параметры и выделяем нужный ордер. При ошибке просто выходим, т.е. ордер модифицирован не будет...
int _TrailingStop ( int _OrderTicket, int TrailingStop, color _Color = CLR_NONE )
{
//	Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - loaded..." );
	if ( TrailingStop <= 0 )
	{
//		Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(0);" );
		return(0);
	}
	
	if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false )
	{
//		Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-2);" );
		return(-2);
	}



Сохраняем все данные ордера в переменные и нормализуем их:

	string _Symbol = OrderSymbol();
	int _OrderType = OrderType();
	double point = MarketInfo ( _Symbol, MODE_POINT );
	int digits = MarketInfo( _Symbol, MODE_DIGITS );
	double bid = NormalizeDouble( MarketInfo ( _Symbol, MODE_BID ), digits );
	double ask = NormalizeDouble( MarketInfo ( _Symbol, MODE_ASK ), digits );
	double orderopenprice = NormalizeDouble ( OrderOpenPrice(), digits );
	double orderstoploss = NormalizeDouble ( OrderStopLoss(), digits );
	double ordertakeprofit = NormalizeDouble ( OrderTakeProfit(), digits );
	datetime orderexpiration = OrderExpiration();
	double NewStopLoss;




это цвет и "красивость" лога...

	string _OrderType_str = _OrderType_str ( _OrderType );
	if ( _Color <= 0 )
	{
		_Color = ordersellcolor;
		if ( _OrderType == OP_BUY || _OrderType == OP_BUYLIMIT || _OrderType == OP_BUYSTOP )
		{ _Color = orderbuycolor; }
	}



теперь, для длинной позиции определяем новый уровень СЛ, нормализуем, сравниваем со старым (только в том случае, если позиция прибыльная)

	if ( _OrderType == OP_BUY )
	{
		NewStopLoss = NormalizeDouble( bid - TrailingStop * point, digits );
		if ( ( bid - orderopenprice ) > 0 )
  		{
			if ( orderstoploss <= 0 || orderstoploss < NewStopLoss )//TrailingStop < ( bid - orderstoploss ) / point )
			{


выводим инфу в лог

				_info1 ( "Trailing Stop (" + TrailingStop + " points) для позиции № " + _OrderTicket + ", " + _OrderType_str + "..." );
				_info2 ( "New Stop Loss = " + DoubleToStr( NewStopLoss, digits ) );
				_info3 ( "" );
				_info4 ( "" );



тройная попытка модификации ордера с соблюдением 10-сек паузы (каждый раз ордер выделяется)

				for ( int x = 0; x < 3; x ++ )
				{
					while ( LocalTime() - GlobalVariableGet ( "LastTradeTime" ) < 10 )
					{ Sleep(1000); }

					if ( OrderSelect( _OrderTicket, SELECT_BY_TICKET ) == false )
					{
//						Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-2);" );
						return(-2);
					}

					int ordermodify = OrderModify( _OrderTicket, orderopenprice, NewStopLoss, ordertakeprofit, orderexpiration, _Color );


и только если ordermodify <= 0 отправляется почта с кодом ошибки

					if ( ordermodify > 0 )
					{
						_info3 ( "Успешно..." );
						GlobalVariableSet ( "LastTradeTime", LocalTime() );
//						Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(1);" );
						return(1);
					}
					int error_code = GetLastError();
					_info1 ( "Ошибка Trailing Stop!!!", 1 );
					Processing_Error ( error_code );
					Sleep(10000);
				}


если после 3-х попыток ордер так и не модифицирован, выходим(-1)

//				Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(-1);" );
				return(-1);
			}
  		}
  	}


далее - тоже для селл позиций

 	if ( _OrderType == OP_SELL )
	{
	}


и, наконец, если необходимости двигать стоп нет, выходим(0)

//Print( "_TrailingStop ( ", _OrderTicket, ", ", TrailingStop, " ) - return(0);" );
return(0);
}





незнаю....

 

понятно, что можно люфт сделать, но это же не серьёзно.... а если придётся люфт 10-20 пипсов делать, "для надёжности", да на М30, сказка просто =)


При чем здесь? "+Point" решает проблему с округлением последнего значимого знака цены. Не о 2, 3, а тем более 10-20 пунктах речи не идет.
Причина обращения: