Vasiliy Sokolov: Ответ засчитан. Но проблема точности сохраняется.
Так это и есть точно. Количество пунктов - средневзвешенное по объему количество пунктов каждой из сделок. Т.е. оно совсем не должно быть равно целому числу.
fxsaber: Так это и есть точно. Количество пунктов - средневзвешенное по объему количество пунктов каждой из сделок. Т.е. оно совсем не должно быть равно целому числу.
Да, действительно если взвешивать по объему, тогда все верно. Все от задачи зависит, может о_О вполне и подойдет предложенный Вами вариант.
Я дал не полный ответ. Надеюсь дальше мало кто не разберётся.
Вы видимо невкурили вопрос топикстартера. Наивный финский юноша, поверьте, мистер o_O очень хорошо знает что такое DEAL_ENTRY_IN и DEAL_ENTRY_OUT:))
з.ы. Но за старания спасибо:))
Почему?
Посмотрите SlipPage. Он находит эти числа для каждой из позиций и умножает их на соответствующий TickValue.
sinput ulong dealticket = 0; // Тикет любой сделки интересуемой позиции
double CalcHistorySlip( const string Symb/*, PLUSMINUS &TotalProfit, PLUSMINUS &TotalSlip, double &TickValue, const int OrderType = ORDER_TYPE_ANY */)
{
double TotalSlip = 0; // Add
double TurnOver = 0;
// const bool AllTypes = (OrderType == ORDER_TYPE_ANY);
double TotalVolume = 0;
double TotalDealPrice = 0;
const int DealsTotal = ::HistoryDealsTotal();
for (int i = 0; i < DealsTotal; i++)
{
const ulong DealTicket = ::HistoryDealGetTicket(i);
const ENUM_DEAL_TYPE DealType = (ENUM_DEAL_TYPE)::HistoryDealGetInteger(DealTicket, DEAL_TYPE);
if (((DealType == DEAL_TYPE_BUY) || (DealType == DEAL_TYPE_SELL))/* && ::HistoryDealGetString(DealTicket, DEAL_SYMBOL) == Symb*/)
{
const double DealVolume = (DealType == DEAL_TYPE_BUY) ?
::HistoryDealGetDouble(DealTicket, DEAL_VOLUME) : -::HistoryDealGetDouble(DealTicket, DEAL_VOLUME);
const double DealPrice = ::HistoryDealGetDouble(DealTicket, DEAL_PRICE);
if (TotalVolume * DealVolume >= 0)
TotalDealPrice = (TotalDealPrice * TotalVolume + DealPrice * DealVolume) / (TotalVolume + DealVolume);
else
{
const bool InOutFlag = (::MathAbs(DealVolume) - ::MathAbs(TotalVolume) > 0.005);
/*
const double DealProfit = ::HistoryDealGetDouble(DealTicket, DEAL_PROFIT);
if ((DealProfit != 0) && (DealPrice != TotalDealPrice))
TickValue = DealProfit / (((InOutFlag) ? -TotalVolume : DealVolume) * (TotalDealPrice - DealPrice));
*/
if (InOutFlag)
TotalDealPrice = DealPrice;
}
TotalVolume = ::NormalizeDouble(TotalVolume + DealVolume, 2);
// const ulong OrderTicket = ::HistoryDealGetInteger(DealTicket, DEAL_ORDER);
// if (AllTypes || (GetOrderType(OrderTicket) == OrderType))
{
// TotalSlip += DealVolume * (::HistoryOrderGetDouble(OrderTicket, ORDER_PRICE_OPEN) - DealPrice);
TotalSlip += DealVolume * (TotalDealPrice - DealPrice); // Add
TurnOver += (DealType == DEAL_TYPE_BUY) ? DealVolume : -DealVolume;
}
/*
if (TickValue != 0)
{
TotalProfit += TotalSlip * TickValue;
TotalSlip = 0;
}*/
}
}
// return(TurnOver);
return((TurnOver == 0) ? 0 : 2 * TotalSlip / (TurnOver * ::SymbolInfoDouble(Symb, SYMBOL_POINT))); // Add
}
void OnStart()
{
if (::HistorySelect(0, ::TimeCurrent()) && ::HistorySelectByPosition(::HistoryDealGetInteger(dealticket, DEAL_POSITION_ID)))
Alert(CalcHistorySlip(::HistoryDealGetString(dealticket, DEAL_SYMBOL)));
}
Вы видимо невкурили вопрос топикстартера. Наивный финский юноша, поверьте, мистер o_O очень хорошо знает что такое DEAL_ENTRY_IN и DEAL_ENTRY_OUT:))
з.ы. Но за старания спасибо:))
if (TotalVolume * DealVolume >= 0)
TotalDealPrice = (TotalDealPrice * TotalVolume + DealPrice * DealVolume) / (TotalVolume + DealVolume);
Не поленись пожалуйста разжевать...
Ответ засчитан. Но проблема точности сохраняется.
Так это и есть точно. Количество пунктов - средневзвешенное по объему количество пунктов каждой из сделок. Т.е. оно совсем не должно быть равно целому числу.
Написал заявку в СД.
Решение этой задачи скоро будет упрощено.
Отпишусь позже о подробностях