MM функция расчета лота в зависимости от просадки.

 

Здравствуйте, асы МКЛ!

Ко мне поступила просьба одного инвестора по модификации функции лота, которая применяется в стандартном советнике МТ4 в MACD Sample.

Сам я не являюсь программистом, я ему показал один пример с другого форума. Но идею он дал такую, которая меня заинтересовала самого.

Суть в том что бы лот рассчитывался от того, на сколько сможет выдержать депозит пунктов просадки до стоп аута при таком лоте. Наверно многие не понимают что я пишу хотя я и сам не могу понять как это реализовать. В общем задаем во внешних переменных просадку 50 пунктов, - это будет уровень после которого сработает стопаут при таком лоте, если изменится плечо у брокера нужно что бы это учитывалось это тоже.

В общем надеюсь поняли что имеется в виду.

double LotsOptimized() {
double lot = Lots;
double minlot = MarketInfo(Symbol(), MODE_MINLOT);
double maxlot = MarketInfo(Symbol(), MODE_MAXLOT);
if (MM){
int orders = OrdersHistoryTotal();
int losses = 0;
lot = NormalizeDouble(AccountFreeMargin() * MaximumRisk / balans, 2);
if (DecreaseFactor > 0.0) {
for (int i = orders - 1; i >= 0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == FALSE) {
Print("Error in history!");
break;}
if (OrderSymbol() != Symbol() || OrderType() > OP_SELL) continue;
if (OrderProfit() > 0.0) break;
if (OrderProfit() < 0.0) losses++;}
if (losses > 1) lot = NormalizeDouble(lot - lot * losses / DecreaseFactor, 2);}}
if(lot < minlot) lot = minlot;
if(lot > maxlot) lot = maxlot;
return (lot);}
 

я бы назвал это "расширенным расчетом лота"

//№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
// П Р О Ц Е Д У Р А   Р А С Ч Е Т А   Л О Т А   В   З А В И С И М О С Т И   О Т   С Т Р А Т Е Г И И .
//№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№
// идея: расчет лота в зависимости от стратегии                                                                                №№№№№№№№
//№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№

// массив для получения данных по функции определения лота
#define GetLot.Equity      0
#define GetLot.IEquity     1
#define GetLot.Lot         2
#define GetLot.Zalog       3
#define GetLot.PriceStep   4
#define GetLot.PriceSpred  5
#define GetLot.PipsSLSO    6
#define GetLot.PriceSLSO   7
#define GetLot.PriceItog   8
#define GetLot.Max         9

double M.GetLot[GetLot.Max];

// Sy - символ валюты расчета
// Pips.SLSO - расстояние в пуктах до Стоп-Аута - автоматического закрытия позиции
// TuneStepLot - точность рассчетов при итерации. 1-высокая точность, 2-меньше, 3-меньше точность...
// k.Equity - коэффициент использование депозита. возможно от 1.0 до 0.1 единица - полное (возможно, что его необходимо связать с вероятностью точности прогноза)
//                    Symbol()      170      1-высокая точность      0.7(70%депо)
void GetLotBy.STRG(string Sy, int Pips.SLSO, int TuneStepLot, double k.Equity)
{
// цена пункта - всегда постоянная.             лот 0.01 - 0.1 доллара за пункт ( на пункт )
// динамические величины -------------------------------------------------------------------------------------------
double Market.Balance            = AccountBalance();     // баланс счета
double Market.Equity             = AccountEquity();      // свободные средства для открытия позиций и удержания позиций
// постоянные величины --------------------------------------------------------------------------------------------------------------------
double Market.PricePipMinLot     = 0.1; // 0.1 доллара за пункт при лоте 0.01
double Market.PriceLot.1.00      = MathRound(MarketInfo(Symbol(),MODE_MARGINREQUIRED));   // необходимый залог для одного лота
double Market.MinLot             = MarketInfo(Symbol(), MODE_MINLOT);         // 0.01 минимальный лот
double Market.PriceMinLot        = Market.PriceLot.1.00 * Market.MinLot;
double Market.Spred              = MarketInfo(Symbol(), MODE_SPREAD);      // 2.00000000 - размер спреда
double Market.TickSize           = MarketInfo(Symbol(), MODE_TICKSIZE);       // шаг рынка(тикет) 0.00010000 - четырех знак   (0.00001000 - пятизнак)
double Market.LotStep            = MarketInfo(Symbol(), MODE_LOTSTEP);        // шаг лота - 0.01 
double Market.MinSLTP            = MarketInfo(Symbol(), MODE_STOPLEVEL);      // минимальный размер для установки SL или TP (лучше подстраховаться +1)
// динамические величины -------------------------------------------------------------------------------------------
double Market.FreeMargin         = AccountFreeMargin();  // свободная сумма для удержания позиций и открытия ордеров
double Market.Margin             = AccountMargin();      // общая сумма используемая в залоге при открытых позициях
double Market.Profit             = AccountProfit();      // общая сумма "прибыль-убыток" при открытых позициях

double Market.IdealMaxLot        = Market.Equity/Market.PriceLot.1.00;   // идеальный максимальный лот 
int   Market.NomberByIdealMaxLot = Market.IdealMaxLot/Market.MinLot;    // 0.74/0.01 = 74 ( 74 итерации от 1 до 74 )      
double I.Lot, I.PriceStep, I.Zalog, I.Spred, I.StopOut, I.Itog, I.Equity;

I.Equity = k.Equity*Market.Equity; // эквити с учетом коэффициента для получения процентной части 
//int TuneStepLot;                 // шаг - тонкая настройка для прохода по количеству итераций лота

// Pips.SLSO = 170;          // 30 пунктов до стоп-лосса равного стоп-ауту
// TuneStepLot = 1;     // шаг в пунктах по количеству инераций подбора
for(int i=Market.NomberByIdealMaxLot; i>1; i-=TuneStepLot) // i = 65 - к примеру
{
   I.Lot = i*Market.MinLot;                 // 65*0.01 = 0.65 - тестируемый лот (0.65- к примеру)
   I.PriceStep = I.Lot * 10;                // 0.65 * 10 = 6.5 - цена пункта шага в рынке
   I.Zalog = i*Market.PriceMinLot;          // 65 * 7.20 = 468 - залог для открытия лота
   I.Spred = I.PriceStep * Market.Spred;    // 6.5 * 2 = 13 - учет суммы спреда в ордере
   I.StopOut = Pips.SLSO * I.PriceStep;         // 30 * 6.5 = 195 - учет суммы уровня SL=SO - через столько пунктов ордер закроется в минусе. останется - залог
   I.Itog = I.Zalog + I.Spred + I.StopOut;  // итоговая сумма для сравнения с эквити 
   if (I.Equity>I.Itog) break;
}//расчитанный лот выглядит следующим образом

M.GetLot[GetLot.Equity]       = Market.Equity;
M.GetLot[GetLot.IEquity]      = I.Equity;
M.GetLot[GetLot.Lot]          = I.Lot;
M.GetLot[GetLot.Zalog]        = I.Zalog;
M.GetLot[GetLot.PriceStep]    = I.PriceStep;
M.GetLot[GetLot.PriceSpred]   = I.Spred;
M.GetLot[GetLot.PipsSLSO]     = Pips.SLSO;
M.GetLot[GetLot.PriceSLSO]    = I.StopOut;
M.GetLot[GetLot.PriceItog]    = I.Itog;
}
хотя переделывать надо эту функцию. она работает от эквити, надо от свободных средств. но если
 
DDFedor >>:

я бы назвал это "расширенным расчетом лота"...

моя функция выглядит так...

хотя переделывать надо эту функцию. она работает от эквити, надо от свободных средств. но если

Интересно, спасибо конечно но мне казалось что можно проще сделать.

типа добавить

AccountStopoutLevel()// опрделить стоп аут
AccountLeverage() // определить плечо
AccountStopoutMode() // расчет уровня стоп аута

Потом это добавить просто в расчет лота, хотя могу и ошибаться.

Причина обращения: