Übertragen Sie verschiedene Eingabeparameter. Symbol, Periode, Eingabeparameter sind gleich, der Indikator ist gleich. Das Terminal versucht, den Ressourcenverbrauch zu minimieren, und in diesem Fall wird keine neue Kopie des Indikators erstellt, d.h. ein mql5-Programm funktioniert tatsächlich.
Bitte helfen Sie mir, dies zu korrigieren. Im Strategy Tester funktioniert alles perfekt, aber in der RTS-Demo auf m1 werden manchmal statt einer Position von 3 Lots 2 Orders von je 3 Lots gesendet, und die Gesamtposition beträgt 6 Lots.
#property copyright "Copyright 2013, DKeN"#property link ""#property version "1.00"/*
1 Название: Параболик
2 Терминал: МТ5
3 Рабочий инструмент: любой инструмент и период
4 Индикатор: параболик
5 Правила:
при пересечение входим в направлении пересечения по рынку ,
профит делим на 3 части , при закрытие первого выставляем стоп в ноль или чуть в плюс,
если профит не достигнут, а цена ушла в минус переворачиваем позицию при пересечении параболика…
6 второй вариант: при пересечение входим в направлении пересечения по рынку , профит делим на 2 части , при закрытие первой части вторую оставляем до пересечения параболика
7 настройки: а) к-во лотов
б) индикатор
в) время работы
8. возможность работы по нескольким инструментам на одном счете
если торгуем на РТС необходимо строго со спецификацией инструмента данные задавать!
*/inputstring comment="";
//комментарий к ордеруinputint slippage=10;
//проскальзываниеinputdouble lot=3;
//рабочий лот позицииinputint takeprofit=200;
//тейк профит основной позицииinputint stoploss=1000;
//стоп лосс основной позицииinputint mode=1;
/*режим выхода 1 или 2*/inputint takeprofit1=100;
//точка закрытия первой части профита в пунктахinputdouble lot1=1;
//объем закрываемой части ордераinputdouble bu1=10;
//для режима 1, пренос в безубыток +1inputint takeprofit2=150;
//точка закрытия второй части профита в пунктахinputdouble lot2=1;
//объем закрываемой позицииinputENUM_TIMEFRAMES tf=0;
//период, 0 - по умолчанию с графика текущийinputdouble step=0.02;
inputdouble maximum=0.2;
//настрйоки для сар step,maximuminputstring times="00:00-24:00";
//поддерживаются интервалы через , например 00:00-12:00, 16:00-20:00 и т.д. поддержка ночного перехода например 22:00-05:00//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+int psar=-1;
ulong semafor=0;
intOnInit()
{
//---
psar=iSAR(NULL,tf,step,maximum);
if(psar==INVALID_HANDLE){
PrintFormat("Не удалось создать хэндл индикатора iSAR для пары %s/%s, код ошибки %d", _Symbol, EnumToString(_Period),GetLastError());
return (-1);
}
semafor=0;
//---return(0);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//---if(psar!=INVALID_HANDLE) IndicatorRelease(psar);
Comment("");
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
//---bool bWork=time_check(times);
Comment("Торговый интервал времени");
if(!bWork)Comment("Неторговый интервал времени. Разрешено закрытие по обратному сигналу и частичное закрытие. Открытие новых сделок запрещено.");
double sar[],dLot,open,stop,take;
ENUM_POSITION_TYPE type;
ArraySetAsSeries(sar,true);
string n=_Symbol;
if(CopyBuffer(psar,0,0,2,sar)>=0){
//1 - предыдущее значение//0 - текущий барMqlRates rates[];
MqlTick tick;
ArraySetAsSeries(rates,true);
int op=0;
if(CopyRates(NULL,tf,0,2,rates)>0){
if(SymbolInfoTick(n,tick)){
if(tick.bid<sar[1] && sar[1]<rates[0].open) op=-1;
elseif(tick.ask>sar[1] && sar[1]>rates[0].open) op=1;
}
//првоерим если позиции в рынке нет, попробуем открыть по сигналуif(!PositionSelect(n)) {
order_OrderDeleteAll(n); //удалим отложкиif(op==0) return; //сигнала нет! if(bWork){
if(op==1) order_OrderSend(n,ORDER_TYPE_BUY,lot,0,stoploss,takeprofit,comment);
if(op==-1) order_OrderSend(n,ORDER_TYPE_SELL,lot,0,stoploss,takeprofit,comment);
}
}else{
type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
dLot=PositionGetDouble(POSITION_VOLUME);
if(dLot==lot){
int orders[];
int all=order_OrdersTotal(n,orders);
open=PositionGetDouble(POSITION_PRICE_OPEN);
if(type==POSITION_TYPE_BUY && orders[ORDER_TYPE_SELL_LIMIT]==0){
if(mode==2 || mode==1)order_OrderSend(n,ORDER_TYPE_SELL_LIMIT,lot1,open+takeprofit1*_Point,0,0,"");
if(mode==1)order_OrderSend(n,ORDER_TYPE_SELL_LIMIT,lot2,open+takeprofit2*_Point,0,0,"");
}
if(type==POSITION_TYPE_SELL && orders[ORDER_TYPE_BUY_LIMIT]==0){
if(mode==2 || mode==1)order_OrderSend(n,ORDER_TYPE_BUY_LIMIT,lot1,open-takeprofit1*_Point,0,0,"");
if(mode==1)order_OrderSend(n,ORDER_TYPE_BUY_LIMIT,lot2,open-takeprofit2*_Point,0,0,"");
}
}elseif(dLot<lot && mode==1){
open=PositionGetDouble(POSITION_PRICE_OPEN);
stop=PositionGetDouble(POSITION_SL);
take=PositionGetDouble(POSITION_TP);
if(type==POSITION_TYPE_BUY && (stop<open || stop==0.0)) order_OrderModify(n,open+bu1*_Point,take);
if(type==POSITION_TYPE_SELL && (stop>open || stop==0.0)) order_OrderModify(n,open-bu1*_Point,take);
}
//Print(GetLastError()," op=",op," type=",type); if(op==0) return;
//позиция к этому моменту могла быть уже закрыта, перепроверим и проверим ее лот и типif(PositionSelect(n)){
type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
dLot=PositionGetDouble(POSITION_VOLUME);
//осуществим переворот, да так чтобы закрыть остаток и открыть начальным лотомif(type==POSITION_TYPE_BUY && op==-1) {
order_OrderDeleteAll(n); //удалим отложки
order_OrderSend(n,ORDER_TYPE_SELL,dLot,0,0,0,comment);
}elseif(type==POSITION_TYPE_SELL && op==1) {
order_OrderDeleteAll(n); //удалим отложки
order_OrderSend(n,ORDER_TYPE_BUY,dLot,0,0,0,comment);
}
}
}
}
}
}
//+------------------------------------------------------------------+bool order_OrderModify(string name,double sl,double tp){
/*
SL & TP Modification
Торговый приказ на модификацию уровней StopLoss и/или TakeProfit. Требуется указание 4 полей:
action
symbol
sl
tp
*/MqlTradeRequest rq={0}; // структура запросаMqlTradeResult rs={0};
rq.action=TRADE_ACTION_SLTP;
rq.symbol=name;
rq.sl=sl;
rq.tp=tp;
return (OrderSend(rq,rs));
}
bool order_OrderSend(string name,ENUM_ORDER_TYPE type,double dlot,double open,double sl,double tp,string cmt){
MqlTradeRequest rq={0}; // структура запросаMqlTradeResult rs={0};
MqlTick tick={0};
MqlTradeCheckResult cr={0};
if(PositionSelect(name)) semafor=0;
if(semafor>0) return (false);
if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_SELL){
rq.action=TRADE_ACTION_DEAL;
rq.symbol=name;
rq.volume=NLot(name,dlot);
rq.type=type;
bool ntick=SymbolInfoTick(name,tick);
if(open<=0){
if(type==ORDER_TYPE_BUY) rq.price=tick.ask;
elseif(type==ORDER_TYPE_SELL) rq.price=tick.bid;
}else{
rq.price=open; //если цена указана явно, то откроем по цене+проскальзывание
}
rq.sl=0;
rq.tp=0;
//выставим стопif(sl>0 && type==ORDER_TYPE_BUY) rq.sl=NormalizeDouble(rq.price-sl*_Point,_Digits);
elseif(sl>0 && type==ORDER_TYPE_SELL) rq.sl=NormalizeDouble(rq.price+sl*_Point,_Digits);
//выставим тейкif(tp>0 && type==ORDER_TYPE_BUY) rq.tp=NormalizeDouble(rq.price+tp*_Point,_Digits);
elseif(tp>0 && type==ORDER_TYPE_SELL) rq.tp=NormalizeDouble(rq.price-tp*_Point,_Digits);
rq.deviation=slippage;//допустимое проскальзывание
rq.type_filling=ORDER_FILLING_FOK;
rq.comment=cmt;
}else{
rq.action=TRADE_ACTION_PENDING;
rq.symbol=name;
rq.volume=NLot(name,dlot);
rq.type=type;
rq.deviation=slippage;//допустимое проскальзывание
rq.type_time=ORDER_TIME_DAY;
//ORDER_TIME_GTC; //ордер будет до снятия его программно или вручную//bool ntick=SymbolInfoTick(name,tick);
rq.price=open;
rq.sl=sl; //должна быть ценой!
rq.tp=tp;
rq.type_filling=ORDER_FILLING_RETURN;
rq.comment=cmt;
}
if(OrderCheck(rq,cr)){
if(OrderSend(rq,rs)){
if(rs.retcode!=TRADE_RETCODE_DONE && rs.retcode!=TRADE_RETCODE_PLACED){
Comment("Debug: order_OrderSend(retcode=",ResultRetcodeDescription(cr.retcode),")");
}
semafor=rs.deal;
if(rs.retcode==TRADE_RETCODE_DONE || rs.retcode==TRADE_RETCODE_PLACED){
if(type==ORDER_TYPE_BUY || type==ORDER_TYPE_SELL){
rq.action= TRADE_ACTION_SLTP;
rq.order= rs.order;
return (OrderSend(rq,rs));
}
}
return (true);
}
}else{
semafor=0;
Comment("Debug: order_OrderSend(retcode=",ResultRetcodeDescription(cr.retcode),")");
}
return (false);
}
/*удаляет отложки*/bool order_OrderDeleteAll(string name){
ulong ticket;
MqlTradeRequest rq={0};
MqlTradeResult rs={0};
for(int i=OrdersTotal()-1;i>=0;i--){
if((ticket=OrderGetTicket(i))>0){
ZeroMemory(rq);
ZeroMemory(rs);
rq.action=TRADE_ACTION_REMOVE;
rq.order=ticket;
OrderSend(rq,rs);
}
}
return (false);
}
int order_OrdersTotal(string name,int &orders[]){
ulong ticket;
int total=0;
ArrayResize(orders,10,0);
ArrayInitialize(orders,0);
//--- пройдем по всем отложенным ордерамfor(int i=OrdersTotal()-1;i>=0;i--)
if((ticket=OrderGetTicket(i))>0)
if(OrderGetString(ORDER_SYMBOL)==name){
orders[(int)OrderGetInteger(ORDER_TYPE)]++;
total++;
}
//---return(total);
}
//+------------------------------------------------------------------+ //| возврат стрингового результата торговой операции по его коду | //+------------------------------------------------------------------+ string ResultRetcodeDescription(int retcode)
{
string str;
//---- switch(retcode)
{
caseTRADE_RETCODE_REQUOTE: str="Реквота"; break;
caseTRADE_RETCODE_REJECT: str="Запрос отвергнут"; break;
caseTRADE_RETCODE_CANCEL: str="Запрос отменен трейдером"; break;
caseTRADE_RETCODE_PLACED: str="Ордер размещен"; break;
caseTRADE_RETCODE_DONE: str="Заявка выполнена"; break;
caseTRADE_RETCODE_DONE_PARTIAL: str="Заявка выполнена частично"; break;
caseTRADE_RETCODE_ERROR: str="Ошибка обработки запроса"; break;
caseTRADE_RETCODE_TIMEOUT: str="Запрос отменен по истечению времени";break;
caseTRADE_RETCODE_INVALID: str="Неправильный запрос"; break;
caseTRADE_RETCODE_INVALID_VOLUME: str="Неправильный объем в запросе"; break;
caseTRADE_RETCODE_INVALID_PRICE: str="Неправильная цена в запросе"; break;
caseTRADE_RETCODE_INVALID_STOPS: str="Неправильные стопы в запросе"; break;
caseTRADE_RETCODE_TRADE_DISABLED: str="Торговля запрещена"; break;
caseTRADE_RETCODE_MARKET_CLOSED: str="Рынок закрыт"; break;
caseTRADE_RETCODE_NO_MONEY: str="Нет достаточных денежных средств для выполнения запроса"; break;
caseTRADE_RETCODE_PRICE_CHANGED: str="Цены изменились"; break;
caseTRADE_RETCODE_PRICE_OFF: str="Отсутствуют котировки для обработки запроса"; break;
caseTRADE_RETCODE_INVALID_EXPIRATION: str="Неверная дата истечения ордера в запросе"; break;
caseTRADE_RETCODE_ORDER_CHANGED: str="Состояние ордера изменилось"; break;
caseTRADE_RETCODE_TOO_MANY_REQUESTS: str="Слишком частые запросы"; break;
caseTRADE_RETCODE_NO_CHANGES: str="В запросе нет изменений"; break;
caseTRADE_RETCODE_SERVER_DISABLES_AT: str="Автотрейдинг запрещен сервером"; break;
caseTRADE_RETCODE_CLIENT_DISABLES_AT: str="Автотрейдинг запрещен клиентским терминалом"; break;
caseTRADE_RETCODE_LOCKED: str="Запрос заблокирован для обработки"; break;
caseTRADE_RETCODE_FROZEN: str="Ордер или позиция заморожены"; break;
caseTRADE_RETCODE_INVALID_FILL: str="Указан неподдерживаемый тип исполнения ордера по остатку "; break;
caseTRADE_RETCODE_CONNECTION: str="Нет соединения с торговым сервером"; break;
caseTRADE_RETCODE_ONLY_REAL: str="Операция разрешена только для реальных счетов"; break;
caseTRADE_RETCODE_LIMIT_ORDERS: str="Достигнут лимит на количество отложенных ордеров"; break;
caseTRADE_RETCODE_LIMIT_VOLUME: str="Достигнут лимит на объем ордеров и позиций для данного символа"; break;
default: str="Неизвестный результат";
}
//---- return(str);
}
double NLot(string name,double dlot){
double stepLot=SymbolInfoDouble(name,SYMBOL_VOLUME_STEP);
return (MathFloor(dlot/stepLot)*stepLot);
}
bool time_check(string timeList){
//разделим строку на подстроки (разделитель , )ushort usep1=StringGetCharacter(",",0);
ushort usep2=StringGetCharacter("-",0);
ushort usep3=StringGetCharacter(":",0);
string param[],param2[],param3[],param4[];
long start_hour=0,start_minute=0,start_seconds=0;
long end_hour=0,end_minute=0,end_seconds=0;
datetime start_tm=0,end_tm=0,tm[];
ArrayInitialize(tm,0);
ArraySetAsSeries(tm,true);
CopyTime(_Symbol,PERIOD_D1,0,2,tm);
MqlDateTime dt={0};
TimeToStruct(TimeCurrent(),dt);
int c=StringSplit(timeList,usep1,param);
if(c<0) return (true);//диапозон не задан, можно торговать весь деньfor(int i=0;i<c;i++){
StringTrimRight(param[i]);
StringTrimLeft(param[i]);
if(StringSplit(param[i],usep2,param2)==2){
StringTrimRight(param2[0]);
StringTrimLeft(param2[0]);
StringTrimRight(param2[1]);
StringTrimLeft(param2[1]);
//удалили возможные лишние пробелы, теперь у нас есть время начала и окончания//разделим на чч.мм.ссif(StringSplit(param2[0],usep3,param3)>=1){
//время начала
start_hour=StringToInteger(param3[0]);
if(ArraySize(param3)>=2) start_minute=StringToInteger(param3[1]);
if(ArraySize(param3)==3) start_seconds=StringToInteger(param3[2]);
}
if(StringSplit(param2[1],usep3,param4)>=1){
//время окончания
end_hour=StringToInteger(param4[0]);
if(ArraySize(param4)>=2) end_minute=StringToInteger(param4[1]);
if(ArraySize(param4)==3) end_seconds=StringToInteger(param4[2]);
}
if(start_hour<=end_hour){
start_tm=(datetime)(tm[0]+start_hour*3600+start_minute*60+start_seconds);
end_tm=(datetime)(tm[0]+end_hour*3600+end_minute*60+end_seconds);
}else{
if(dt.hour>=0 && dt.hour<start_hour){
start_tm=(datetime)(tm[1]+start_hour*3600+start_minute*60+start_seconds);
end_tm=(datetime)(tm[0]+end_hour*3600+end_minute*60+end_seconds);
}
if(dt.hour>0 && dt.hour>=start_hour){
start_tm=(datetime)(tm[0]+start_hour*3600+start_minute*60+start_seconds);
end_tm=(datetime)(tm[0]+24*3600+end_hour*3600+end_minute*60+end_seconds);
}
}
if(TimeCurrent()>=start_tm && TimeCurrent()<=end_tm) return (true);
}
}
return (false);
}
voidOnTrade(){
if(semafor>0){
PrintFormat("Открыт ордер %d",semafor);
semafor=0; //сбросим семафор, операция с ордером завершаена, можно открывать следующий ордер
}
}
Möglicherweise handelt es sich um einen Fehler) Beim Start von MT5 wird, anders als bei MT4, beim Start ohne Verbindung zu einem Server die letzte Autorisierung (Login/Passwort) aus irgendeinem Grund nicht geladen und muss erneut autorisiert werden, Passwort und Login werden in diesem Fall nicht gespeichert. Was könnte das Problem sein?
Dies ist, was die Technik zu gekommen ist - verschiedene Gewinne zur gleichen Zeit auf dem gleichen Konto (es war ein Tag aus, Notierungen, Einstiegspreise, Swaps - übereinstimmen, nur der Gewinn nicht übereinstimmen)
Der einzige Unterschied besteht darin, dass im ersten Bild das Terminal über das Investitionspasswort angemeldet ist und die Optimierung läuft, während im zweiten Bild die Anmeldung über das Handelspasswort erfolgt. Und auch nach dem Neustart und der Aktualisierung des Terminals blieb alles beim Alten. Als die Zitate eintrafen, schien alles normalisiert zu sein
Dies ist, was die Technik zu kommen - unterschiedliche Gewinne zur gleichen Zeit auf dem gleichen Konto (es war ein Tag aus, Notierungen, Einstiegspreise, Swaps - übereinstimmen, nur der Gewinn nicht übereinstimmen)
Der einzige Unterschied besteht darin, dass im ersten Bild das Terminal über das Investitionspasswort angemeldet ist und die Optimierung läuft, während im zweiten Bild die Anmeldung über das Handelspasswort erfolgt. Und auch nach dem Neustart und der Aktualisierung des Terminals blieb alles beim Alten. Als die Zitate eintrafen, schien alles normalisiert zu sein
Offenbar waren die für das Terminal verfügbaren Cross Rates zur Berechnung des gleitenden Gewinns unterschiedlich.
Rosh: Offensichtlich standen dem Terminal für die Berechnung der gleitenden Gewinne unterschiedliche Cross Rates zur Verfügung .
Das ist mir einmal passiert und darf nicht wieder passieren. Das heißt, sie ist überhaupt nicht kritisch. Deshalb habe ich mich auch nicht an den Service Desk gewandt. Ich möchte nur, dass Sie wissen, dass das Verfahren der Gewinn-/Verlustberechnung nicht perfekt ist (warum sind z.B. die Quersätze unterschiedlich?).
Übertragen Sie verschiedene Eingabeparameter. Symbol, Periode, Eingabeparameter sind gleich, der Indikator ist derselbe. Das Terminal versucht, den Ressourcenverbrauch zu minimieren, und in diesem Fall wird keine neue Kopie des Indikators erstellt, d.h. ein mql5-Programm arbeitet tatsächlich.
Ich verstehe und erinnere mich an die Optimierung des Ressourcenverbrauchs, aber vielleicht sollten wir neben dem Symbol, der Periode und den Eingabeparametern auch die Kurzbezeichnung des Indikators überprüfen? Wenn der Programmierer einen eindeutigen Kurznamen festlegt, versteht er, was er tut, und er braucht eine separate Kopie, auch wenn dieser Indikator bereits im Diagramm vorhanden ist. Zum Beispiel hat der Indikator überhaupt keine Eingabedaten, er berechnet alle Anfangsdaten automatisch in der Anfangsphase, aber wir müssen den Benutzer zwingen, einen falschen Parameter einzugeben und sich diesen zu merken, um ihn nicht in einen anderen einzugeben.
Übertragen Sie verschiedene Eingabeparameter. Symbol, Periode, Eingabeparameter sind gleich, der Indikator ist gleich. Das Terminal versucht, den Ressourcenverbrauch zu minimieren, und in diesem Fall wird keine neue Kopie des Indikators erstellt, d.h. ein mql5-Programm funktioniert tatsächlich.
Bitte geben Sie auch zu dieser einfachen Frage Ratschläge: https://www.mql5.com/ru/forum/1111/page975#comment_469324 , denn niemand weiß es. )))
Bitte helfen Sie mir, dies zu korrigieren. Im Strategy Tester funktioniert alles perfekt, aber in der RTS-Demo auf m1 werden manchmal statt einer Position von 3 Lots 2 Orders von je 3 Lots gesendet, und die Gesamtposition beträgt 6 Lots.
Dies ist, was die Technik zu
gekommen ist - verschiedene Gewinne zur gleichen Zeit auf dem gleichen Konto (es war ein Tag aus, Notierungen, Einstiegspreise, Swaps - übereinstimmen, nur der Gewinn nicht übereinstimmen)
Der einzige Unterschied besteht darin, dass im ersten Bild das Terminal über das Investitionspasswort angemeldet ist und die Optimierung läuft, während im zweiten Bild die Anmeldung über das Handelspasswort erfolgt. Und auch nach dem Neustart und der Aktualisierung des Terminals blieb alles beim Alten. Als die Zitate eintrafen, schien alles normalisiert zu sein
Dies ist, was die Technik zu kommen - unterschiedliche Gewinne zur gleichen Zeit auf dem gleichen Konto (es war ein Tag aus, Notierungen, Einstiegspreise, Swaps - übereinstimmen, nur der Gewinn nicht übereinstimmen)
Der einzige Unterschied besteht darin, dass im ersten Bild das Terminal über das Investitionspasswort angemeldet ist und die Optimierung läuft, während im zweiten Bild die Anmeldung über das Handelspasswort erfolgt. Und auch nach dem Neustart und der Aktualisierung des Terminals blieb alles beim Alten. Als die Zitate eintrafen, schien alles normalisiert zu sein
Offensichtlich standen dem Terminal für die Berechnung der gleitenden Gewinne unterschiedliche Cross Rates zur Verfügung .
Alle zwei Minuten sendet es diesen "Satz" von Fehlern über das Handelssignal aus. Wie kann man das beheben?
Übertragen Sie verschiedene Eingabeparameter. Symbol, Periode, Eingabeparameter sind gleich, der Indikator ist derselbe. Das Terminal versucht, den Ressourcenverbrauch zu minimieren, und in diesem Fall wird keine neue Kopie des Indikators erstellt, d.h. ein mql5-Programm arbeitet tatsächlich.