Пишем функцию для оптимизации стоп-лосса

  • Автор темы Автор темы Юрий FT
  • Дата начала Дата начала

Юрий FT

Модератор
Планирую написать функцию аля - getstoploss(int param1,int param2), которая в зависимости от входящего параметра будет выдавать размер стоп лосс по запрограммированым в нее методам. Т.е будет достаточно просто вставить эту функцию в OrderSend и быстро оптимизировать стоп лосс любой торговой стратегии/советника.

Планируемые методы реализации для стоп лосса:

1. Процент от общего размера депозита.
StopLoss = Сумма счета*Процент/100;

2. Отклонение от текущей цены в %.
StopLoss = Price - (Price ∗ (( 100 — percent(%))/100));

3. Срабатывание стопа по касанию средней ценой.
Указываем размер стоплосса в пунктах, но срабатывает он только тогда когда MA(period) касается цены.

4. По ATR.
StopLoss = ATR(value);

5. По Standard Deviation
StopLoss = StdDev (value);

6. Стоп лосс по волатильности прошлого дня.
StopLoss = Максимум прошлого дня - Минимум прошлого дня.

7. Стоп лосс по половине волатильности прошлого дня.
StopLoss = (Максимум прошлого дня - Минимум прошлого дня)/2;

8. Стоп лосс по средней волатильности.
StopLoss = AVG(Максимум прошлого дня - Минимум прошлого дня, period);

9. Стоп лосс по волатильности наоборот.
StopLoss = Максимальное значение волатильности за 10 дней, если волатильность прошлого дня минимальная и наоборот;

10. Стоп лосс на поддержках/сопротивлениях.
StopLoss = Максимум/Минимум за определенное количество дней.

11. Стоп лосс по фибоначи
StopLoss = % значение фибоначи между максимумом и минимумом.


Как идея? Что скажете о перечисленных методах? Предлагайте еще методы! Задавайте вопросы если непонятен какой-то из методов.
 

supervisor

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

user55

Местный знаток
12. SL при появлении дивергенции. В качестве базовой можно взять расхождение RSI.
13. SL равный расстоянию цены до границы канала Боллинджера.
 

AmeR

Активный участник
Вскрывая код MQL4 через десу, выяснил, как можно закрывать часть позиции от открытой, что в принципе невозможно.
Т.е. открыли сделку в лот, а закрыть можно хоть сколько раз по кусочку, до окончания рамера лота. Допустим один лот можно закрыть по 0.1 десять раз в разное время и по разной цене, конечно последовательно. При этом оставшиеся позиции будут открыты по начальной цене, у них можно менять SL, TP и иметь всю прибыль от начальной цены.
Дробить можно до максимума.
 

cmillion

Гуру форума
Трейлинг стоп по фракталам и экстремумам свечей

Трейлинг может осуществляться по фракталам, по экстремумам прошлых баров или по указанному количеству пунктов. Может запускаться как отдельный советник или скрипт, совместно с любым советником.
Описание:

В зависимости от переменной TrailingStop, трейлинг может осуществляться по фракталам, по экстремумам прошлых баров или по указанному кол-ву пунктов.
Если TrailingStop больше 0, то трейлинг будет осуществлен с тем кол-вом пунктов, которое указано в переменной TrailingStop. Если TrailingStop меньше ограничения минимального уровня стопов, то трейлинг будет с минимальными стопами.
Если TrailingStop = 0 и Tip.Fr.or.Candl=0, то трейлинг будет по фракталам. Т.е. для уровня стоплосс выбирается первый соответствующий фрактал.
Если TrailingStop = 0 и Tip.Fr.or.Candl=1, то трейлинг будет по минимумам/максимумам прошлых свечей.
Если Magic = 0, то трейлинг проводится по всем ордерам текущего символа, без учета магического номера. Если в переменной Magic указан магический номер, то соответственно будет только трейлинг ордеров с номером Magic.
Если OnlyProfit = true, то модифицируются только профитные ордера
Если OnlyWithoutLoss = true, то вместо трейлинга ордера только переводятся в безубыток

Визуализация:

На экране отображается информация о текущей работе скрипта:

- установки с которыми скрипт запущен
- количество ордеров с которыми скрипт работает
- текущее время
- минимальные уровни выставления стопов (-)
- текущие возможные уровни стопов (ценовые метки)

Советы:

Скрипт заканчивает работу, когда все ордера закрыты. Если программа запущена как советник, то выход из программы только вручную.

Мои работы: :?:

Удачи!
 

Вложения

Юрий FT

Модератор
Вскрывая код MQL4 через десу, выяснил, как можно закрывать часть позиции от открытой, что в принципе невозможно.
Т.е. открыли сделку в лот, а закрыть можно хоть сколько раз по кусочку, до окончания рамера лота. Допустим один лот можно закрыть по 0.1 десять раз в разное время и по разной цене, конечно последовательно. При этом оставшиеся позиции будут открыты по начальной цене, у них можно менять SL, TP и иметь всю прибыль от начальной цены.
Дробить можно до максимума.
Почему невозможно? Можно закрыть часть позиции указав в orderclose необходимый обьем для закрытия. Или речь идет не об этом?
 

cmillion

Гуру форума
Почему невозможно? Можно закрыть часть позиции указав в orderclose необходимый обьем для закрытия. Или речь идет не об этом?

Я думаю, что речь именно об этом.
функция OrderClose(ticket, lots, price, slippage, Color)
Параметры:
ticket - Уникальный порядковый номер ордера.
lots - Количество лотов для закрытия.
price - Цена закрытия.
slippage - Значение максимального проскальзывания в пунктах.
Color - Цвет стрелки закрытия на графике. Если параметр отсутствует или его значение равно CLR_NONE, то стрелка на графике не отображается.

Т.е. предусмотренно закрытие не полной позиции, а определенного колличества lots
 

Юрий FT

Модератор
Код:
Expand Collapse Copy
//получим 10% от депозита в пунктах. 
GetPipsStopLoss(0,10);

int GetPipsStopLoss(int type,int count) {
   int num;
   if(type==0){
   num = AccountBalance()*count/100;
   }
 

AmeR

Активный участник
void ManageOrders(){
for (int i=0;i<OrdersTotal();i++)
{
if(OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if (Bid >= OrderOpenPrice() + PipsTarget_1 * Point && OrderLots() == Lots )
{ RefreshRates();
if (Move_SL_1 > 0) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + Move_SL_1 * Point, OrderTakeProfit(), 0, CLR_NONE);
RefreshRates();
OrderClose(OrderTicket(), PC1, MarketInfo(OrderSymbol(), MODE_BID), 0, CLR_NONE);
}}

if(OrderType() == OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {
if (Ask <= OrderOpenPrice() - PipsTarget_1 * Point && OrderLots() == Lots )
{ RefreshRates();
if (Move_SL_1 > 0) OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - Move_SL_1 * Point, OrderTakeProfit(), 0, CLR_NONE);
RefreshRates();
OrderClose(OrderTicket(), PC1, MarketInfo(OrderSymbol(), MODE_ASK), 0, CLR_NONE);
}}}

Друзья и только так это можно сделать!
Вот полная версия советника.
 

Вложения

193909

Местный житель
Вот советник взят с сайта codebase.Что то не получается вставить тралл,стоплосс,тейкпрофит.Особо не сильно силен в MOL.Может кто поможет.Тралл вставлял но почему то не работает.Вот код советника.
//============================================================================================
//
//
//
//
//
//============================================================================================
extern int MA1_Period=3; // Период 1-й МА
extern int MA2_Period=13; // Период 2-й МА
extern int MA1_Method=0; // Метод вычисления МА1 (SMA=0,EMA=1,SMMA=2,LWMA=3)
extern int MA2_Method=3; // Метод вычисления МА2 (SMA=0,EMA=1,SMMA=2,LWMA=3)
extern int MA1_Price=0; // Метод вычисления цены МА1
extern int MA2_Price=4; // Метод вычисления цены МА2
extern int MA1_Shift=0; // Временной сдвиг МА1
extern int MA2_Shift=0; // Временной сдвиг МА2
extern double Lot = 0.1; // Фиксированный лот
extern int slippage = 0; // Отклонение цены для рыночных ордеров
int New_Bar; // 0/1 Факт образования нового бара
int Time_0; // Время начала нового бара
int PosOpen; // Направление пересечения
int PosClose; // Направление пересечения
int total; // Количество открытых ордеров
double MA1_0; // Текущее значение 1-й МА (розов)
double MA1_1; // Предыдущее значение 1-й МА (розов)
double MA2_0; // Текущее значение 2-й МА (голубая)
double MA2_1; // Предыдущее значение 2-й МА (голубая)
int orderBuy; // 1 = факт налиия ордера Buy
int orderSell; // 1 = факт налиия ордера Sell
//============================================================================================
int init()
{

}
//============================================================================================
int start()
{
orderBuy=0;
orderSell=0;
double price;
int openOrders=0;
int total=OrdersTotal(); // Общее количество ордеров
for(int i=total-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true) // Выбираем ордер
{
if(OrderType()==OP_BUY) // Если стоит ордер на покупку
{
orderBuy=1;
if(CrossPositionClose()==1) // Закрывем ордер, если удовлетворяет
{ // условию CrossPositionClose()=1
price=MarketInfo(Symbol(),MODE_BID);
OrderClose(OrderTicket(),OrderLots(),price,slippage,CLR_NONE);
}
}
if(OrderType()==OP_SELL) // Если стоит ордер на покупку
{
orderSell=1;
if(CrossPositionClose()==2) // Закрывем ордер, если удовлетворяет
{ // условию CrossPositionClose()=2
price=MarketInfo(Symbol(),MODE_ASK);
OrderClose(OrderTicket(),OrderLots(),price,slippage,CLR_NONE);
}
}
}
}

New_Bar=0; // Для начала обнулимся
if (Time_0 != Time[0]) // Если уже другое время начала бара
{
New_Bar= 1; // А вот и новый бар
Time_0 = Time[0]; // Запомним время начала нового бара
}

MA1_0=iMA(NULL,0, MA1_Period, MA1_Shift,MAMethod(MA1_Method), MAPrice(MA1_Price), 0); // Текущее значение 1-й МА
MA1_1=iMA(NULL,0, MA1_Period, MA1_Shift,MAMethod(MA1_Method), MAPrice(MA1_Price), 1); // Предыдущее значение 1-й МА
MA2_0=iMA(NULL,0, MA2_Period, MA2_Shift,MAMethod(MA2_Method), MAPrice(MA2_Price), 0); // Текущее значение 2-й МА
MA2_1=iMA(NULL,0, MA2_Period, MA2_Shift,MAMethod(MA2_Method), MAPrice(MA2_Price), 1); // Предыдущее значение 2-й МА

if (CrossPositionOpen()==1 && New_Bar==1) // Движение снизу вверх = откр. Buy
{
OpenBuy();
}
if (CrossPositionOpen()==2 && New_Bar==1) // Движение сверху вниз = откр. Sell
{
OpenSell();
}
return;
}
//============================================================================================
int CrossPositionOpen()
{
PosOpen=0; // Вот где собака зарыта!!:)
if ((MA1_1<=MA2_0 && MA1_0>MA2_0) || (MA1_1<MA2_0 && MA1_0>=MA2_0)) // Пересечение снизу вверх
{
PosOpen=1;
}
if ((MA1_1>=MA2_0 && MA1_0<MA2_0) || (MA1_1>MA2_0 && MA1_0<=MA2_0)) // Пересечение сверху вниз
{
PosOpen=2;
}
return(PosOpen); // Возвращаем направление пересечен.
}
//============================================================================================
int CrossPositionClose()
{
PosClose=0; // Вот где собака зарыта!!:)
if ((MA1_1>=MA2_0 && MA1_0<MA2_0) || (MA1_1>MA2_0 && MA1_0<=MA2_0)) // Пересечение сверху вниз {
{
PosClose=1;
}
if ((MA1_1<=MA2_0 && MA1_0>MA2_0) || (MA1_1<MA2_0 && MA1_0>=MA2_0)) // Пересечение снизу вверх
{
PosClose=2;
}
return(PosClose); // Возвращаем направление пересечен.
}
//============================================================================================
int OpenBuy()
{
if (total==1)
{
OrderSelect(0, SELECT_BY_POS,MODE_TRADES); // Выделим ордер
if (OrderType()==OP_BUY) return; // Если он buy, то не открываемся
}
OrderSend(Symbol(),OP_BUY, Lot, Ask, slippage, 0, 0, "Buy: MA_cross_Method_PriceMode", 1, 0, CLR_NONE);// Открываемся
return;
}
//============================================================================================
int OpenSell()
{
if (total==1)
{
OrderSelect(0, SELECT_BY_POS,MODE_TRADES); // Выделим ордер
if (OrderType()==OP_SELL) return; // Если он sell, то не открываемся
}
OrderSend(Symbol(),OP_SELL, Lot, Bid, slippage, 0, 0, "Sell: MA_cross_Method_PriceMode", 2, 0, CLR_NONE);
return;
}
//============================================================================================
int MAMethod(int MA_Method)
{
switch(MA_Method)
{
case 0: return(0); // Возвращает MODE_SMA=0
case 1: return(1); // Возвращает MODE_EMA=1
case 2: return(2); // Возвращает MODE_SMMA=2
case 3: return(3); // Возвращает MODE_LWMA=3
}
}
//============================================================================================
int MAPrice(int MA_Price)
{
switch(MA_Price)
{
case 0: return(PRICE_CLOSE); // Возвращает PRICE_CLOSE=0
case 1: return(PRICE_OPEN); // Возвращает PRICE_OPEN=1
case 2: return(PRICE_HIGH); // Возвращает PRICE_HIGH=2
case 3: return(PRICE_LOW); // Возвращает PRICE_LOW=3
case 4: return(PRICE_MEDIAN); // Возвращает PRICE_MEDIAN=4
case 5: return(PRICE_TYPICAL); // Возвращает PRICE_TYPICAL=5
case 6: return(PRICE_WEIGHTED); // Возвращает PRICE_WEIGHTED=6
}
}
//============================================================================================
 

193909

Местный житель
Какой трал ты хочешь вставить?
Самый простенький,чтобы одера тралил.Желательно еще тейкпрофит и стоплосс.Тралл можно и этот к примеру.

extern int TrailingStop = 30; // Растояние в пунктах, откуда начнем тралить
extern int TrailingStep = 1; // Шаг трала


//+-------------------------------------------------------------------------------------------------------------------+
//| Функция трейлинг стоп лосс |
void T_SL()
{
int i=0;
for(i=0; i<OrdersTotal(); i++)
{
if(!(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))) continue;
if(OrderSymbol() != Symbol()) continue;
if(OrderMagicNumber()!=MagicNumber) continue;
if(OrderType()==OP_BUY)
{
if(NormalizeDouble(Bid-OrderOpenPrice(),Digits)>NormalizeDouble(TrailingStop*Point,Digits))
{
if(NormalizeDouble(OrderStopLoss(),Digits)<NormalizeDouble(Bid-(TrailingStop+TrailingStep-1)*Point,Digits))
{
OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Bid-TrailingStop*Point,Digits), OrderTakeProfit(), 0, CLR_NONE);
}
} //end if(NormalizeDouble(Bid-OrderOpenPrice(),Digits)>NormalizeDouble(TrailingStop*Point,Digits))
} //end if(OrderType()==OP_BUY)
if(OrderType()==OP_SELL)
{
if(NormalizeDouble(OrderOpenPrice()-Ask,Digits)>NormalizeDouble(TrailingStop*Point,Digits))
{
if(NormalizeDouble(OrderStopLoss(),Digits)>NormalizeDouble(Ask+(TrailingStop+TrailingStep-1)*Point,Digits))
{
OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Ask+TrailingStop*Point,Digits), OrderTakeProfit(), 0, CLR_NONE);
}
} //end if(NormalizeDouble(OrderOpenPrice()-Ask,Digits)>NormalizeDouble(TrailingStop*Point,Digits))
} //end if(OrderType()==OP_SELL)
} //end for(i=0; i<OrdersTotal(); i++)
} //end void T_SL()
//| Конец функции трейлинг стоп лосс |
//+-------------------------------------------------------------------------------------------------------------------+
 
Верх