Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 122
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Решил дополнить предыдущий вопрос.
1)
Допустим у меня сигнал - при резком расширении спреда (на новостях)
закрыть все текущие сделки
Но на новостях ордера просто так закрыть или открыть не дадут.
поэтому если взять команду допустим OrderClose засунуть в цикл + Sleep (3000) и выполнять до тех пор пока не закроется
2)
если в кнопке привязать внутреннюю переменную и привязать значение нажата\отжата к возможности открытия ордера будет ли это работать в реальном времени?
Решил дополнить предыдущий вопрос.
1)
Допустим у меня сигнал - при резком расширении спреда (на новостях)
закрыть все текущие сделки
Но на новостях ордера просто так закрыть или открыть не дадут.
поэтому если взять команду допустим OrderClose засунуть в цикл + Sleep (3000) и выполнять до тех пор пока не закроется
2)
если в кнопке привязать внутреннюю переменную и привязать значение нажата\отжата к возможности открытия ордера будет ли это работать в реальном времени?
Приветствую, пишу индикатор, который отрисовывает историю ордеров на графике, код:
//| history.mq4 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_chart_window
extern int MagicNumber = 1110;
extern datetime HistoryOrdersFromDateTime = 0;
extern color SellColor = clrRed;
extern color BuyColor = clrBlue;
extern color ProfitColor = clrWhite;
extern bool DeleteHistoryOrders = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
void start()
{
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
if(HistoryOrdersFromDateTime<OrderCloseTime())
{
if((TimeCurrent()-OrderCloseTime())>60)
HistoryOrders();
}
}
}
}
void HistoryOrders()
{
double b=OrderOpenPrice(), d=OrderClosePrice(), lots=OrderLots(), Profit=0;
datetime a=OrderOpenTime(), c=OrderCloseTime(), close_time;
string Ticket=(string)OrderTicket(), type="Sell", symbol=OrderSymbol(), comment=OrderComment(), Background;
color col=SellColor;
if(OrderType()==0) {col=BuyColor; type="Buy";}
if(DeleteHistoryOrders==false)
{
//Начальная точка
ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJ_ARROW,0,a,b);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_COLOR,col);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_ARROWCODE,1);
//Линия
ObjectCreate("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJ_TREND,0,a,b,c,d);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_WIDTH,1);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_STYLE,STYLE_DOT);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_RAY,0);
//Конечная точка
ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJ_ARROW,0,c,d);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_ARROWCODE,3);
//Расчет профита
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
Ticket=(string)OrderTicket();
}
}
}
//Размер фона
for(int i=2; i<StringLen(DoubleToString(Profit,2)); i++)
StringAdd(Background,"g");
//Фон профита
ObjectCreate("#"+Ticket+" Background",OBJ_TEXT,0,c,d);
ObjectSet("#"+Ticket+" Background",OBJPROP_ANCHOR,ANCHOR_LOWER);
ObjectSetText("#"+Ticket+" Background",Background,10,"Webdings",col);
ObjectSet("#"+Ticket+" Background",OBJPROP_PRICE1,d);
ObjectSet("#"+Ticket+" Background",OBJPROP_TIME1,c+Period());
//Профит
ObjectCreate("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJ_TEXT,0,c,d);
ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_ANCHOR,ANCHOR_LOWER);
ObjectSetText("#"+Ticket+" Profit: "+DoubleToString(Profit,2),DoubleToString(Profit,2),10,"Arial",ProfitColor);
ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_PRICE1,d);
ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_TIME1,c+Period());
} else ObjectsDeleteAll(0, "#"+Ticket+" ");
}
void OnDeinit(const int reason)
{
//Удалаение истории ордеров
for(int i=0; i<OrdersHistoryTotal(); i++)
{
DeleteHistoryOrders=true;
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
HistoryOrders();
}
}
Единичный сделки индикатор отрисовывает правильно (линия>фон>профит), а вот в отображении закрытых сеток ордеров есть небольшой "косяк" (скрин прилагаю), на фон и профит накладываются линии (линия(1)>фон>профит>линия(2)>линия(3)>линия(4) . . . ).
Должно быть так: (линия(1)>линия(2)>линия(3)>линия(4) . . . >фон>профит). Различные танцы с бубном не привели к успеху, помогите доработать.
Приветствую, пишу индикатор, который отрисовывает историю ордеров на графике,
Единичный сделки индикатор отрисовывает правильно (линия>фон>профит), а вот в отображении закрытых сеток ордеров есть небольшой "косяк" (скрин прилагаю), на фон и профит накладываются линии (линия(1)>фон>профит>линия(2)>линия(3)>линия(4) . . . ).
Должно быть так: (линия(1)>линия(2)>линия(3)>линия(4) . . . >фон>профит). Различные танцы с бубном не привели к успеху, помогите доработать.
Попробуй линиям и значкам присваивать свойство OBJPROP_BACK на заднем плане.
Не вариант, так линии становятся на заднем плане (за свечами), а нужно что б отрисовка была поверх свечей: свечи>линии>фон профита>профит
К стати это избавит от дополнительного цикла для подсчёта профита.
Вот этого
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
Ticket=(string)OrderTicket();
}
}
}
ps просьба. Размещай картинки через эту кнопку
Тогда только последовательность нанесения на график. Или при нанесении фона и профита проверять наличие этих объектов по времени, читать значение профита в объекте OBJ_TEXT и плюсовать к профиту текущего ордера. Потом удалять фон и профит и заново рисовать.
К стати это избавит от дополнительного цикла для подсчёта профита.
а профит определяешь в начале вместе с остальными параметрами ордера.
Как задать такую последовательность отрисовки, допустим, сначала отрисовываем все точки и линии соединяющие их, а после приступить к отрисовке фона и профита?
Как задать такую последовательность отрисовки, допустим, сначала отрисовываем все точки и линии соединяющие их, а после приступить к отрисовке фона и профита?
Лучше рассмотри этот вариант.
ObjectFind() потом если объект найден ObjectGetString() перевод из текста в число, к полученному плюсуем профит последнего ордера, удаляем устаревший OBJ_TEXT и рисуем новый.
Если-же это первый или единственный ордер закрытый на этом баре, то просто рисуется OBJ_TEXT и всё.
А для упрощения имя задать не тикет, а время открытия бара. Или тикет нужен для последующей работы?
Ну, если по первому моему предположению, то так. А потом у меня сразу мелькнул экспромт и я не стал удалять первое предложение, но второе мне больше нравится.
Лучше рассмотри этот вариант.
ObjectFind() потом если объект найден ObjectGetString() перевод из текста в число, к полученному плюсуем профит последнего ордера, удаляем устаревший OBJ_TEXT и рисуем новый.
Если-же это первый или единственный ордер закрытый на этом баре, то просто рисуется OBJ_TEXT и всё.
А для упрощения имя задать не тикет, а время открытия бара. Или тикет нужен для последующей работы?
Да тикет нужен для последующего анализа истории. Спасибо, что наталкнули на перерисовку. Решил проблему немного проще, добавив в код такую проверку и перерисовку:
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
ProfitTicket=(string)OrderTicket();
CountOrders++;
}
}
}
//Перерисовка фона и профита
if(CountOrders>1)
{
ObjectDelete("#"+Ticket+" Background");
ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
Ticket=ProfitTicket;
}
Не знаю на сколько это правильно, но в принципе отрисовывает как надо (линии>фон>профит):
Да тикет нужен для последующего анализа истории. Решил проблему немного проще, добавив в код такую проверку и перерисовку:
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
ProfitTicket=(string)OrderTicket();
CountOrders++;
}
}
}
//Перерисовка фона и профита
if(CountOrders>1)
{
ObjectDelete("#"+Ticket+" Background");
ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
Ticket=ProfitTicket;
}
В принципе отрисовывает правильно (линии>фон>профит):