Veuillez m'aider à le corriger. Dans le Strategy Tester tout fonctionne parfaitement, mais sur la démo RTS sur m1 parfois au lieu d'une position de 3 lots il envoie 2 ordres de 3 lots chacun, et la position totale de 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; //сбросим семафор, операция с ордером завершаена, можно открывать следующий ордер
}
}
Il s'agit probablement d'un bogue) Lors du démarrage de MT5, contrairement à MT4, lors du démarrage sans connexion à un serveur, la dernière autorisation (login/mot de passe) n'est pas chargée pour une raison quelconque et doit être autorisée à nouveau, le mot de passe et le login ne sont pas sauvegardés dans ce cas. Quel pourrait être le problème ?
C'est ce que la technique est venue à- différents profits au même moment sur le même compte (c'était un jour de congé, les cotations, les prix d'entrée, les swaps - coïncident, seulement le profit ne coïncide pas)
La seule différence est que dans la première image, le terminal est connecté via le mot de passe d'investissement et l'optimisation est en cours ; la deuxième image montre la connexion via le mot de passe de transaction. Et même après avoir redémarré et mis à jour le terminal, tout est resté pareil. Quand les citations sont arrivées, tout semblait être normalisé
Voilà où en est la technique - différents profits au même moment sur le même compte (c'était un jour de congé, les cotations, les prix d'entrée, les swaps - coïncident, seul le profit ne coïncide pas).
La seule différence est que dans la première image, le terminal est connecté via le mot de passe d'investissement et l'optimisation est en cours ; la deuxième image montre la connexion via le mot de passe de transaction. Et même après avoir redémarré et mis à jour le terminal, tout est resté pareil. Quand les citations sont arrivées, tout semblait être normalisé
Apparemment, les taux croisésdisponibles pour le terminal pour le calcul du bénéfice flottant étaient différents.
Rosh: Apparemment, les taux croisésdont disposait le terminal pour calculer les bénéfices flottants étaient différents.
Cela m'est arrivé une fois et ne se reproduira peut-être plus. C'est-à-dire qu'il n'est pas du tout critique. C'est pourquoi je n'ai pas écrit au Service Desk. Je veux juste que vous sachiez que la procédure de calcul des profits et des pertes n'est pas parfaite (pourquoi les taux croisés sont-ils différents, par exemple ?).
Transmettre différents paramètres d'entrée. Le symbole, la période, les paramètres d'entrée sont les mêmes, l'indicateur est le même. Le terminal essaie de minimiser la consommation de ressources et dans ce cas, une nouvelle copie de l'indicateur n'est pas créée, c'est-à-dire qu'un seul programme mql5 fonctionne réellement.
Je comprends et je me souviens de l'optimisation de la consommation des ressources, mais peut-être qu'en plus du symbole, de la période, des paramètres d'entrée, nous devrions également vérifier le nom court de l'indicateur? Si le programmeur définit clairement un nom court unique, il comprend ce qu'il fait, et il a besoin d'une copie séparée, même si cet indicateur existe déjà dans le graphique. Par exemple, l'indicateur n'a aucune donnée d'entrée, il calcule automatiquement toutes les données initiales au stade initial, mais nous devons obliger l'utilisateur à entrer un faux paramètre et à s'en souvenir pour ne pas l'entrer dans un autre.
//+------------------------------------------------------------------+//| ClassEx.mq5 |//| Copyright 2013, MetaQuotes Software Corp. |//| http://www.mql5.com |//+------------------------------------------------------------------+#property copyright "Copyright 2013, MetaQuotes Software Corp."#property link "http://www.mql5.com"#property version "1.00"//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+class CClass1
{
public:
CClass1(void){};
CClass1(int i){};
};
class CClass2 : public CClass1
{
//public:// CClass2();
};
voidOnStart()
{
//---
CClass1 lCC1(0);
// CClass2 lCC2(0);
}
//+------------------------------------------------------------------+
Bonjour !
Si je supprime le commentaire //CClass2, j'obtiens une erreur "wrong parameters count".
La question a déjà été posée ici, mais le sujet s'est approfondi dans une autre direction. Ma question est la suivante. Je m'attends à ce que CClass2 lCC2(0), appelle le constructeur de la classe de base. Cela n'a pas l'air de se produire. Quel est le problème ?
Si vous n'avez pas de compte, veuillez vous inscrire
Autorisez l'utilisation de cookies pour vous connecter au site Web MQL5.com.
Veuillez activer les paramètres nécessaires dans votre navigateur, sinon vous ne pourrez pas vous connecter.
Vous êtes connecté. L'authentification à deux facteurs a été désactivée. Configurez-la à nouveau et scannez un nouveau code QR, ou continuez avec l'authentification à deux facteurs désactivée.
Veuillez m'aider à le corriger. Dans le Strategy Tester tout fonctionne parfaitement, mais sur la démo RTS sur m1 parfois au lieu d'une position de 3 lots il envoie 2 ordres de 3 lots chacun, et la position totale de 6 lots.
C'est ce que la technique est venue à
- différents profits au même moment sur le même compte (c'était un jour de congé, les cotations, les prix d'entrée, les swaps - coïncident, seulement le profit ne coïncide pas)
La seule différence est que dans la première image, le terminal est connecté via le mot de passe d'investissement et l'optimisation est en cours ; la deuxième image montre la connexion via le mot de passe de transaction. Et même après avoir redémarré et mis à jour le terminal, tout est resté pareil. Quand les citations sont arrivées, tout semblait être normalisé
Voilà où en est la technique - différents profits au même moment sur le même compte (c'était un jour de congé, les cotations, les prix d'entrée, les swaps - coïncident, seul le profit ne coïncide pas).
La seule différence est que dans la première image, le terminal est connecté via le mot de passe d'investissement et l'optimisation est en cours ; la deuxième image montre la connexion via le mot de passe de transaction. Et même après avoir redémarré et mis à jour le terminal, tout est resté pareil. Quand les citations sont arrivées, tout semblait être normalisé
Apparemment, les taux croisés dont disposait le terminal pour calculer les bénéfices flottants étaient différents.
Toutes les deux minutes, il envoie cette "série" d'erreurs sur le signal de trading. Comment le réparer ?
Transmettre différents paramètres d'entrée. Le symbole, la période, les paramètres d'entrée sont les mêmes, l'indicateur est le même. Le terminal essaie de minimiser la consommation de ressources et dans ce cas, une nouvelle copie de l'indicateur n'est pas créée, c'est-à-dire qu'un seul programme mql5 fonctionne réellement.
Bonjour !
Si je supprime le commentaire //CClass2, j'obtiens une erreur "wrong parameters count".
La question a déjà été posée ici, mais le sujet s'est approfondi dans une autre direction. Ma question est la suivante. Je m'attends à ce que CClass2 lCC2(0), appelle le constructeur de la classe de base. Cela n'a pas l'air de se produire. Quel est le problème ?
Merci ! !!