Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Уважаемые знатоки.
Я не программист, но мне удалось разобраться в MQL-4 и создать работающего советника.
Судя по тому, что я вижу в сети и на форумах, проблема манименеджемента рано или поздно начинает волновать всех (лучше рано, чем поздно :)). Однако, ответа на мой вопрос я найти не смог, поэтому решил спросить у форумчан.
В первых версиях моего советника размер рабочего лота вычислялся примитивным делением депозита на некое число. Со временем (после появления сбоев и ошибок, связанных с нехваткой средств) этот расчет усложнялся и на сегодня я постарался учесть такие показатели, как реальный капитал, с которым можно работать, максимально возможную просадку, цену пункта, максимальную необходимую маржу.
По алгоритму максимальное количество открытых позиций = 2. Позиции противоположно направлены. Стандартный рабочий лот одинаковый. В случае убытка по стоп приказу, лот умножается на некий коэффициент k, задаваемый пользователем при запуске советника.
В алгоритме предусмотрены два варианта умножения лота на коэффициент при срабатывании стопа:
1. только в одном направлении
2. в обоих направлениях
Стало быть требуется рассчитать размер рабочего лота так, чтобы при наихудшем варианте (умножении рабочего лота на коэффициент в обоих направлениях) депозит выдержал требуемую маржу и максимально возможную просадку.
Сейчас код функции выглядит так:
void MyDEP_count()
{
RefreshRates();
int level=AccountStopoutLevel();//уровень стоп аут%
double Margin=AccountFreeMargin();//свободные средства
double Stop_Rest;//остаток после стоп аута
double Free_Capital;//свободный капитал
double Point_Price;//цена пункта
double Lot_Size=MarketInfo(Symbol(), MODE_LOTSIZE);//стандартный лот
double one_point = 0.0001;//пункт
double max_lot;//максимальный лот
double margin_r = MarketInfo (Symbol(),MODE_MARGINREQUIRED); //маржа на 1 лот
double drowdown_max;//максимальная просадка
double margin_max;//максимальная маржа
double max_lot_red;//скорректированный максимальный лот
int lot_reduction;//процент снижения просадки для расчета скорректированного максимального лота
int stop = SL;//стоп лосс в пунктах
if (Digits==5)
{
one_point = 0.00001;//коррекция пункта при 5 значном терминале
stop=stop/10;//коррекция стоп лосса при 5 значном терминале
}
if(AccountStopoutMode()==0)
{
Alert("Stop Out = ", level, "%"); //расчет капитала (свободная маржа минус стоп аут)
Stop_Rest=level*Margin/100;
Free_Capital= NormalizeDouble (Margin-Stop_Rest,2);
}
if(AccountStopoutMode()==1)
{
Alert("Stop Out = ", level, "USD");//расчет капитала (свободная маржа минус стоп аут)
Free_Capital= NormalizeDouble (Margin-level,2);
}
max_lot = NormalizeDouble (Free_Capital*0.95/stop/Lot_Size*10000/2,LotStep);
Point_Price = NormalizeDouble (max_lot*Lot_Size/10000,2);
drowdown_max = NormalizeDouble (Point_Price*stop*1.2,2);
margin_max = NormalizeDouble (max_lot*margin_r,2);
Alert("max лот = ",max_lot);
Alert("свободная маржа = ", Margin);
Alert("максимальная маржа с max лотом = ", margin_max);
Alert("максимальная просадка с max лотом = ", drowdown_max);
Alert("необходимый капитал с max лотом = ", drowdown_max + margin_max);
Alert("свободный капитал = ", Free_Capital, "USD");
if (drowdown_max + margin_max > Free_Capital)
{
lot_reduction = Free_Capital*100/(drowdown_max + margin_max);
drowdown_max = NormalizeDouble (drowdown_max/100*lot_reduction,2);
max_lot_red=NormalizeDouble (drowdown_max/stop/Lot_Size*10000/2,LotStep);
Lot1 = NormalizeDouble (max_lot_red/k,LotStep);// рабочий лот
}
else
Lot1 = NormalizeDouble (max_lot/k,LotStep);// рабочий лот
margin_max= NormalizeDouble (Lot1*k*margin_r,2);
drowdown_max= NormalizeDouble (Lot1*1.2*k*Lot_Size/10000*stop,2);
Alert("средства на 1 лот = ",margin_r);
Alert("максимальный лот скорректированный = ", max_lot_red);
Alert("НЗ = ", Stop_Rest, "USD");
Alert("цена пункта = ", Point_Price, "USD");
Alert("рабочий лот = ", Lot1);
Alert("максимальная маржа с рабочим лотом = ", margin_max);
Alert("максимальная просадка с рабочим лотом = ", drowdown_max);
Alert("необходимый капитал с рабочим лотом = ", drowdown_max + margin_max);
Alert("свободный капитал = ", Free_Capital, "USD");
return;
}
Алерты писались для проверки результатов расчета в ручную. У меня остается ощущение чрезмерной громоздкости и корявости расчета. Из-за того, что я уже
несколько месяцев занимаюсь этим вопросом, у меня в голове образовалась такая каша, что я уже не в состоянии увидеть что либо стоящее, способное упростить расчет и сделать его более универсальным.
Кстати, в данном варианте функция верно работает только в случае открытия позиций по валютным парам с валютой котировки USD. Теоретически я понимаю, что для расчета лота на других инструментах нужно вводить значение котировки текущего инструмента к доллару, но никак не могу понять, как это значение от терминала получить в корректной форме.
Я понимаю, что в моем расчете есть "дыры" и "косяки", но именно потому, что я не смог их обнаружить и исправить самостоятельно, или найти что-либо подходящее в библиотеке кодов, я и решил обратиться к вам, как к опытным практикам.
Помогите, пожалуйста исправить "косяки" или подкиньте полезные ссылки.
Заранее благодарен за помощь.