Добрый день. Простая задача - зная стоплосс рассчитать размер лота, чтобы в случае неудачи потерять, например, не более 50 процентов депозита.
Для решения нужно знать стоимость пункта в валюте депозита. Казалось бы, задача тривиальная, но, как оказалось не совсем ( или я в трех соснах запутался...) Вот здесь довольно грамотно все рассказано - https://www.mql5.com/ru/articles/113 Но может быть есть проще способы -какими-нибудь стандартными средствами (пишу на MQL4) ?
Меня смущает, что при тестировании на истории (для кросс пары) я все время должен обращаться не только к информации по тестируемой паре, но и другим парам. А будет ли она доступна ?
Проверьте, должно работать
#property strict void OnTick() { Comment( sLot(5, 50) ); // 5% со стопом 50 } //=============================================================================================== //------------------------------ Расчет лота по риску и StopLoss -------------------------------+ //=============================================================================================== double sLot(double Percent=1, double Stloss=100, string symb="0") { if(symb=="0") symb=Symbol(); double TickValue =SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_VALUE), TickSize =SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_SIZE), ContractSize=SymbolInfoDouble(symb,SYMBOL_TRADE_CONTRACT_SIZE), Min_Lot =SymbolInfoDouble(symb,SYMBOL_VOLUME_MIN), Max_Lot =SymbolInfoDouble(symb,SYMBOL_VOLUME_MAX), Step =SymbolInfoDouble(symb,SYMBOL_VOLUME_STEP), Free =AccountInfoDouble(ACCOUNT_FREEMARGIN), Lots_New =0.0; int CalcMode=(int)SymbolInfoInteger(symb,SYMBOL_TRADE_CALC_MODE); if(Percent > 100) Percent = 100; if(Stloss <=0) return(0); if(Percent == 0) Lots_New = Min_Lot; else { if(CalcMode==0 || CalcMode==4) Lots_New = MathFloor((((Free*Percent/100)/Stloss)/TickValue)/Step)*Step; if(CalcMode==1||CalcMode==2||CalcMode==3) Lots_New = MathFloor(((((Free*Percent)/100)/Stloss)/((TickSize*TickValue)*ContractSize/TickValue))/Step)*Step; } if(Lots_New > Max_Lot) Lots_New = Max_Lot; if(Lots_New < Min_Lot) return(0); return(NormalizeDouble(Lots_New,LotDigit())); } //=============================================================================================== //-------------------- Кол-во знаков после точки в значении торгового лота ---------------------+ //=============================================================================================== int LotDigit(string symb="0") { if(symb=="0") symb=_Symbol; double lotStep = SymbolInfoDouble(symb, SYMBOL_VOLUME_STEP); return((int)MathCeil(MathAbs(MathLog(lotStep)/MathLog(10)))); }
Проверьте, должно работать
Спасибо, буду разбираться
Вот еще, может, пригодится. Использую для задания Sl и TP не в пунктах, а в значениях валюта_депозита/лот. Например, для EURUSD и депозите в USD значение $100/lot == 100 poits for 5-digits. Вроде как и с кроссами правильно работает
bool Price2Quote(double &diff, double price4lot, string symbol = "EURUSD") { long dig = 0; double tickSize, tickValue; if(!SymbolInfoInteger(symbol, SYMBOL_DIGITS, dig)) return(false); // операция неуспешна if(!SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE, tickSize)) return(false); if(!SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE, tickValue)) return(false); if(tickValue > 0) { diff = price4lot*tickSize / tickValue; diff = NormalizeDouble(diff, (int)dig); } else return false; return true; }
Проверьте, должно работать
Спасибо, проверил, действительно работает, правда пока до конца не понимаю почему и как -))
@Vitaly Muzichenko, у меня так же примерно. Только я мани-менеджмент, в отличие от торговых алгоритмов сам не писал ещё. Так вот тут нюанс. Зачем вообще MathLog(10) используется? И почему логарифм именно от 10 и именно натуральный? И вообще зачем делить на то, что MathLog(10) возвращает?
Надеюсь, кто-нить понимает это и пояснить.. так.. для общего кругозора. А то висит такая же реализация, но я не понимаю её целиком. А это не вариант...))
@Vitaly Muzichenko, у меня так же примерно. Только я мани-менеджмент, в отличие от торговых алгоритмов сам не писал ещё. Так вот тут нюанс. Зачем вообще MathLog(10) используется? И почему логарифм именно от 10 и именно натуральный? И вообще зачем делить на то, что MathLog(10) возвращает?
Надеюсь, кто-нить понимает это и пояснить.. так.. для общего кругозора. А то висит такая же реализация, но я не понимаю её целиком. А это не вариант...))
И все-таки я поторопился, когда сказал, что работает... Работает для пар одного порядка, eur usd и пр. А для пар, где значение исчисляется сотнями (AUDJPY например) , врет на два порядка - дает очень маленькое значение лота.Пока использую для определения стоимости пункта кустарный, но понятный способ - делю прибыль от профита предыд ордера на число пунктов .
И все-таки я поторопился, когда сказал, что работает... Работает для пар одного порядка, eur usd и пр. А для пар, где значение исчисляется сотнями (AUDJPY например) , врет на два порядка - дает очень маленькое значение лота.Пока использую для определения стоимости пункта кустарный, но понятный способ - делю прибыль от профита предыд ордера на число пунктов .
У меня сделано так для валютных пар из валют "USD EUR GBP JPY AUD CHF CAD NZD "
//+------------------------------------------------------------------+ //| Функция возвращает результат торгов по паре Pair минимальным | //| лотом на покупку без учета спреда, свопов и комиссий на интервале| //| времени [ptime, ctime] Результат в USD | //| Вызывается из GetPrices() | //| Вызываются модули: LastKnownPrice(), TickValueVariant() | //+------------------------------------------------------------------+ double ResultForPair( string Pair, datetime ctime, datetime ptime) { int variant; string SecondSymbol; double w1, w2, result, tv2; w1 = LastKnownPrice( Pair, ptime); w2 = LastKnownPrice( Pair, ctime); variant = TickValueVariant( Pair ); SecondSymbol = StringSubstr( Pair, 3, 3); switch( variant ) { case 0: // второй символ USD tv2 = 1.0; break; case 1: // второй символ прямая котировка USD tv2 = LastKnownPrice( SecondSymbol + "USD", ctime); break; case 2: // второй символ обратная котировка USD tv2 = 1.0 / LastKnownPrice( "USD" + SecondSymbol, ctime); break; default: break; } result = ( w2 - w1 ) * tv2; result *= 1000.0; return( result ); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функция возвращает вариант расчета TickValue для пары pair | //| Вызывается из ResultForPair() | //| Вызываются модули: | //+------------------------------------------------------------------+ int TickValueVariant( string pair ) { int variant; string SecondSymbol; // список мажоров для варианта расчета TickValue определен в глобальном блоке // string MajorSymbolList = "EURUSD GBPUSD AUDUSD USDJPY USDCHF USDCAD NZDUSD "; SecondSymbol = StringSubstr( pair, 3, 3 ); if ( SecondSymbol == "USD" ) variant = 0; else { if ( StringFind( MajorSymbolList, SecondSymbol + "USD") >= 0 ) variant = 1; else variant = 2; // для variant = 2 будет верно // StringFind( MajorSymbolList, "USD" + SecondSymbol ) >= 0 } return( variant ); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Функция возвращает последнее известное на момент времени cTime | //| цены для пары SymbolName | //| Вызывается из ResultForPair() | //| Вызываются модули: | //+------------------------------------------------------------------+ double LastKnownPrice( string SymbolName, datetime cTime) { int shift; shift = iBarShift( SymbolName, 0, cTime, false); if (iTime(SymbolName, 0, shift) > cTime) shift++; return( iClose(SymbolName, 0, shift) ); } //+------------------------------------------------------------------+
а что функция
SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE)
не работает
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Добрый день. Простая задача - зная стоплосс рассчитать размер лота, чтобы в случае неудачи потерять, например, не более 50 процентов депозита.
Для решения нужно знать стоимость пункта в валюте депозита. Казалось бы, задача тривиальная, но, как оказалось не совсем ( или я в трех соснах запутался...) Вот здесь довольно грамотно все рассказано - https://www.mql5.com/ru/articles/113 Но может быть есть проще способы -какими-нибудь стандартными средствами (пишу на MQL4) ?
Меня смущает, что при тестировании на истории (для кросс пары) я все время должен обращаться не только к информации по тестируемой паре, но и другим парам. А будет ли она доступна ?