суть такая, что среди полотенца ордеров надо их смешать при закрытии, с пропорцией 1к3 или ещё лучше, но что бы не было 5 убытка подрят. в гугле инфы нет даже и намёков.
Написал функцию, проверял принтами, вроде работает нормально, в понедельник проверю на реале.
Функция большая получилась, немного сжал форматирование кода там где всё и так понятно, там где разбор массива, оставил с нормальным форматированием - можно сжать.
Работает по принципу: закрывает от большего лота к меньшему, так-же учитывает пропорцию прибыльные/убыточные. Пока особого смысла не пойму зачем делать закрытие по пропорции, но на выходных почитаю о преимуществе.
Функция в любом случае работает быстрее, чем брокер закрывает позиции. Извиняюсь что долго, но в такой рынок заниматься писаниной - глупо и тупо, нужно торговать )
//===============================================================================================//------------- Закрытие позиций в порядке сортировки по пропорции: прибыль/убыток -------------+//===============================================================================================void ClosePosSort(string symb="0",int type=-1,int mg=-1,color cl=clrNONE) {
int c=0,pl=0,ms=0;
double m[][3],pr=0;
if(symb=="0") symb=_Symbol;
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) return;
for(int i=0; i<OrdersTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if((OrderSymbol()==symb||symb=="")&&(type<0||OrderType()==type)&&(mg<0||OrderMagicNumber()==mg)) {
if(OrderType()==OP_BUY || OrderType()==OP_SELL) {
pr=(OrderProfit()+OrderSwap()+OrderCommission());
if(pr>0) pl++; else ms++; // счетчик количества прибыльных/убыточных позиций
c++; // счетчик общего количества позицийArrayResize(m, c); // собираем массив закрываемых позиций
m[c-1][0]=OrderLots();
m[c-1][1]=OrderTicket();
m[c-1][2]=pr;
}}}}
if(c>0) PosBySort(m, c, pl, ms, symb, type ,mg, cl); // если есть что закрыватьreturn;
}
//----------------- Сортируем прибыльные/убыточные для пропорционального закрытия (+/-)void PosBySort(double& mas[][],int c,double pl,double ms,string symb,int type,int mg,color cl) {
double Plus[], Minus[], dfp=0, dfm=0;
int p=0, m=0, plus=0, minus=0;
// Сортируем по размеру лотов от большего к меньшемуArraySort(mas, WHOLE_ARRAY, 0, MODE_DESCEND);
// Создадим массивы прибыльных и убыточных позицийfor(int am=0; am<c; am++) {
if(mas[am][2]>0) { // если профит больше "0"
plus++;
ArrayResize(Plus, plus);
Plus[plus-1]=mas[am][1]; // прибыльные тикеты
} else {
minus++;
ArrayResize(Minus, minus);
Minus[minus-1]=mas[am][1]; // убыточные тикеты
}
}
// Узнаем соотношение прибыльные/убыточные
pl=pl==0?1:pl;
ms=ms==0?1:ms;
dfp=MathCeil(pl/ms); dfp=dfp==0?1:dfp;
dfm=MathCeil(ms/pl); dfm=dfm==0?1:dfm;
// Comment("dfm ",dfm," dfp ",dfp," ms ",ms," pl ",pl);// Пройдем по массивамwhile(c > 0) {
int jm=0, jp=0;
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
// Минусовые доминируют - начинаем закрывать с минусовыхif(pl<=ms) {
// минусовыеfor(int im=0; im<ArraySize(Minus); im++) {
jm++;
c--;
m++;
if(m>ArraySize(Minus)) break; // не выйти за пределы массива
ClosePosTicket((int)Minus[m-1], cl);
if(jm==dfm) break; // соблюдение пропорции
}
// плюсовыеfor(int ip=0; ip<ArraySize(Plus); ip++) {
jp++;
c--;
p++;
if(p>ArraySize(Plus)) break; // не выйти за пределы массива
ClosePosTicket((int)Plus[p-1], cl);
if(jp==dfp) break; // соблюдение пропорции
}
}
// Плюсовые доминируют - начинаем закрывать с плюсовыхif(pl>ms) {
// плюсовыеfor(int ip=0; ip<ArraySize(Plus); ip++) {
jp++;
c--;
p++;
if(p>ArraySize(Plus)) break; // не выйти за пределы массива
ClosePosTicket((int)Plus[p-1], cl);
if(jp==dfp) break; // соблюдение пропорции
}
// минусовыеfor(int im=0; im<ArraySize(Minus); im++) {
jm++;
c--;
m++;
if(m>ArraySize(Minus)) break; // не выйти за пределы массива
ClosePosTicket((int)Minus[m-1], cl);
if(jm==dfm) break; // соблюдение пропорции
}
}
//-
} // while// Проверяем, все закрылись или нет. Возможно нужен флаг, чтоб не закрыть ново-открытые.
ClosePosSort(symb, type ,mg, cl);
return;
} // end//----------------- Закрытие позиций по переданному тикетуvoid ClosePosTicket(int tic, color cl=clrNONE) {
double l, p, pr;
bool res=false;
if(OrderSelect(tic, SELECT_BY_TICKET)) {
if(OrderCloseTime()==0) {
for(int i=1; i<=5; i++) { // количество попыток закрытия при ошибкеif(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
while(!IsTradeAllowed()) Sleep(5000);
RefreshRates();
p=MarketInfo(OrderSymbol(), OrderType()==OP_BUY? MODE_BID:MODE_ASK);
l=OrderLots();
p=NormalizeDouble(p, (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
pr=OrderProfit()+OrderSwap()+OrderCommission();
res=OrderClose(OrderTicket(), l, p, Slippage, cl);
if(res) {
break;
} else {
int err=_LastError;
if(err==146) while(IsTradeContextBusy()) Sleep(1000);
Print("Close Error(",err,") ",OrderType()==0?"Buy=":"Sell=",OrderSymbol(),", Ticket: ",OrderTicket(), ", Price: ",
DoubleToStr(p,(int)MarketInfo(OrderSymbol(), MODE_DIGITS)),", Lot: ",OrderLots(),", Profit: ",DoubleToStr(pr,2));
Sleep(1000*5);
}}}}}
//===============================================================================================
Применение как всегда
#property strictint Slippage=30;
//===============================================================================================voidOnTick()
{
// Применение// ClosePosSort(Символ, OP_BUY или OP_SELL, Magic, Цвет значка);if(условие закрытия) {
ClosePosSort(_Symbol, -1, 14, clrYellow); // по текущему символу BUY и SELL с Magic=14
ClosePosSort("GBPCAD", OP_SELL, 35, clrYellow); // по конкретному символу только SELL с Magic=35
ClosePosSort("", OP_BUY , -1, clrYellow); // по всему счету только BUY и любым Magic номером
}
//-
}
Конструктивная критика работы кода - приветствуется.
Написал функцию, проверял принтами, вроде работает нормально, в понедельник проверю на реале.
Функция большая получилась, немного сжал форматирование кода там где всё и так понятно, там где разбор массива, оставил с нормальным форматированием - можно сжать.
Работает по принципу: закрывает от большего лота к меньшему, так-же учитывает пропорцию прибыльные/убыточные. Пока особого смысла не пойму зачем делать закрытие по пропорции, но на выходных почитаю о преимуществе.
Функция в любом случае работает быстрее, чем брокер закрывает позиции. Извиняюсь что долго, но в такой рынок заниматься писаниной - глупо и тупо, нужно торговать )
Применение как всегда
Конструктивная критика работы кода - приветствуется.
Огромное спасибо за функцию, я бы городил огород с кучей циклов и проверок, начну тестировать тоже на реале. Смысл в том что если закрывать серию красиво и график красивее, на результат торговли не влияет, а вот визуальное восприятие да. Еще раз огромное спасибо!
Эта проверка служит для экстренной остановки функции. Бывают ситуации, когда не нужно закрывать позиции, например на новостях, пошло резвое движение в нашу сторону, появилась возможность выжать с рынка ещё несколько пунктов, но тут начинается закрытие, и нажатием на кнопку "Авто-торговля", мы прерываем работу функции. Так-же проверка на разрешение торговли, если отжата кнопка "Авто-торговля", то функция не работает, если в режиме тестера - то игнорируем кнопку "Авто-торговля"
Vitaly Muzichenko: Эта проверка служит для экстренной остановки функции. Бывают ситуации, когда не нужно закрывать позиции, например на новостях, пошло резвое движение в нашу сторону, появилась возможность выжать с рынка ещё несколько пунктов, но тут начинается закрытие, и нажатием на кнопку "Авто-торговля", мы прерываем работу функции. Так-же проверка на разрешение торговли, если отжата кнопка "Авто-торговля", то функция не работает, если в режиме тестера - то игнорируем кнопку "Авто-торговля"
Спасибо за пояснения, а так же за код. Закрывает всё правильно, перемешивает убыточные позиции при закрытии среди профитных, улучшая тем статистику и делает более плавный баланс на выходе. А также великолепно кроет при разных лотах.
пока проверил в тестере, на центе с понедельника проверю.
Спасибо за пояснения, а так же за код. Закрывает всё правильно, перемешивает убыточные позиции при закрытии среди профитных, улучшая тем статистику и делает более плавный баланс на выходе. А также великолепно кроет при разных лотах.
пока проверил в тестере, на центе с понедельника проверю.
Вот так будет скорее всего правильнее, чем было
//===============================================================================================//------------- Закрытие позиций в порядке сортировки по пропорции: прибыль/убыток -------------+//===============================================================================================void ClosePosSort(string symb="0",int type=-1,int mg=-1,color cl=clrNONE) {
int c=0,pl=0,ms=0;
double m[][3],pr=0;
if(symb=="0") symb=_Symbol;
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) return;
for(int i=0; i<OrdersTotal(); i++) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if((OrderSymbol()==symb||symb=="")&&(type<0||OrderType()==type)&&(mg<0||OrderMagicNumber()==mg)) {
if(OrderType()==OP_BUY || OrderType()==OP_SELL) {
pr=(OrderProfit()+OrderSwap()+OrderCommission());
if(pr>0) pl++; else ms++; // счетчик количества прибыльных/убыточных позиций
c++; // счетчик общего количества позицийArrayResize(m, c); // собираем массив закрываемых позиций
m[c-1][0]=OrderLots();
m[c-1][1]=OrderTicket();
m[c-1][2]=pr;
}}}}
if(c>0) PosBySort(m, c, pl, ms, symb, type ,mg, cl); // если есть что закрыватьreturn;
}
//----------------- Сортируем прибыльные/убыточные для пропорционального закрытия (+/-)void PosBySort(double& mas[][],int cw,double pl,double ms,string symb,int type,int mg,color cl) {
double Plus[], Minus[], dfp=0, dfm=0;
int mp=0, mm=0, pp=0, pm=0, plus=0, minus=0;
// Сортируем по размеру лотов от большего к меньшемуArraySort(mas, WHOLE_ARRAY, 0, MODE_DESCEND);
// Создадим массивы прибыльных и убыточных позицийfor(int am=0; am<cw; am++) {
if(mas[am][2]>0) { // если профит больше "0"
plus++;
ArrayResize(Plus, plus);
Plus[plus-1]=mas[am][1]; // прибыльные тикеты
} else {
minus++;
ArrayResize(Minus, minus);
Minus[minus-1]=mas[am][1]; // убыточные тикеты
}
}
// Узнаем соотношение прибыльные/убыточные
pl=pl==0?1:pl;
ms=ms==0?1:ms;
dfp=MathCeil(pl/ms); dfp=dfp==0?1:dfp;
dfm=MathCeil(ms/pl); dfm=dfm==0?1:dfm;
// Пройдем по массивамfor(int ci=0; ci<cw; ci++) {
int jm=0, jp=0;
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
// Минусовые доминируютif(pl<=ms) {
// минусовыеfor(int im=0; im<ArraySize(Minus); im++) {
jm++;
ci++;
mm++;
if(mm>ArraySize(Minus)) break; // не выйти за пределы массива
ClosePosTicket((int)Minus[mm-1], cl);
if(jm==dfm) break; // соблюдение пропорции
}
// плюсовыеfor(int ip=0; ip<ArraySize(Plus); ip++) {
jp++;
ci++;
mp++;
if(mp>ArraySize(Plus)) break; // не выйти за пределы массива
ClosePosTicket((int)Plus[mp-1], cl);
if(jp==dfp) break; // соблюдение пропорции
}
}
// Плюсовые доминируютif(pl>ms) {
// плюсовыеfor(int ip=0; ip<ArraySize(Plus); ip++) {
jp++;
ci++;
pp++;
if(pp>ArraySize(Plus)) break; // не выйти за пределы массива
ClosePosTicket((int)Plus[pp-1], cl);
if(jp==dfp) break; // соблюдение пропорции
}
// минусовыеfor(int im=0; im<ArraySize(Minus); im++) {
jm++;
ci++;
pm++;
if(pm>ArraySize(Minus)) break; // не выйти за пределы массива
ClosePosTicket((int)Minus[pm-1], cl);
if(jm==dfm) break; // соблюдение пропорции
}
}
//-
} // for// Проверяем, все закрылись или нет
ClosePosSort(symb, type ,mg, cl);
return;
} // end//----------------- Закрытие позиций по переданному тикетуvoid ClosePosTicket(int tic, color cl=clrNONE) {
double l, p, pr;
bool res=false;
if(OrderSelect(tic, SELECT_BY_TICKET)) {
if(OrderCloseTime()==0) {
for(int i=1; i<=5; i++) {
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
while(!IsTradeAllowed()) Sleep(5000);
RefreshRates();
p=MarketInfo(OrderSymbol(), OrderType()==OP_BUY? MODE_BID:MODE_ASK);
l=OrderLots();
p=NormalizeDouble(p, (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
pr=OrderProfit()+OrderSwap()+OrderCommission();
res=OrderClose(OrderTicket(), l, p, Slippage, cl);
if(res) {
break;
} else {
int err=_LastError;
if(err==146) while(IsTradeContextBusy()) Sleep(1000);
Print("Close Error(",err,") ",OrderType()==0?"Buy=":"Sell=",OrderSymbol(),", Ticket: ",OrderTicket(), ", Price: ",
DoubleToStr(p,(int)MarketInfo(OrderSymbol(), MODE_DIGITS)),", Lot: ",DoubleToStr(OrderLots(),2),", Profit: ",DoubleToStr(pr,2));
Sleep(1000*5);
}}}}}
//===============================================================================================
А можно узнать, что Вы переделали в новой версии, технические нюансы или алгоритм сортировки ? Сортировка осталась такой же как и была, судя по тесту. На реале вчера проверял функцию и был приятно удивлен скоростью работы, визуально даже быстрее закрывает чем стандартный перебор) За это ещё раз спасибо.
Vladimir Zubov: А можно узнать, что Вы переделали в новой версии, технические нюансы или алгоритм сортировки ? Сортировка осталась такой же как и была, судя по тесту. На реале вчера проверял функцию и был приятно удивлен скоростью работы, визуально даже быстрее закрывает чем стандартный перебор) За это ещё раз спасибо.
Улучшена сортировка при б0льшем перекосе прибыльные/убыточные. Связано с изменением
// Пройдем по массивам
for(int ci=0; ci<cw; ci++) {
То есть, сначала закрывает всё что собрано в массиве изначально по коэффициенту, после всех закрытий, остаются ещё открытые, и снова функция начинает работу заново, снова сортирует, и начинает закрытие.
Улучшено тем, что в самом конце закрывает так-же с сортировкой, а первом варианте, сначала сортирует, и если не хватает позиций для перемешивания - закрывает оставшиеся подряд. Полезно при большом перекосе, но функция может срабатывать до трёх раз.
суть такая, что среди полотенца ордеров надо их смешать при закрытии, с пропорцией 1к3 или ещё лучше, но что бы не было 5 убытка подрят. в гугле инфы нет даже и намёков.
Написал функцию, проверял принтами, вроде работает нормально, в понедельник проверю на реале.
Функция большая получилась, немного сжал форматирование кода там где всё и так понятно, там где разбор массива, оставил с нормальным форматированием - можно сжать.
Работает по принципу: закрывает от большего лота к меньшему, так-же учитывает пропорцию прибыльные/убыточные. Пока особого смысла не пойму зачем делать закрытие по пропорции, но на выходных почитаю о преимуществе.
Функция в любом случае работает быстрее, чем брокер закрывает позиции. Извиняюсь что долго, но в такой рынок заниматься писаниной - глупо и тупо, нужно торговать )
Применение как всегда
Конструктивная критика работы кода - приветствуется.
Написал функцию, проверял принтами, вроде работает нормально, в понедельник проверю на реале.
Функция большая получилась, немного сжал форматирование кода там где всё и так понятно, там где разбор массива, оставил с нормальным форматированием - можно сжать.
Работает по принципу: закрывает от большего лота к меньшему, так-же учитывает пропорцию прибыльные/убыточные. Пока особого смысла не пойму зачем делать закрытие по пропорции, но на выходных почитаю о преимуществе.
Функция в любом случае работает быстрее, чем брокер закрывает позиции. Извиняюсь что долго, но в такой рынок заниматься писаниной - глупо и тупо, нужно торговать )
Применение как всегда
Конструктивная критика работы кода - приветствуется.
Возник вопрос, зачем проверка в режиме тестера или нет ?
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
P.S. код не вставляется в сообщение нормально
Возник вопрос, зачем проверка в режиме тестера или нет ?
if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
P.S. код не вставляется в сообщение нормально
Эта проверка служит для экстренной остановки функции. Бывают ситуации, когда не нужно закрывать позиции, например на новостях, пошло резвое движение в нашу сторону, появилась возможность выжать с рынка ещё несколько пунктов, но тут начинается закрытие, и нажатием на кнопку "Авто-торговля", мы прерываем работу функции. Так-же проверка на разрешение торговли, если отжата кнопка "Авто-торговля", то функция не работает, если в режиме тестера - то игнорируем кнопку "Авто-торговля"
Спасибо за пояснения, а так же за код. Закрывает всё правильно, перемешивает убыточные позиции при закрытии среди профитных, улучшая тем статистику и делает более плавный баланс на выходе. А также великолепно кроет при разных лотах.
пока проверил в тестере, на центе с понедельника проверю.
Спасибо за пояснения, а так же за код. Закрывает всё правильно, перемешивает убыточные позиции при закрытии среди профитных, улучшая тем статистику и делает более плавный баланс на выходе. А также великолепно кроет при разных лотах.
пока проверил в тестере, на центе с понедельника проверю.
Вот так будет скорее всего правильнее, чем было
Вот так будет скорее всего правильнее, чем было
А можно узнать, что Вы переделали в новой версии, технические нюансы или алгоритм сортировки ? Сортировка осталась такой же как и была, судя по тесту. На реале вчера проверял функцию и был приятно удивлен скоростью работы, визуально даже быстрее закрывает чем стандартный перебор) За это ещё раз спасибо.
Улучшена сортировка при б0льшем перекосе прибыльные/убыточные. Связано с изменением
// Пройдем по массивам
for(int ci=0; ci<cw; ci++) {
То есть, сначала закрывает всё что собрано в массиве изначально по коэффициенту, после всех закрытий, остаются ещё открытые, и снова функция начинает работу заново, снова сортирует, и начинает закрытие.
Улучшено тем, что в самом конце закрывает так-же с сортировкой, а первом варианте, сначала сортирует, и если не хватает позиций для перемешивания - закрывает оставшиеся подряд. Полезно при большом перекосе, но функция может срабатывать до трёх раз.
Вот результат работы