Нужно в сеточный скрипт добавить возможность открытия первого ордера не с того места, куда скрипт брошен мышью, а с текущей цены. То есть просто щёлкаем по скрипту и он открывает первый ордер с текущей цены, а остальные согласно задаваемым параметрам.
Сам скрипт:
#property copyright "Copyright © 2012, Хлыстов Владимир"
#property link ""
#property show_inputs
/*--------------------------------------------------------------------
скрипт определяет цену, куда мы его бросили и от нее строит сеть отложенных ордеров
если ниже цены, то BuyLimit, если выше, то SellLimit
//--------------------------------------------------------------------*/
extern int Step = 50; //расстояние (в пунктах) между ордерами
extern int Orders = 5; //кол-во ордеров сетки
extern int Magic = 0; //уникальный номер ордера
extern double Lot = 0.01; //объем первого Stop ордера
extern double K_Lot = 1; //умножение лота Stop ордеров
extern double PlusLot = 0.00; //прибавлять это значение к лоту последующих ордеров
extern double MinusLot = 0.00; //отнимать это значение от лота предыдущего ордера
extern int DigitsLot = 2; //округление значения лота
extern int stoploss = 0; //уровень выставления SL, если 0, то SL не выставляется
extern int takeprofit = 0; //уровень выставления TP, если 0, то TP не выставляется
extern int Expiration = 0; //Срок истечения отложенного ордера в минутах, если 0, то срок не ограничен (1440 - сутки)
extern int attempts = 10; //кол-во попыток открытия ордера
//--------------------------------------------------------------------
string txt;
int n,slippage=3,STOPLEVEL;
datetime expiration;
//--------------------------------------------------------------------
int start()
{
if (Expiration>0) expiration=TimeCurrent()+Expiration*60; else expiration=0;
STOPLEVEL=MarketInfo(Symbol(),MODE_STOPLEVEL);
if (Digits==3 || Digits==5) slippage=30;
double Price;
double LOT=Lot;
Price = NormalizeDouble(WindowPriceOnDropped(),Digits);
for (int i=1; i<=Orders; i++)
{
if (Price<Bid)
{
OPENORDER (OP_BUYLIMIT,Price,LOT,i);
Price = NormalizeDouble(Price-Step*Point,Digits);
}
if (Price>Ask)
{
OPENORDER (OP_SELLLIMIT,Price,LOT,i);
Price = NormalizeDouble(Price+Step*Point,Digits);
}
LOT=NormalizeDouble(LOT*K_Lot+PlusLot-MinusLot,DigitsLot);
}
return(0);
}
//--------------------------------------------------------------------
void OPENORDER(int ord,double Price,double L,int i)
{
int error,err;
double SL,TP;
while (true)
{ error=0;
if (ord==OP_BUYSTOP)
{
if (takeprofit!=0) TP = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;
if (stoploss!=0) SL = NormalizeDouble(Price - stoploss*Point,Digits); else SL=0;
error=OrderSend(Symbol(),ord, L,Price,slippage,SL,TP,"",Magic);
}
if (ord==OP_SELLSTOP)
{
if (takeprofit!=0) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;
if (stoploss!=0) SL = NormalizeDouble(Price + stoploss*Point,Digits); else SL=0;
error=OrderSend(Symbol(),ord,L,Price,slippage,SL,TP,"",Magic);
}
if (ord==OP_SELLLIMIT)
{
if (takeprofit!=0) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;
if (stoploss!=0) SL = NormalizeDouble(Price + stoploss*Point,Digits); else SL=0;
error=OrderSend(Symbol(),ord, L,Price,slippage,SL,TP,"",Magic);
}
if (ord==OP_BUYLIMIT)
{
if (takeprofit!=0) TP = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;
if (stoploss!=0) SL = NormalizeDouble(Price - stoploss*Point,Digits); else SL=0;
error=OrderSend(Symbol(),ord,L,Price,slippage,SL,TP,"",Magic);
}
if (error==-1)
{
txt=StringConcatenate(txt,"\nError ",GetLastError());
if (ord==OP_BUYSTOP) txt = StringConcatenate(txt," OPENORDER BUYSTOP ", i," Ask =",DoubleToStr(Ask,Digits)," Lot =",DoubleToStr(L,DigitsLot)," Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),") SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),") TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),") STOPLEVEL=",STOPLEVEL);
if (ord==OP_SELLSTOP) txt = StringConcatenate(txt," OPENORDER SELLSTOP ", i," Bid =",DoubleToStr(Bid,Digits)," Lot =",DoubleToStr(L,DigitsLot)," Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),") SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),") TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),") STOPLEVEL=",STOPLEVEL);
if (ord==OP_SELLLIMIT) txt = StringConcatenate(txt," OPENORDER SELLLIMIT ",i," Ask =",DoubleToStr(Ask,Digits)," Lot =",DoubleToStr(L,DigitsLot)," Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),") SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),") TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),") STOPLEVEL=",STOPLEVEL);
if (ord==OP_BUYLIMIT) txt = StringConcatenate(txt," OPENORDER BUYLIMIT ", i," Bid =",DoubleToStr(Bid,Digits)," Lot =",DoubleToStr(L,DigitsLot)," Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),") SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),") TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),") STOPLEVEL=",STOPLEVEL);
Print(txt);
Comment(txt," ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));
err++;Sleep(1000);RefreshRates();
}
else
{
n++;
return;
}
if (err>attempts) return;
}
return;
}
Надеюсь, что мозгов разделить его потом на 2(отдельно для бай и селл) у меня хватит.
И нужен простенький(ну как мне кажется) советник закрывашка входящих в рынок ордеров. Суть его такова, что он должен выставлять общий тейкпрофит задаваемым количеством пипс только худшим по котировке ордерам по задаваемому параметру.
Пример:
-Допустим параметр 1. Соответственно сов при одном ордере в рынке выставляет ему задаваемый тейк(пусть будет 10пипс). При вхождении последующих ордеров в рынок до сработки тейка устанавливает им усреднённый тейк с заданным параметром(те же самые 10 пипс), исключая самый дальний.
-Меняем этот же параметр на 2. Соответственно сов при одном ордере в рынке курит бамбук. При вхождении 2го ордера в рынок устанавливает первому ордеру тейк с заданным параметром(те же самые 10 пипс). При вхождении в рынок 3го ордера отдыхает(т. е. не предпринимает ничего). При вхождении в рынок 4го ордера нижним 2м(1му и 2му) устанавливает им усреднённый тейк с заданным параметром(те же самые 10 пипс), исключая 3й и 4й ордера. При вхождении в рынок 5го ордера отдыхает. При вхождении в рынок 6го ордера нижним 3м(1му, 2му и 3му) устанавливает усреднённый тейк с заданным параметром(те же самые 10 пипс), исключая 3й, 5й и 6й ордера.
И так далее.
Ещё один параметр на общее количество ордеров в рынке, по достижении которого он бы просто выключался
P. S. Если я лихачнул с заявкой, то прошу начать с советника, а скрипт отложить на потом.
Комментарии (36)
Это только кажется.
1. 1 ордер — нет действий
2. 2 ордера — тейк первому
3. 3 ордера — нет действий
4. 4 ордера — первым двум усредненный тейк. N — всего, тейк N-2
5. 5 ордеров — нет действий
6. 6 ордеров — усредненный тейк N-3
Алгоритм. Советник включается, когда в рынке четное количество поз и вешает тейк по формуле: N/2 ордерам, где N — где N общее количество поз.
Так получается?
35 AM2 Сообщений: 16256 - Андрей
Так мне не стремается признаться, что я в некоторых вещах более, чем бестолков))), поэтому и пришпилена P.S.ка
P. S. Андрей, нужен ещё один параметр на отключение советника, допустим 10, то есть, если в рынок вошло 10 и более ордеров одного направления, то советник умирает до перезапуска. Редактирован: 12 января 2016, 19:32
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
Так это и нужно.
Для данной ситуации:
При параметре 1 один верхний ордер должен остаться в рынке, а нижние 9 должны убиться в бу +10 пипс.
При параметре 2 пять верхних должны остаться в рынке, а нижние 5 должны убиться в бу +10 пипс.
При параметре 3 семь верхних должны остаться в рынке, а нижние 3 должны убиться в бу +10 пипс.
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
Не работает эта функция:
35 AM2 Сообщений: 16256 - Андрей
35 AM2 Сообщений: 16256 - Андрей
35 AM2 Сообщений: 16256 - Андрей
Такое у меня уже есть. Не нравится тем, что риски разные, а результат одинаков. Может возможно параметр на закрытие худших ордеров сделать процентным?
Если допустим ставим 50%, вошло в рынок шесть ордеров — бу втыкается трём худшим, вошло десять — бу втыкается пяти худшим.
Если ставим 40%, вошло в рынок пять ордеров — бу втыкается двум худшим, вошло десять — бу втыкается четырём худшим.
За скрипт спасибо, уже лучше. А его никак не научить 1й ордер открывать рыночным, а остальную сеть достраивать лимитками? Редактирован: 13 января 2016, 13:30
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
Лучше напишу с нуля, так проще чем искать и править чужой код.
35 AM2 Сообщений: 16256 - Андрей
Редактирован: 13 января 2016, 22:31
35 AM2 Сообщений: 16256 - Андрей
Анатолий, сделать процентное бу можно, только мне нужно видеть на графике такую ситуацию, как я обычно прошу скрины в студию, чтобы я смог смоделировать в тестере и отладить советник.
Та же версия советника выведет в бу указанные ордера если цена развернулась.
35 AM2 Сообщений: 16256 - Андрей
Ещё бы вот это добавить:
extern double PlusLot = 0.00; //прибавлять это значение к лоту последующих ордеров
extern double MinusLot = 0.00; //отнимать это значение от лота предыдущего ордера
И убрать функцию оставления меток.
Была бы совсем красота.
По советнику попробую позже графически изложить. Редактирован: 14 января 2016, 11:29
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
35 AM2 Сообщений: 16256 - Андрей
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
Что касается советника, графически изобразить мне показалось сложновато, попробую описать алгоритм словами:
Если параметр 0 — на все входящие в рынок ордера ставит бу + задаваемое кол-во пипс.
Если параметр 1, в рынке один ордер — ничего, два ордера — худшему тейк бу+пипс, три ордера — ничего, четыре ордера-2м худшим бу+пипс, пятый ордер — ничего, шестой ордер-3м худшим бу+пипс и так далее.
Если параметр 2, в рынке один ордер — ничего, второй ордер — ничего, третий ордер — худшему бу + пипс, четвёртый ордер — ничего, пятый ордер — ничего, шестой ордер — худшим 2м — бу + пипс и так далее.
В общем суть та, что нужен регулируемый параметр, замедляющий скорость подтягивания тейка по отношению к количеству открываемых ордеров.
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
Анатолий, хотя бы калябушки в пайнте. Мне ведь четко нужно представлять всю картину.
35 AM2 Сообщений: 16256 - Андрей
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
35 AM2 Сообщений: 16256 - Андрей
Если сов как-то нумерует ведомые ордерки, может как-то можно ему подсказать, чтобы учитывал их через 1 или через 2?
P. S. Частенько бывает так и в реале: Придёшь в магазин, спросишь требуемое — нифига, всё есть, а этого нет, непруха одним словом. Редактирован: 24 января 2016, 18:50
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
Можно смотреть по остатку от деления на 2.
35 AM2 Сообщений: 16256 - Андрей
Страшно далека уже арифметика, годов так на двадцать с лишком. Мне бы пощупать чего…
Предполагаю, что остаток деления на 2 это либо ноль, либо один… Редактирован: 24 января 2016, 19:03
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
35 AM2 Сообщений: 16256 - Андрей
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
35 AM2 Сообщений: 16256 - Андрей
Тейк так и не выставил.
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
Значит надо ставить на отладку. Завтра поставлю.
35 AM2 Сообщений: 16256 - Андрей
35 AM2 Сообщений: 16256 - Андрей
20 Anatoly74 Автор Сообщений: 3710 - Анатолий
Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий