Функция усреднения Помогите доработать

rus008

Почетный гражданин
Доброго времени суток!
Суть заключается в следующем.
extern double LOTS = 0;
Когда LOTS стоит на 0 сделки открываются от процента депозита
double LOT()
{
if (LOTS!=0) return(LOTS);
double LOT = NormalizeDouble(AccountBalance()*RiskPercent/100/MarketInfo(Symbol(),MODE_MARGINREQUIRED),DigitsLot);
if (LOT>MAXLOT) LOT = MAXLOT;
if (LOT<MINLOT) LOT = MINLOT;
return(LOT);
}

Когда ставлю LOTS к примеру 0.01 То идет фиксированный лот
Хочу добавить в советник усреднение, но ни как не получается, при фиксированном лоте шаг усреднения идет, но не увеличивается лот при усреднении
if(Usred)
{
if(FindOrderType()==0 && (FindLastBuyPrice()-Ask)/_Point>=UStep)
{
PutOrder(0,Ask);
}

if(FindOrderType()==1 && (Bid-FindLastSellPrice())/_Point>=UStep)
{
PutOrder(1,Bid);
}
}
А при LOTS = 0 т.е Лот от процента баланса нет ни шага, ни усреднения.
Можно как то обьеденить LOT и Lot?
double Lot()
{
double lot=LOTS;
if(CountTrades()>0) lot=NormalizeDouble(LOTS*MathPow(KLot,CountTrades()),2);
if(lot>MaxLot)lot=LOTS;
return(lot);
}
Или быть может как то сделать это по другому?
Использую вот такой метод открытия ордеров
if (SendOrder(OP_SELLSTOP,LOT(),Price,0,0,TimeCurrent()+Period()*60*BarLife)) TimeOpen=iTime(NULL,TIMEFRAMES,0);
 

AlexeNP

Гуру форума
ну может так лучше будет
input double Lot=0,
KLot=1;

double CalculateLot(int order_type//Тип ордера
)
{
//---
lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);

if(lot==0)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
else
lot=lot*MathPow(KLot,CountTrades());

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
 

rus008

Почетный гражданин
ну может так лучше будет
input double Lot=0,
KLot=1;

double CalculateLot(int order_type//Тип ордера
)
{
//---
lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);

if(lot==0)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
else
lot=lot*MathPow(KLot,CountTrades());

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
Спасибо! Сейчас буду пробовать
 

rus008

Почетный гражданин
ну может так лучше будет
input double Lot=0,
KLot=1;

double CalculateLot(int order_type//Тип ордера
)
{
//---
lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);

if(lot==0)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
else
lot=lot*MathPow(KLot,CountTrades());

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
Ошибки выдает. Пробовал double lot=Lot; вместо lot=Lot; Предупреждения уходят,но ошибки остаются
 

Вложения

  • Screenshot_57.png
    Screenshot_57.png
    24 КБ · Просмотры: 12

rus008

Почетный гражданин
Ошибки выдает. Пробовал double lot=Lot; вместо lot=Lot; Предупреждения уходят,но ошибки остаются
вот в этой строке ругается
if (SendOrder(OP_BUYSTOP,lot,Price,0,0,TimeCurrent()+Period()*60*BarLife)) TimeOpen=iTime(NULL,TIMEFRAMES,0);
 

Вложения

  • Screenshot_59.png
    Screenshot_59.png
    39,7 КБ · Просмотры: 12

AlexeNP

Гуру форума
ты расчет лота в виде функции сделал?
тогда в SendOrder(OP_SELLSTOP,здесь функция расчета лота ,Price,0,0,TimeCurrent()+Period()*60*BarLife)
 

rus008

Почетный гражданин
ты расчет лота в виде функции сделал?
тогда в SendOrder(OP_SELLSTOP,здесь функция расчета лота ,Price,0,0,TimeCurrent()+Period()*60*BarLife)
Я не совсем понял,точнее не понял. Я особо не разбираюсь в написании кода.Но поробую донести свою мысль.
double Lot()
{
double lot=Lots;
if(CountTrades()>0)
{
lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
}
if(lot>MaxLot)
lot=Lots;
return(lot);
}
если укажу в коде Lot то нет ни каких ошибок и он открывает ордера по этому принцыпу
if (SendOrder(OP_SELLSTOP,Lot(),Price,0,0,TimeCurrent()+Period()*60*BarLife)) TimeOpen=iTime(NULL,TIMEFRAMES,0);
если укажу в коде LOT тоже нет ни каких ошибок и работает уже по этому принцыпу
double LOT()
{
if (Lot!=0) return(Lot);
double LOT = NormalizeDouble(AccountBalance()*RiskPercent/100/MarketInfo(Symbol(),MODE_MARGINREQUIRED),DigitsLot);
if (LOT>MAXLOT) LOT = MAXLOT;
if (LOT<MINLOT) LOT = MINLOT;
return(LOT);
}
 

rus008

Почетный гражданин
А тот вариант который вы сделали я уже по разному пытаюсь указать,ни как не хочет
так тоже пробовал
if (SendOrder(OP_SELLSTOP,CalculateLot(),
 

AlexeNP

Гуру форума
отлично... давай пробежимся сначала по твоему коду

double Lot()
{
double lot=Lots;
//начиная отсюда занимаемся фигней... какая разница что выдаст CountTrades() лот всё равно будет
lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);//вот это и оставляем хотя нормализация лота -
/*а вот это уберем
if(CountTrades()>0)
{
lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
}
*/
if(lot>MaxLot)
lot=Lots;
return(lot);
}

теперь возьмем функцию которую я тебе предлагал... в ней кроме всего прочего присутствует параметр определяющий направление сделки, тогда правильно будет примерно так

SendOrder(OP_BUYSTOP,CalculateLot(0) ,Price,0,0,TimeCurrent()+Period()*60*BarLife)

SendOrder(OP_SELLSTOP,CalculateLot(1) ,Price,0,0,TimeCurrent()+Period()*60*BarLife)
 

rus008

Почетный гражданин
отлично... давай пробежимся сначала по твоему коду

double Lot()
{
double lot=Lots;
//начиная отсюда занимаемся фигней... какая разница что выдаст CountTrades() лот всё равно будет
lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);//вот это и оставляем хотя нормализация лота -
/*а вот это уберем
if(CountTrades()>0)
{
lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
}
*/
if(lot>MaxLot)
lot=Lots;
return(lot);
}

теперь возьмем функцию которую я тебе предлагал... в ней кроме всего прочего присутствует параметр определяющий направление сделки, тогда правильно будет примерно так

SendOrder(OP_BUYSTOP,CalculateLot(0) ,Price,0,0,TimeCurrent()+Period()*60*BarLife)

SendOrder(OP_SELLSTOP,CalculateLot(1) ,Price,0,0,TimeCurrent()+Period()*60*BarLife)
Все получилось теперь при Lot 0 открывается лот от процента депозита
А при Lot к примеру 0,1 Открывается фиксированный,
Но при фиксированном лоте шаг усреднения работает,но нет увеличения лота.
А при лоте от процента депозита, нет шага усреднения и соответственно я не могу узнать увеличивается ли там лот.
 

rus008

Почетный гражданин
1 скрин фикс лот
2 скрин лот процент от депо
 

Вложения

  • Screenshot_60.png
    Screenshot_60.png
    18 КБ · Просмотры: 24
  • Screenshot_61.png
    Screenshot_61.png
    20,9 КБ · Просмотры: 24

rus008

Почетный гражданин
if(Usred)
{
if(FindOrderType()==0 && (FindLastBuyPrice()-Ask)/_Point>=UStep)
{
PutOrder(0,Ask);
}

if(FindOrderType()==1 && (Bid-FindLastSellPrice())/_Point>=UStep)
{
PutOrder(1,Bid);
}
}
 

AlexeNP

Гуру форума
Все получилось теперь при Lot 0 открывается лот от процента депозита
А при Lot к примеру 0,1 Открывается фиксированный,
Но при фиксированном лоте шаг усреднения работает,но нет увеличения лота.
А при лоте от процента депозита, нет шага усреднения и соответственно я не могу узнать увеличивается ли там лот.
ну, на твоем месте я лучше бы явно указывал какой вариант управления капиталом использовать...
дальше, смотрим на такую строку

lot=lot*MathPow(KLot,CountTrades());

тут результат зависит от KLot и CountTrades() - в виде формулы всё верно, но на практике я бы такое делать не стал)
теперь как сделал бы я)
lot=lot+CountTrades()*lot_step; - так мы получим гарантированное увеличение лота на один шаг за каждый открытый ордер
можно сделать помягче:
lot=lot+CountTrades()*lot_step/KLot;
KLot - целое число больше или равное 1
 

rus008

Почетный гражданин
ну, на твоем месте я лучше бы явно указывал какой вариант управления капиталом использовать...
дальше, смотрим на такую строку

lot=lot*MathPow(KLot,CountTrades());

тут результат зависит от KLot и CountTrades() - в виде формулы всё верно, но на практике я бы такое делать не стал)
теперь как сделал бы я)
lot=lot+CountTrades()*lot_step; - так мы получим гарантированное увеличение лота на один шаг за каждый открытый ордер
можно сделать помягче:
lot=lot+CountTrades()*lot_step/KLot;
KLot - целое число больше или равное 1
Оба варианта буду тестировать Огромное спасибо!
 

rus008

Почетный гражданин
ну, на твоем месте я лучше бы явно указывал какой вариант управления капиталом использовать...
дальше, смотрим на такую строку

lot=lot*MathPow(KLot,CountTrades());

тут результат зависит от KLot и CountTrades() - в виде формулы всё верно, но на практике я бы такое делать не стал)
теперь как сделал бы я)
lot=lot+CountTrades()*lot_step; - так мы получим гарантированное увеличение лота на один шаг за каждый открытый ордер
можно сделать помягче:
lot=lot+CountTrades()*lot_step/KLot;
KLot - целое число больше или равное 1
Уже как то неудобно становится вам надоедать.
Оба варианта посмотрел,но ни один из них не увеличивает лот
В случает процент от депозита нет шага все равно

double CalculateLot(int order_type//Тип ордера
)
{
//---
double lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);

if(lot==0)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
else
lot=lot+CountTrades()*lot_step;

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
 

Вложения

  • Screenshot_62.png
    Screenshot_62.png
    32 КБ · Просмотры: 18

AlexeNP

Гуру форума
Уже как то неудобно становится вам надоедать.
Оба варианта посмотрел,но ни один из них не увеличивает лот
В случает процент от депозита нет шага все равно

double CalculateLot(int order_type//Тип ордера
)
{
//---
double lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);

if(lot==0)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
else
lot=lot+CountTrades()*lot_step;

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
а результат работы CountTrades() ты проверял?
 

AlexeNP

Гуру форума
int CountTrades()
{
int count=0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
{
if(OrderType()<2)
count++;
}
}
}
return(count);
}
ну вроде все правильно, поэтому делаю предположение, что вся путаница в определении каким способом происходит управление капиталом... предлагаю такие изменения
входящие переменные

input double Lot=0;
input uchar MoneyManagment=0,//0 - фикс. 1 - процент 2 - усреднение
KLot=1,
RiskPercent=10;

функция расчета лота

double CalculateLot(int order_type)//Тип ордера
{
//---
double lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);


if(MoneyManagment==1)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
if(MoneyManagment==2)
lot=lot+CountTrades()*lot_step;

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
 

rus008

Почетный гражданин
ну вроде все правильно, поэтому делаю предположение, что вся путаница в определении каким способом происходит управление капиталом... предлагаю такие изменения
входящие переменные

input double Lot=0;
input uchar MoneyManagment=0,//0 - фикс. 1 - процент 2 - усреднение
KLot=1,
RiskPercent=10;

функция расчета лота

double CalculateLot(int order_type)//Тип ордера
{
//---
double lot=Lot;
double lot_min=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MIN),
lot_max=SymbolInfoDouble(NULL,SYMBOL_VOLUME_MAX),
lot_step=SymbolInfoDouble(NULL,SYMBOL_VOLUME_STEP);


if(MoneyManagment==1)
lot=AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/(100*(AccountInfoDouble(ACCOUNT_MARGIN_FREE)-AccountFreeMarginCheck(NULL,order_type,1)));
if(MoneyManagment==2)
lot=lot+CountTrades()*lot_step;

if(lot<lot_min)
lot=lot_min;
if(lot>lot_max)
lot=lot_max;
int step=(int)((lot-lot_min)/lot_step);

return(lot_min+step*lot_step);
//---
}
Вот этот вариан с выбором мне очень нравится.
при фикс лоте 0 есть шаг усреднения,но опять же нет увеличения лота
при проценте от депозита 1 появился шаг усреднения,но нет так же увеличения лота
 
Верх