В нескольких топиках довелось участвовать в
сраче обсуждении того, как рассчитывать уровень без убытка…
И вроде бы не сложный вопрос, вызывает порой серьезные затруднения и буйный полет фантазии в решениях
На самом деле все очень просто. Расскажу как это делаю я
1.
Расчет уровня БУ без учета комиссий, свопов и прочего. Чистое арифметическое среднее.
Из со школы все знают формулу
или простой наглядный пример
Применение этой формулы в коде:
double lots=0;
double sum=0;
for (int i=0; i<OrdersTotal(); i++)
{
if (!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
if (OrderSymbol()!=Symbol()) continue;
if (OrderType()==OP_BUY)
{
lots=lots+OrderLots();
sum=sum+OrderLots()*OrderOpenPrice();
}
if (OrderType()==OP_SELL)
{
lots=lots-OrderLots();
sum=sum-OrderLots()*OrderOpenPrice();
}
}
double price=0;
if (lots!=0) price=sum/lots;
Рассмотрим как это работает:
Сначала посмотрим в конец примера…
Искомый уровень БУ вычисляется здесь
price=sum/lots;
А в переменных «lots» и «sum» содержатся данные по открытым ордерам, собираемые в цикле.
Причем для ордеров типа «Buy» данные ордеров берутся со знаком "+", а для «Sell» соответственно с "-".
Делается это из-за того, что ордера противоположного направления, компенсируют друг друга.
Сначала то, что касается переменной «lots»…
Прибавляя объем ордеров (OrderLots) одного типа и вычитая объемы противоположных ордеров, определим — не является ли сумма ордеров равновесной?
Ведь если объем ордеров на покупку, равен объему ордеров на продажу, то уровня без убытка просто не существует.
Теперь рассмотрим, как подсчитывается «sum»…
В ней суммируются произведения цены открытия ордера (OrderOpenPrice), на его объем (OrderLots). Т.е. цена ордера берется столько раз, сколько лотов в этом ордере.
Для примера, если взять два ордера Buy равного объема (пусть объем равен 1) с ценами открытия Pr1= 100 и Pr2=200, то сразу видно что среднее значение равно 150-ти.
А если их объемы будут равны Lot1=2, а Lot2=5? Ведь в таком случае второй ордер будет сильнее влиять на нашу прибыль/убыток.
Учтем это взяв цену первого ордера 2 раза, а цену второго соответственно 5 раз.
И для получения среднего, разделим на количество слагаемых.
(100+100+200+200+200+200+200)/2+5 = (2*100+5*200)/7 = 171,428571(428571)
Таким образом мы приходим в выражению price=sum/lots.
Для практического применения его нужно еще привести к нужному количеству знаков после запятой, но это уже другой вопрос.
2.
Расчет уровня БУ с учетом свопов и комиссий.
(далее рассматриваются случаи для наиболее распространенных (в данный момент) долларовых депозитов)
Этот вопрос намного интереснее и не так прост.
Общая идея учета комиссий и свопов, в том, что бы определить, на каком уровне полученный профит компенсирует
начисленные суммы и общий результат сделок будет равен нулю.
Так как комиссии и свопы начисляются не в пунктах, а в валюте депозита, то тут начинает играть роль стоимость одного пункта.
А она зависит от торгуемой пары.
— Так для
обратных котировок (
EUR/USD, GBP/USD и всех других где доллар стоит в знаменателе) все просто:
Цена пункта = размер пункта * объем позиции
Для 1-го стандартного лота, стоимость одного (4зн) пункта всегда равна 10$.
— Для
прямых котировок (
USD/JPY, USD/CHF и других, где USD стоит в числителе) уже сложнее… Тут имеет значение текущий курс.
Формула расчета:
Цена пункта = размер пункта * объем позиции / текущий курс
Так как мы рассчитываем цену пункта не по текущему курсу, а по будущему, то расчет уровня БУ уже становится не таким простым.
— И наиболее сложный случай —
кроссовые пары (
GBP/CHF, EUR/JPY и др.)
Формула для расчета следующая:
Цена пункта = объем позиции * размер пункта * текущая котировка базовой валюты по отношению к USD / текущий курс валютной пары (кросс-курс)
Для примера возьмем GBP/CHF, по курсу 1.4400 франка за 1 фунт, при курсе GBP/USD= 1.5800.
Тогда 1-го лота цена пункта=100000 * 0.0001 * 1.5800 (курс GBP/USD) / 1.4400 = 11 $
В этом случае расчет уровеня БУ становится совершенно не тривиальной задачей,
т.к. требуется знать котировку базовой валюты по отношению к USD на момент достижения этого уровня БУ.
И как же в таком случае быть?
Лично я пришел к выводу, что в практике расчета уровня БУ в советниках, не требуется совершенно точно вычислять уровень БУ.
Если цена находится далеко от предполагаемого уровня, то погрешность вычисления может быть достаточно большой.
Все равно, так как в процессе удержания позиции величина накопленных комиссий и свопов изменяется, то уровень БУ требуется пересчитывать.
И по мере приближения к этому уровню, уточняются значения курсов влияющих на стоимость одного пункта.
А значит и расчет уровня БУ становится точнее.
Общая идея (алгоритм) расчета уровня БУ с учетом комиссий и свопов в следующем:
1. Сначала определяем уровень БУ методом арифметического среднего (см. выше)
2. Далее корректируем найденное значение, для компенсации накопленных начислений.
В этом нам поможет метод
MarketInfo(Symbol(), MODE_TICKVALUE), возвращающий размер минимального изменения
цены инструмента в валюте депозита на один стандартный лот.
А вот так это воплощается в коде:
double _lost=0 ;
double _sum=0 ;
double _sumsvop=0;
double ZeroLevelAll=0;
double tickvalue = MarketInfo(Symbol(), MODE_TICKVALUE);
for(int i=0; i<OrdersTotal(); i++)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol()) continue;
if(OrderType()==OP_BUY)
{
_lost+=OrderLots();
_sum+=OrderLots()*OrderOpenPrice();
_sumsvop+=OrderSwap( )+OrderCommission( );
}
if(OrderType()==OP_SELL)
{
_lost-=OrderLots();
_sum-=OrderLots()*OrderOpenPrice();
_sumsvop+=OrderSwap( )+OrderCommission( );
}
}
if (_lost>0)
{ZeroLevelAll=_sum/_lost - (_sumsvop / (tickvalue * (_lost)) * Point); //уровень безубытка для открытых ордеров, перевес Buy
}
if (_lost<0)
{ZeroLevelAll=_sum/_lost + (_sumsvop/ (tickvalue * (_lost)) * Point); //уровень безубытка для открытых ордеров, перевес Sell
}
Программный код отличается предыдущего:
— подсчетом суммы свопов и комиссий: _sumsvop+=OrderSwap( )+OrderCommission( )
— Формулой расчета уровня БУ:
ZeroLevelAll=_sum/_lost ± (_sumsvop / (tickvalue * (_lost)) * Point), в которой
первое слагаемое
_sum/_lost — расчет арифметического среднего,
а второе
(_sumsvop/ (tickvalue * (_lost)) * Point) — коррекция зависящая
от накопленной суммы и направления несбалансированной позиции.( Переведенная в пункты изменения цены)
ПС: В приведенных примерах рассчитывается БУ для всех ордеров (Buy и Sell) по паре.
Для расчета отодельно по Buy или Sell достаточно в теле цикла закоментировать строки относящиеся к ненужным типам ордеров.
Комментарии (18)
Я использую формулу:
Это тоже или нет?
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
А вот насчет знака всегда со знаком минус?
13 Fargo Автор Сообщений: 495
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
Мне вот никак не сочинить формулу:
у нас есть несколько однонаправленных сделок, когда у них наступит stop out? Fargo, может поможешь?
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
int level=AccountStopoutLevel();
if(AccountStopoutMode()==0)
Print(«StopOut level = », level, "%");
else
Print(«StopOut level = », level, " ", AccountCurrency());
Если у нас первый случай (в процентах), тогда нужно воспользоватся AccountMargin()
и перевести проценты в деньги.
level= AccountMargin()*level/100;
Далее для текущего положения дел
if(lots > 0) LSO = Bid — ((AccountFreeMargin()+AccountMargin() -level) / (tickvalue * lots)) * Point;
if(lots < 0) LSO = Ask — ((AccountFreeMargin()+AccountMargin() -level) / (tickvalue * lots)) * Point;
Как то так
Ну это на вскидку, я не проверял Редактирован: 17 мая 2015, 19:15
13 Fargo Автор Сообщений: 495
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
Открыта sell позиция лот 0,03
AccountMargin() => 6.69 — Сумма залоговых средств, она неизменна.
Почему мы эту сумму умножаем на проценты?
Может надо?: AccountBalance()*level/100
У меня на втором счете StopOut 10%, а на третьем 20%
Т.е. это сколько средств может остаться после StopOut? Т.е. на первом счете после StopOut у меня останется 60% средств? Редактирован: 19 мая 2015, 16:16
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
Вот хорошую картинку нашел
Структура средств на депозите наглядно Редактирован: 19 мая 2015, 16:42
13 Fargo Автор Сообщений: 495
Твоя формула:
У меня: level= 6.69*60/100 = 4,014 — непонятно, что получилось
А если: AccountBalance()*level/100 => то получается, сколько останется средств после срабатывания stop-out
Так хотя бы понятно, что получилось.
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
-начальный баланс 1000$, то при SO 60%, то тебя принудительно закроют если получишь убыток в 400$, т.е. на счету останется 600$? Хорошо, идем дальше…
— открыты два ордера с залогом пусть по 100$ за каждый,
— один из ордеров ты закрываешь с прибылью в 500$
— текущий баланс 1500$. Тогда тебя закроют если ты достигнешь по оставшемуся ордеру убытка (1500-(1500*60%)) 600$ и на счету останется 900$, т.е. еще раньше
Так? Ну это, извини, фигня получается
А вот 4.014 понятная цифра, тебе принудительно начнут закрывать убыточные ордера если средства твоего депозита будут <= 4.01$. И останется у тебя на спокойном рынке 4$, если будут проскальзывания на новостях или гэп, то и того меньше. Редактирован: 20 мая 2015, 08:56
13 Fargo Автор Сообщений: 495
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
Обычная схема это примерно как здесь написано smfanton.ru/forex/marzhin-koll-i-stop-aut.html Редактирован: 19 мая 2015, 17:32
13 Fargo Автор Сообщений: 495
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
такая же, как у тебя Редактирован: 21 мая 2015, 17:33
27 Oxy Сообщений: 3430 - ..ιllιlι.lι.ιllι.ιlι..
13 Fargo Автор Сообщений: 495
Кто нибудь может обьяснить что тогда считает этот алгоритм?
Мне говорили что высчитывает среднию цену
8 Kudryashov Сообщений: 129
Часть функции для усреднителя, считает среднюю цену открытых позиций одного направления с различным лотом.
35 AM2 Сообщений: 16250 - Андрей
8 Kudryashov Сообщений: 129
Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий