Само по себе хранение не влияет, на реале если вызывать индюк на открытии бара - почти не заметно, по при тестировании - влияет, в основном все за время теста и опта бьются... При вызове индюка происходит масса телодвижений терема - создаются стеки вызова и прочие низкоуровневые движения. Вот Вы знаете сколько экземпляров индюка в памяти при вызове из совы с помощью iCustom нескольких буферов одного индюка с одинаковыми настройками? Я так и не выяснил, но терзают смутные сомнения.хранение в индикаторе 1000 значений разве влияет на производительность?
Обучение языку MQL4 под MetaTrader 4📌
От xbms, 13 апреля, 2013 в Уголок Программиста
Эх, :-H ещё один глупый вопрос по MQL4.
Как говорилось выше, изучаю советника.
В советнике есть функция void Start(). Если я правильно понимаю, то она выполняется только при старте советника? Но справка говорит, что событие Start присуще только скриптам, но ни как не индикаторам и советникам. Другие источники говорят, что Start() - это OnTick().
Исходя из непонимания данного события, я недопонимаю логику советника. Подтолкните, пожалуйста, в нужное направление ^:)^.
start - это OnTick, выполняется каждый тик
init(), start(), и deinit() - устаревшие названия. им соответствуют OnInit(), OnTick() и OnDeinit()
OnStart() - не равно start()
при запуске скриптов - выполняется OnStart(), а при запуске советников и индикаторов - OnInit()
Не получается запустить трал, ордера открывает в безубыток переносит, а тралить не хочет в чем может быть ошибка?
void OnTick()
{
if (TrailingStop!=0) Trailing();
if ( isNewBar() )
{
Основная программа (открытие ордеров по условию)
}
{
Перенос ордеров в безубыток
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void Trailing()
{
for(int i=OrdersTotal() - 1; i>= 0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol()||OrderMagicNumber()==Magic)
if(OrderType()==OP_BUY)
{
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>TrailingStop)
{
int sl = NormalizeDouble(Bid - TrailingStop*Point, Digits);
OrderModify(OrderTicket(),OrderOpenPrice(), sl,OrderTakeProfit(),0,Green);
}
}
}
if(OrderSymbol()==Symbol()||OrderMagicNumber()==Magic)
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==Magic)
if(Bid-OrderOpenPrice()>TrailingStop)
if(Bid-OrderOpenPrice()>TrailingStop*Point)
Подправил, не помогло :(
Если после OP_BUY далее идёт такое же условие, только с OP_SELL, то оно выполняться не будет, т.к., код после
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol()||OrderMagicNumber()==Magic)не заключён в фигурные скобкиПроще бы так:
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=Magic) continue;Всем спасибо за помощь, получилось. Перепутал тип переменных СтопЛос обозначил как int а надо было double
Универсальное решение- считывать показания индикаторов 1 раз в свечу.
Все остальное перечисленное , ИМХО, не поможет .(помещать код индикатора в свечу говорят поможет, но на сколько...)
это интересно. а как это в общих чертах лучше реализовать?
- взять расчетную часть инд. в условие if(NewBar()).
- установить в сове вызов iCustom в условие if(NewBar())
- или ка то по другому?
- установить в сове вызов iCustom в условие if(NewBar())
Я бы так сделал... Если логика индикатора позволяет обращаться раз в свечу
Подскажите как закрывать ордера в определенный день и час, или допустим через определенное время после открытия?
Примерно так:Подскажите как закрывать ордера в определенный день и час, или допустим через определенное время после открытия?
if ( Day() == 5 && Hour() == 18 ) OrderClose(...);
или
if ( TimeCurrent() - OrderOpenTime() > minutClose * 60 ) OrderClose(...);
Доброго времени суток, уважаемые программисты.
Цель: отследить исполнение TP сделок, открытых советником.
Мой метод: После расчета TP и перед его модификацией записываю OrderTicket() в переменную LastOrderTicket. По каждому тику сравниваю значение переменной с последним ордером в истории сделок LastHistOrderTicket (отдельно для buy, отдельно для sell).
Проблема: Среди множества сделок (несколько лет истории) нашлась одна нехорошая, которая закрылась по TP слишком быстро, настолько быстро, что LastOrderTicket не успел модифицировать. Тестирование на "Контрольных точках", на "Тиках" все проходит, на демке тоже пока без проблем, но хотелось бы решить эту проблему для всех методов тестирования.
Часть кода прилагается:
void OnTick(){
fOrdersHistoryCounting();
for(int pos=OrdersTotal()-1;pos>=0;pos--){
if(!OrderSelect(pos,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderType()==OP_BUY && OrderMagicNumber()==MagicNumber && OrderSymbol()==_Symbol){
BLastOrderTicket=OrderTicket();
if(OrderTakeProfit()!=NormalizeDouble(B_Take_Profit,Digits)){
fModifyPosition(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),NormalizeDouble(B_Take_Profit,Digits),OrderExpiration(),clrRed);
}
}
}
}
void fOrdersHistoryCounting()
{
for(int pos=0;pos {
if(!OrderSelect(pos,SELECT_BY_POS,MODE_HISTORY)) continue;
if(OrderType()==OP_BUY && OrderMagicNumber()==MagicNumber && OrderSymbol()==_Symbol) BLastHistOrderTicket=OrderTicket();
}
if(BLastHistOrderTicket==BLastOrderTicket){
buy=0;
}
}
Изменено 25 октября, 2018 пользователем Finchi
Я при этом ни чего не сохраняю, просто перебирая закрытые ордера сравниваю ТП с ценой закрытия и если не далее Слиппажа - значит ТП состоялся. Сейчас в моде частичные закрытия и даже открытия, т.е. получаются в истории не один ордер с известным тикетом, а несколько (лично видел 3 шт.), поэтому Ваш алгоритм с сохранением тикета может выдать неожиданный результат.
Такой вопрос:
Нашел в сети индикатор ProFx_Strength_Oscillator, он привязан к DLL ProFx32.dll. В тестере стратегий индикатор гоняется нормально и бегло.
Захотел написать с ним советник и тут уже терминал просто начинает виснуть и тормозить при взятии данных c индюка раз в бар.
double ProFSO_Neutral1 = iCustom(NULL,0,"ProFx_Strength_Oscillator",ProFSO_Period1,ProFSO_Period2,ProFSO_Period3,PRICE_CLOSE,Indicators_BarCount,1,1);
После остановки тестера прошло 5 баров, и тут же на графике отображается 5 индикаторов, хотя должен один.
Никогда с таким не сталкивался при работе с iCustom...
Может быть проблема в DLL к которому этот индюк привязан?
Может быть проблема в DLL к которому этот индюк привязан?
Возможно - длл ведь ломаный, а может и др., причины.
Тоже впервые вижу. По идее длл не может контролировать терем - она про него ничего знать не должна и тем более запустить в тереме индюк повторно. Я знаю ты не любишь классы или здесь использовал? - может там задвоилось что-то.Может быть проблема в DLL к которому этот индюк привязан?
Я знаю ты не любишь классы или здесь использовал? - может там задвоилось что-то.
Ничего не использовал, все по старинке, никакого ООП.
Просто раз в свечу вызываю данные индикатора (код выше писал). Даже ничего с ними не делаю, просто вызов. Если вызов нескольких значений - сразу подгружается несколько раз )) Сколько пробовал сторонних индикаторов через iCustom - такое впервые. Грешу на dll, т.к. с ним раньше не присоединял их. Можешь сам попробовать, если время есть, индюк во вложении.
Господа, подскажите. Поставил совы на vps (windows server 2008 eng), одна сова не смогла рассчитать стоимость пункта (на домашнем работало без проблем)..... в другой почему то русские шрифты превратились в тыкву))), в третьей все нормально. Выбрал в настройках русский яз. везде где только можно, но все равно, в одной сове все нормально с буквами в настройках, в другой знаки вопроса и краказямбы......
функция определения цены пункта, ей передаем переменную _Symbol
double StoimPunkt(string B) //цена пункта для одного лота
{
RefreshRates();
double S=0;
if(MarketInfo(B,MODE_TICKVALUE)!=0 && MarketInfo(B,MODE_TICKSIZE)!=0 && MarketInfo(B,MODE_POINT)!=0)
{
S=MarketInfo(B,MODE_TICKVALUE)/(MarketInfo(B,MODE_TICKSIZE)/MarketInfo(B,MODE_POINT));
}
return(S);
}
Могут при первом запросе вернуть 0.
функция определения цены пункта, ей передаем переменную _Symbol
double StoimPunkt(string B) //цена пункта для одного лота
{
RefreshRates();
double S=0;
if(MarketInfo(B,MODE_TICKVALUE)!=0 && MarketInfo(B,MODE_TICKSIZE)!=0 && MarketInfo(B,MODE_POINT)!=0)
{
S=MarketInfo(B,MODE_TICKVALUE)/(MarketInfo(B,MODE_TICKSIZE)/MarketInfo(B,MODE_POINT));
}
return(S);
}
do { TickValue = MarketInfo(symb, MODE_TICKVALUE); } while(TickValue == 0);
Интересно, бывают ли случаи, чтобы оно и при повторных проверках тоже вернуло 0, и выполнение зациклилось?
Могут при первом запросе вернуть 0.
функция определения цены пункта, ей передаем переменную _Symbol
double StoimPunkt(string B) //цена пункта для одного лота
{
RefreshRates();
double S=0;
if(MarketInfo(B,MODE_TICKVALUE)!=0 && MarketInfo(B,MODE_TICKSIZE)!=0 && MarketInfo(B,MODE_POINT)!=0)
{
S=MarketInfo(B,MODE_TICKVALUE)/(MarketInfo(B,MODE_TICKSIZE)/MarketInfo(B,MODE_POINT));
}
return(S);
}
do { TickValue = MarketInfo(symb, MODE_TICKVALUE); } while(TickValue == 0);
Интересно, бывают ли случаи, чтобы оно и при повторных проверках тоже вернуло 0, и выполнение зациклилось?
Значит надо два раза спрашивать :)) Сервер глуховат. Спасибо.
Бывает на не подключенном тереме. Я бы в цикл Sleep и проверку IsStopped добавил.Интересно, бывают ли случаи, чтобы оно и при повторных проверках тоже вернуло 0, и выполнение зациклилось?
У меня такой общий код был.
До ошибки никогда не доходило, вроде бы.
double GetTickValue() {
double _TickValue;
int a=0;
do {
_TickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
a++;
if (_TickValue == 0) Sleep(500);
} while (_TickValue == 0 && a if (_TickValue == 0) { Print("TickValue Error"); return(0); }
return _TickValue;
}Добрый день!
Просмотрел второй урок и столкнулся со следующей проблемой. В случае определения МАКС и МИН перебирая 10 баров не происходит сброса. Т.е. если к примеру запустить данного советника в тестер то он запоминает последний хай и минимум и будет ставить ордера только в случае если будет превышение последнего определенного хая и мин..
Как написать так чтобы к примеру каждый новый день в 11 часов он сбрасывал вчерашний результат и определял новый пересчитывая указанное последнее кол-во баров.
вод код советника на писаного во втором уроке:
extern int BarCount = 10;
extern int HourStart = 11;
extern double Lots = 0.01;
extern int StopLoss = 300;
extern int TakeProfit = 200;
extern int Magic = 12345;
double minprice = 999999,
maxprice = -999999,
mp, SL, TP;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
GetMaxPrice();
GetMinPrice();
if(TimeHour(TimeCurrent()) == HourStart)
{
if (BuyLimitCount() == 0 && BuyCount() == 0)
{
SL = NormalizeDouble(minprice - StopLoss*Point, 5);
TP = NormalizeDouble(minprice + TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_BUYLIMIT, Lots, minprice, 3, SL, TP, "", Magic, 0, Blue);
if(ticket Print("Не удалось открыть ордер");
}
if (SellLimitCount() == 0 && SellCount() == 0)
{
SL = NormalizeDouble(maxprice + StopLoss*Point, 5);
TP = NormalizeDouble(maxprice - TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_SELLLIMIT, Lots, maxprice, 3, SL, TP, "", Magic, 0, Red);
if(ticket Print("Не удалось открыть ордер");
}
}
Comment("Maxprice:" +DoubleToStr(maxprice, 5) + "\n"+
"Minprice:" +DoubleToStr(minprice, 5));
}
//+------------------------------------------------------------------+
int BuyLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUYLIMIT)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int SellLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELLLIMIT)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int BuyCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUY)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int SellCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELL)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
void GetMinPrice()
{
for(int i=0; i {
mp = iLow(Symbol(), PERIOD_CURRENT, i);
if(mp minprice=mp;
}
return;
}
//+------------------------------------------------------------------+
void GetMaxPrice()
{
for(int i=0; i {
mp = iHigh(Symbol(), PERIOD_CURRENT, i);
if(mp > maxprice)
maxprice=mp;
}
return;
}
Изменено 4 ноября, 2018 пользователем 0ll
Добрый день!
Просмотрел второй урок и столкнулся со следующей проблемой. В случае определения МАКС и МИН перебирая 10 баров не происходит сброса. Т.е. если к примеру запустить данного советника в тестер то он запоминает последний хай и минимум и будет ставить ордера только в случае если будет превышение последнего определенного хая и мин..
Как написать так чтобы к примеру каждый новый день в 11 часов он сбрасывал вчерашний результат и определял новый пересчитывая указанное последнее кол-во баров.
вод код советника на писаного во втором уроке:
extern int BarCount = 10;
extern int HourStart = 11;
extern double Lots = 0.01;
extern int StopLoss = 300;
extern int TakeProfit = 200;
extern int Magic = 12345;
double minprice = 999999,
maxprice = -999999,
mp, SL, TP;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
GetMaxPrice(); для чего вызывать здесь эту функцию?
GetMinPrice(); для чего вызывать здесь эту функцию?
if(TimeHour(TimeCurrent()) == HourStart)
{
if (BuyLimitCount() == 0 && BuyCount() == 0)
{
SL = NormalizeDouble(minprice - StopLoss*Point, 5);
TP = NormalizeDouble(minprice + TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_BUYLIMIT, Lots, minprice, 3, SL, TP, "", Magic, 0, Blue);
if(ticket Print("Не удалось открыть ордер");
}
if (SellLimitCount() == 0 && SellCount() == 0)
{
SL = NormalizeDouble(maxprice + StopLoss*Point, 5);
TP = NormalizeDouble(maxprice - TakeProfit*Point, 5);
ticket = OrderSend(Symbol(), OP_SELLLIMIT, Lots, maxprice, 3, SL, TP, "", Magic, 0, Red);
if(ticket Print("Не удалось открыть ордер");
}
}
Comment("Maxprice:" +DoubleToStr(maxprice, 5) + "\n"+
"Minprice:" +DoubleToStr(minprice, 5));
}
//+------------------------------------------------------------------+
int BuyLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUYLIMIT)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int SellLimitCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELLLIMIT)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int BuyCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_BUY)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int SellCount()
{
int count = 0;
for(int i=OrdersTotal()-1; i>=0; i--)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true &&
OrderMagicNumber() == Magic &&
OrderType() == OP_SELL)
{
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
void GetMinPrice()
{
for(int i=0; i {
mp = iLow(Symbol(), PERIOD_CURRENT, i);
if(mp minprice=mp;
}
return;
}
//+------------------------------------------------------------------+
void GetMaxPrice()
{
for(int i=0; i {
mp = iHigh(Symbol(), PERIOD_CURRENT, i);
if(mp > maxprice)
maxprice=mp;
}
return;
}
У вас функции GetMaxPrice() и GetMinPrice() типа void, а надо double, чтобы они возвращали значение цены. И когда хотите открыть ордер, вызовите эту функцию.
например:
double price_open = GetMinPrice();
SL = NormalizeDouble(
TP = NormalizeDouble(
ticket = OrderSend(Symbol(), OP_BUYLIMIT, Lots,
Comment("Maxprice:" +DoubleToStr(
"Minprice:" +DoubleToStr(
Вот пример функции GetMaxPrice()
double GetMaxPrice() // Функция для определения максимальной цены за n баров
{
double maxprice = -99999;
for (int i=BarCount-1; i>=0; i--)
{
double mp = iHigh(Symbol(), PERIOD_CURRENT, i);
if(mp > maxprice)
maxprice = mp;
MaxPrice = maxprice;
}
return(MaxPrice); //что вернет функция
}
Изменено 3 ноября, 2018 пользователем Sergey Forex
Для публикации сообщений создайте учётную запись или авторизуйтесь
Перейти к списку тем