Возможно.Всем здравствуйте!
Великолепный раздел для тех кто хочет писАть сам! Очень много полезного нашёл для себя.
Вопрос к Michelangelo, а возможно ли в принципе написание упоминавшегося Вами ТрейлингПрофита?
С уважением, спасибо!
Полезные mql функции
#76
Отправлено 25 November 2010 - 14:30
- Michelangelo® это нравится
 
#77
Отправлено 25 November 2010 - 23:31
Возможно.
Спасибо! Более чем исчерпывающий ответ!
Действительно возможно, уже нашёл. Вопрос снят.
#78
Отправлено 27 November 2010 - 15:25
Функция написана по идее, предложенной Сергеем Ковалевым (SK.) в его статье "Учет ордеров в большой программе" (гугл в помощь или через личку сброшу ссылку). Вообще, как мне кажется, это наиболее удобный способ следить со всеми ордерами эксперта + большой функционал + выполняется по-моему гораздо быстрее стандартного перебора ордеров (специальных тестов не устраивал, на глаз ).
Все ордера заносятся в двухмерный массив, затем ордера сортируются по времени открытия: последний (по времени) открытый ордер будет в начале.
/*
order[][] - двухмерный массив для хранения ордеров
sSymbol - торговая пара: "0" - на которой установлен советник
iMagic - магический ордер советника: отрицательное число - любой
*/
int OrdersManagement_Mono(double &order[][], string sSymbol="0",int iMagic=0) { if(sSymbol=="0")sSymbol=Symbol(); int i=0, k=OrdersTotal()-1,cnt=0; int dg=MarketInfo(Symbol(),MODE_DIGITS); ArrayInitialize(order,0); ArrayResize(order,k+2); for(i=k;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==sSymbol) { if(OrderMagicNumber()==iMagic || iMagic<0) { cnt++; order[cnt][1]=OrderTicket(); order[cnt][2]=OrderType(); order[cnt][3]=NormalizeDouble(OrderLots(),2); order[cnt][4]=NormalizeDouble(OrderOpenPrice(),dg); order[cnt][5]=NormalizeDouble(OrderStopLoss(),dg); order[cnt][6]=NormalizeDouble(OrderTakeProfit(),dg); order[cnt][7]=OrderProfit()+OrderCommission()+OrderSwap(); order[cnt][8]=OrderMagicNumber(); order[cnt][9]=OrderOpenTime(); } } } } order[0][0]=cnt; for(i=1;i<=order[0][0];i++) { double tmp[1][10]; if(order[i][9]<order[i+1][9]) { for(int j=1;j<10;j++) { tmp[1][j]=order[i+1][j]; } for(j=1;j<10;j++) { order[i+1][j]=order[i][j]; } for(j=1;j<10;j++) { order[i][j]=tmp[1][j]; } } } /* for(i=1;i<=order[0][0];i++) { Print("order["+i+"][9]="+order[i][9]); } */ return(cnt); }
Пользоваться можно так:
int start() { double Orders[10][10]; OrdersManagement_Mono(Orders,"0",MagicNumber); }А затем если нужно найти к примеру последнюю цену открытия, то:
double dLastOpenPrice(double order[][],int direction=-1) { for(int i=1;i<=order[0][0];i++) { int TY=order[i][2]; if(TY==direction || direction==-1) { return(order[i][4]); } } return(-1.0); }где order[][] - массив с ордерами советника, а direction - тип сделки (OP_BUY, OP_SELL и т.д.), -1 - любой
- Sema и webic это нравится
#79
Отправлено 19 December 2010 - 18:06
Блок функций для определения оптимального лота путем анализа двух последних серий сделок (количество сделок в серии задается во внешних параметрах).
Идея не моя, где-то на просторах инета когда-то видел, вот решил написать. Суть следующая:
- строим простую скользящую среднюю по N последним прибылям в пунктах сделок какого-либо типа: или на покупку, или на продажу(т.е. цена открытия сделки-цена закрытия сделки, по модулю);
- строим простую скользящую среднюю по M последним прибылям в пунктах какого-либо типа: или на покупку, или на продажу (т.е. цена открытия сделки-цена закрытия сделки, по модулю);
- сравниваем полученные значения: если первая средняя выше второй, значит тренд по линии баланса вверх, и работаем обычным лотом ; в противном случае работаем минимально разрешенным лотом, снижая риск.
extern int Ma1 = 10 ; //период первой средней по истории сделок; extern int Ma2 = 20 ; //период второй средней по истории сделок; bool AboveMaProfit(int ty) { double History[10][12]; HistoryOrdersManagement_Mono(History,Symbol(),MagicNumber); double tmp=0.0; double tmp_l=0.0; double tmp_1=0.0; double tmp_l_1=0.0; if(History[0][0]<MathMax(Ma1,Ma2)+1) return(true); int cnt=0; int cnt_1=0; int TY=-1; for(int i=1;i<=History[0][0];i++) { if(cnt==Ma1) break; TY=History[i][2]; if(TY==ty) { tmp+=MathAbs(History[i][4]-History[i][11]); //tmp_l+=History[i][3]; // tmp_l+=History[i][10]-History[i][9]; cnt++; } } // tmp/=tmp_l; tmp/=(Ma1); cnt_1=0; for(i=1;i<=History[0][0];i++) { if(cnt_1==Ma2) break; TY=History[i][2]; if(TY==ty) { tmp_1+=MathAbs(History[i][4]-History[i][11]); //tmp_l_1+=History[i][3]; // tmp_l_1+=History[i][10]-History[i][9]; cnt_1++; } } // tmp_1/=tmp_l_1; tmp_1/=(Ma2); if(tmp>tmp_1)return(true); return(false); } int HistoryOrdersManagement_Mono(double &order[][], string sSymbol="0",int iMagic=0) { if(sSymbol=="0")sSymbol=Symbol(); int i=0, k=OrdersHistoryTotal()-1,cnt=0; int dg=MarketInfo(Symbol(),MODE_DIGITS); ArrayInitialize(order,0); ArrayResize(order,k+2); for(i=k;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { if(OrderSymbol()==sSymbol || sSymbol=="") { if(OrderMagicNumber()==iMagic || iMagic<0) { cnt++; order[cnt][1]=OrderTicket(); order[cnt][2]=OrderType(); order[cnt][3]=NormalizeDouble(OrderLots(),2); order[cnt][4]=NormalizeDouble(OrderOpenPrice(),dg); order[cnt][5]=NormalizeDouble(OrderStopLoss(),dg); order[cnt][6]=NormalizeDouble(OrderTakeProfit(),dg); order[cnt][7]=OrderProfit()+OrderCommission()+OrderSwap(); order[cnt][8]=OrderMagicNumber(); order[cnt][9]=OrderOpenTime(); order[cnt][10]=OrderCloseTime(); order[cnt][11]=OrderClosePrice(); } } } } order[0][0]=cnt; for(i=1;i<=order[0][0];i++) { double tmp[1][12]; if(order[i][10]<order[i+1][10]) { for(int j=1;j<10;j++) { tmp[1][j]=order[i+1][j]; } for(j=1;j<10;j++) { order[i+1][j]=order[i][j]; } for(j=1;j<10;j++) { order[i][j]=tmp[1][j]; } } } /* for(i=1;i<=order[0][0];i++) { Print("order["+i+"][10]="+order[i][10]); } */ return(cnt); }
Использовать так:
//здесь расчет лота в вашей торговой системе, результат которого сохраняется в переменную _return if(!AboveMaProfit(ty)) {Print("Работаем минимальным лотом");_return=MarketInfo(_Symbol,MODE_MINLOT);} //ty - тип сделки, OP_BUY,OP_SELL //в OrderSend в качестве лота пишем _return
Как видно по коду, что таким же образом можно использовать и другие фильтры (убрать знаки комментирования // где нужно), в частности я пробовал следующие:
- прибыль в пунктах делим на суммарный лот по этим же сделкам;
- прибыль в пунктах делим на суммарное время открытия сделок;
- BUZINESSZONE и Olej это нравится
#80
Отправлено 19 December 2010 - 19:51
Без использования фильтра:
После включения фильтра:
Используется фиксированный лот 0.1 в обоих вариантах. Тест за два последние года на GBPUSD H1, на этих данных не оптимизировался.
В аттаче советник, используемый индикатор и сет.
Параметры советника:
extern int TakeProfit = 0 ; //тейкпрофит (отрицательное число или ноль чтобы не использовать); extern int NumOfBarsSL = 4 ; //количества баров, среди которых выбирается экстремум для выставления стоплосса; extern bool CheckProfit = true ; //если true, то используем анализ истории сделок; extern int Ma1 = 10 ; //период первой средней по истории сделок; extern int Ma2 = 20 ; //период второй средней по истории сделок; extern bool UseMM = true ; //при true используется процент от депозита, при false фиксированный лот, задаваемый параметром TradeVolume; extern double TradeVolume = 0.1 ; //фиксированный лот, используется при UseMM=false; extern double RiskPercent = 5.0 ; //риск в процентах от депозита, используется при UseMM=true;
Прикрепленные файлы
- Admin, BUZINESSZONE и Kortizon это нравится
#81
Отправлено 19 December 2010 - 20:56
Спасибо большое за Грааль.Пример использования вышеуказанного фильтра.
#82
Отправлено 05 January 2011 - 02:05
Учет ордеров в моновалютном советнике
Продолжение серии функций учета ордеров. На этот раз для мультивалютного советника. Функция написана по все той же статье Сергея Ковалева, в данной реализации также используется массив для хранения ордеров, но уже трехмерный.
/* order - трехмерный массив, например, Orders[1][100][10]; 1-ое измерение - торговый символ (номер), 2 - количество ордеров на одной паре, 3 - для параметров ордера; Sym - массив с названиями торговых инструментов, расчет начинается с единицы; mn - магический номер ордеров; */ void OrdersManagement(double &order[][][],string Sym[],int mn) { int k=OrdersTotal()-1; ArrayInitialize(order,0); ArrayResize(order,ArraySize(Sym)); for(int i=k;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderMagicNumber()==mn || mn<0) { string symb=OrderSymbol(); bool found=false; for(int j=1;j<ArraySize(Sym);j++) { if(symb==Sym[j]) { found=true; break; } } if(!found)continue; order[0][0][0]++; order[j][0][0]++; int k0=order[j][0][0]; int Digits_=MarketInfo(Sym[j],MODE_DIGITS); order[j][k0][1]=OrderTicket(); order[j][k0][2]=OrderType(); order[j][k0][3]=NormalizeDouble(OrderLots(),2); order[j][k0][4]=NormalizeDouble(OrderOpenPrice(),Digits_); order[j][k0][5]=NormalizeDouble(OrderStopLoss(),Digits_); order[j][k0][6]=NormalizeDouble(OrderTakeProfit(),Digits_); order[j][k0][7]=OrderProfit()+OrderCommission()+OrderSwap(); order[j][k0][8]=OrderMagicNumber(); order[j][k0][9]=OrderOpenTime(); } } } return; }
Так же заносим ордера в массив, затем сортируем, чтобы по каждому инструменту последние открытые ордера были на первых позициях.
Как пользоваться:
double Orders[1][100][10]; string Symbols[]={"1","EURUSD","GBPUSD","AUDUSD"}; int sz=ArraySize(Symbols); ArrayResize(Orders,sz); OrdersManagement(Orders,Symbols,0); for(int i=1;i<sz;i++) { if(Orders[i][0][0]<1) { Print("нету открытых ордеров на паре "+Symbols[i]); } }
#83
Отправлено 16 February 2011 - 18:08
Блок функций для определения оптимального лота путем анализа двух последних серий сделок (количество сделок в серии задается во внешних параметрах).
Как видно по коду, что таким же образом можно использовать и другие фильтры (убрать знаки комментирования // где нужно), в частности я пробовал следующие:
Во всех этих случаях кривая баланса становится более сглаженной, зачастую уменьшается просадка и увеличивается прибыль.
- прибыль в пунктах делим на суммарный лот по этим же сделкам;
- прибыль в пунктах делим на суммарное время открытия сделок;
Заинтересовала меня вот эта штука... : 1). сама по себе идея оригинальная, красивая + 2). это впрямую ответ (или база для такого ответа) на вопрос, который я задавал в теме: экспромт на тему ММ , на который никто так и не ответил, а тут - на тебе
Только вот так, впраямую, использовать, как предлагалось в тексте - не получится, потому как оно просто не откомпилируется, из-за переменной MagicNumber , появляющейся в 1-й же исполнимой строке, которая никак не объявлена...
Что оно такое и как поправить - всё понятно ... но удивительно: неужели никто не использует и не проверяет то, что пишется в этой премного таки интересной теме?
#84
Отправлено 16 February 2011 - 18:33
Только вот так, впраямую, использовать, как предлагалось в тексте - не получится, потому как оно просто не откомпилируется, из-за переменной MagicNumber , появляющейся в 1-й же исполнимой строке, которая никак не объявлена...
Думаю любой, кто хочет сам написать советник, додумается (к тому же после того как MetaEditor выдаст мол, параметр MagicNumber не определен) добавить одну строчку:
int MagicNumber=1234567890;Проблемы здесь не вижу, надо же чтобы человек хоть что-то сам сделал, а не только скопипастил код, ничего не понимая в нем .
По использованию. Что-то отбрасывается, что-то дорабатывается и используется в дальнейшем, но не всегда есть возможность выкладывать какие-либо результаты. В вашей теме я давал примерные варианты как можно поступить, если этот способ нравится больше - пожалуйста . Применительно к способу - оптимальным был вариант с использованием динамических периодов скользящих средних, но к чему их привязать - у меня вариантов нету.
#85
Отправлено 16 February 2011 - 19:31
Думаю любой, кто хочет сам написать советник, додумается (к тому же после того как MetaEditor выдаст мол, параметр MagicNumber не определен) добавить одну строчку:
int MagicNumber=1234567890;Проблемы здесь не вижу, надо же чтобы человек хоть что-то сам сделал, а не только скопипастил код, ничего не понимая в нем .
Я не к тому, что это нужно писать так или иначе... Но я бы считал, что где-то как-то предупредить бы надо, тем более, что по разным страницам темы довольно много по примерам таких глобальных переменных необъяснённых разбросано ... уровни лосов, профитов и т.д.
Но я к тому, что меня сильно удивило, что за прошедшее время никто не проверил, не использовал, не написал замечание... Это к вопросу оценки продуктивности писания на форумах о подобных вопросах - мысли себе вслух.
#86
Отправлено 25 December 2011 - 00:40
Ветка по любому полезная, много хорошего кода - просто качественный учебный материал и полезный по любому.Я не к тому, что это нужно писать так или иначе... Но я бы считал, что где-то как-то предупредить бы надо, тем более, что по разным страницам темы довольно много по примерам таких глобальных переменных необъяснённых разбросано ... уровни лосов, профитов и т.д.
Но я к тому, что меня сильно удивило, что за прошедшее время никто не проверил, не использовал, не написал замечание... Это к вопросу оценки продуктивности писания на форумах о подобных вопросах - мысли себе вслух.
И мысли интересные в последней части, очень.
Wizard и Necron респект!
Достойный Night, если память не изменяет, классный программист с форума МТ5, конечно, не мог не постебаться чуток...
Но если умные и ядовитые программисты перестанут стебаться, то кто ж тогда будет?!...
С Olej согласен - используемые в функциях внешние переменные все же желательно описать.
Можно в отдельном посте их перечислить - и сказать, что где встретятся, то они везде вот такие.
А то как бы код с загадками, а это неправильно: коды и загадки - отдельно.
Кстати, Olej, зря вы насчет неполезности работы на форуме...
Форум хороший, люди и мысли интересные, а я так вообще ваш фанат, у меня даже небольшой ваш цитатник есть и папочка в компе - у вас очень сильная профессиональная школа за плечами, я вижу.
Что касается трала с убегающим ТП от Michelangelo®, то, как по мне, он мог бы быть весьма к месту в мартинах.
Там игры плохие с тралами, в просадке на 8 колене...
Но и на 8 колене надо пытаться отжать профит и, при достижении курсом уровня сворачивания сетки, как раз отодвинуть ТП и подпереть СЛ выглядит вполне обоснованным - и тралить парой ТП/СЛ потихоньку. Интересные очень цифры на выходе могут получится, если такое реализовать.
Да и от перерывов в связи, сбоев компа подстраховаться явными серверными ТП/СЛ в мартинах лишним никак не будет.
Но и не только в мартинах отбегающий ТП может быть интересен.
Скажем, при затухании импульса часто бывает последняя длинная свеча м1, которая может достать зазевавшийся отбегающий ТП.
На последней свече отскок быстрый часто, стоповый трал на такой экстремум не успеет, лишь отскок на много пипсов хуже поймает.
А вот все менее отбегающий ТП последнюю свечу затухающего импульса принять на себя может - только переменный шаг трала ТП надо как-то вычислить.
Есть в идее отбегающего ТП что-то, точно есть.
- Ira это нравится
#87
Отправлено 09 April 2012 - 20:29
Торговая стратегия RSI-Profit – простота и точность
кусок кода из ф-ии ММ по машкам от баланса
order[0][0]=cnt; for(i=1;i<=order[0][0];i++) { double tmp[1][12]; if(order[i][10]<order[i+1][10]) { for(int j=1;j<10;j++) { tmp[1][j]=order[i+1][j]; } for(j=1;j<10;j++) { order[i+1][j]=order[i][j]; } for(j=1;j<10;j++) { order[i][j]=tmp[1][j]; } } }
как понял, здесь сортировка для того чтобы упорядочить массив по времени закрытия ордера
может я не вижу толком от недосыпа но мне кажется сортировка здесь не получится, мало перемещений элементов. Только по одному разу меняются соседние элементы. В результате только один элемент переместится в начало или в конец. Остальные останутся неупорядоченными. Или я неправ?
И еще.
На каждом тике перебор всей истории с записью в массив - не сильно замедлит тесты? Может есть смысл только последний закрытый ордер добавлять каждый раз в массив? И, допустим, не на каждом тике, а после закрытия очередного ордера.
Или же эти операции быстрые и не стоит париться?
а за функции эти огромный респект!
#88
Отправлено 12 April 2012 - 12:45
начинает наша мм работать только когда наберется сделок = SlowMA. А это может быть например 50
и это бывает очень не гут
надо думать как сделать чтобы последние 50 сделок из тестера переносить в сову чтобы мм начинал сработать СРАЗУ
#89
Отправлено 12 April 2012 - 13:59
можно без сортировки - насколько знаю, сейчас ордера при выборе в цикле через OrderSelect() сортируются автоматически по времени закрытия, поэтому тот кусок кода можно вообще удалить.
Тот код я писал для проверки идеи, цель "сделать оптимальный алгоритм" перед собой не ставил. Можно и только последний добавлять в массив.На каждом тике перебор всей истории с записью в массив - не сильно замедлит тесты? Может есть смысл только последний закрытый ордер добавлять каждый раз в массив?
Лично я для себя делаю советники только по ценам открытия - не верю в моделирование тестера, особенно учитывая "высокое качество котировок" в наших дц и "небольшие дыры" в истории на два-три месяца на минутном графике - поэтому для меня более-менее нормальная производительность функций, хотя их можно и улучшить.
Закрытие ордера еще нужно отследить, а это нужно делать на каждом тике(если советник не по ценам открытия), поэтому без тестирования производительности, к сожалению, нельзя сказать, какой вариант будет быстрее работать.И, допустим, не на каждом тике, а после закрытия очередного ордера.
чтение/запись файлов в помощь добавляешь в deinit() советника функцию, которая будет сохранять текущую историю ордеров, прогоняешь в тестере, потом добавляешь в init() функцию чтения файла и запись данных из него в массив ордеров. Этот массив потом дополняешь новыми значениями ордеров. Или вынести в настройки параметры вроде LoadHistory и WriteHistory, чтобы код постоянно не изменять.надо думать как сделать чтобы последние 50 сделок из тестера переносить в сову чтобы мм начинал сработать СРАЗУ
#90
Отправлено 12 April 2012 - 14:03