Si j'exécute l'EA dans le testeur, je peux voir les quatre premières entrées dans les commentaires, si le testeur est à faible vitesse, et une pause est utilisée - tout est clair.
Je joins le fichier avec le code.
J'essaie maintenant de jouer avec la première condition et d'attribuer N_Caste = 1 aux positions qui remplissent cette condition ;
Pour faire suite aux messages ci-dessus - apprenez à l'EA à créer un tableau à deux dimensions, entrez-y les valeurs du ticket et du rang pour chaque position, au fur et à mesure que les positions s'ouvrent.
À l'avenir, lorsque des signaux ou des conditions se présenteront, les rangs des positions correspondantes changeront. C'est ainsi que j'envisage de gérer les positions.
Il y a un problème - je demande aux professionnels de réagir. Aidez-moi à traiter la suppression d'éléments d'un tableau.
Au fur et à mesure que les postes sont fermés, les élites s'accumulent dans le tableau, qui stocke le ticket et le rang d'un poste "mort" déjà fermé, comment le supprimer je ne sais pas.
L'opération sur les pp. 172-173 ne fonctionne pas.
Dans OnTick() à chaque chandelier, les positions sont ouvertes, leurs stops sont modifiés, leurs ticks sont entrés dans un tableau, et le rang zéro d'origine est assigné.
Au fur et à mesure que les arrêts se déclenchent, le tableau accumule des éléments inutiles. Pour plus de clarté, j'ai ajouté les commentaires nécessaires et tout est visible en ligne.
Le code est petit, donc je vais le poster ici et attacher le fichier aussi.
S'il te plaît, aide-moi à organiser le nettoyage du tableau.
//+------------------------------------------------------------------+//| Sower_1_6 |//| Sergei Voicehovskii |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Sergei Voicehovskii"#property link"https://www.mql5.com"#property version"1.00"//---#include <Trade\AccountInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\TerminalInfo.mqh>
#include <Trade\Trade.mqh>
#include <Arrays\ArrayInt.mqh>
//---
CAccountInfo m_account;
CDealInfo m_deal;
CHistoryOrderInfo m_history;
COrderInfo m_order;
CPositionInfo m_position;
CSymbolInfo m_symbol;
CTerminalInfo m_terminal;
CTrade m_trade;
CArrayInt m_array;
//---#define observations 2int Arr_Position[][observations];
int Array_Change[];
//--- input parametersinputint SL = 50;
inputint TP = 50;
inputdouble Lot = 0.01;
inputdouble InpCloseProfit_money = 5.0;
inputdouble InpCloseProfit_points = 50.0;
inputdouble InpCloseProfit_percent = 3.0;
inputulong InpDeviation = 10;
inputbool InpPrintLog = true;
inputbool InpCommentLog = true;
inputulong Magic = 557755;
//---int stoploss = SL;
int takeprofit = TP;
ulong slippage = InpDeviation;
datetime Time_OpenPos;
//+------------------------------------------------------------------+intOnInit()
{
//--- Обновляем данные
Refresh_Rates();
//--- Устанавливаем символ
m_symbol.Name(_Symbol);
//--- Устанавливаем Magic
m_trade.SetExpertMagicNumber(Magic);
//--- Определяем режим расчета маржи
m_trade.SetMarginMode();
//--- Определяем режим исполнения ордеров
m_trade.SetTypeFillingBySymbol(m_symbol.Name());
//--- Устанавливаем максимальное отклонение от запрашиваемой цены
m_trade.SetDeviationInPoints(slippage);
//---ArrayFree(Arr_Position);
//---//---return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- destroy timerEventKillTimer();
}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+voidOnTick()
{
if(Checking_NewBar())
{
//+---Открываем начальные позиции "свежего" бара
m_trade.Buy(0.01);
m_trade.Sell(0.01);
//+---Выставляем стопы начальных позиций
ModifySLTP_1_range(stoploss,takeprofit,Magic);
//+---Заполняем массив c тикет/кастой позиций int N = Array_Creating_Caste_Positions();
//+--- int R = ArrayRange(Arr_Position,0)-1;
if(R<30)R=0;else R=30;
int tic = Arr_Position[R][0];
if(m_position.SelectByTicket(tic))
Time_OpenPos = m_position.Time();
int P = PositionsTotal();
if(InpCommentLog){
Comment("Выводим данные \n""ticket: ",tic,"\n""Время открытия позиции: ",Time_OpenPos,"\n""Сколько элементов в массиве: ",R+1,"\n""Проверок тикета за проход: ",N,"\n""Ввсего открыто позиций: ",P,"\n"//"Время жизни позиции (стр): ",structura_time.year," год. ",structura_time.mon," мес. ",structura_time.day," дн. ",structura_time.hour," час. ",structura_time.min," мин. ",structura_time.sec," сек. \n"
);}
//---ArrayPrint(Arr_Position);
//---
}
//---
}
//+------------------------------------------------------------------+int Array_Creating_Caste_Positions()
{
int n = 0;
long ticket = 0;
bool new_pos = true;
//---Запись новых тикетов в массив позиций int All_Position = PositionsTotal();
int Array_Size = ArrayRange(Arr_Position,0);
//--- for(int i = 0; i < All_Position; i++)
{
if(m_position.SelectByIndex(i))
{
ticket = PositionGetInteger(POSITION_TICKET);
new_pos = true;
}
for(int e = 0; e < Array_Size; e++)
{
if(Arr_Position[e][0]==ticket)
{
new_pos = false;
n++;
break;
}
}
if(new_pos){
int New_Size = Array_Size+1;
ArrayResize(Arr_Position,New_Size,0);
Arr_Position[Array_Size][0] = (int)ticket;//Ticket
Arr_Position[Array_Size][1] = 0;//Number_Caste (0 = начальные позиции)
n++;}
}
//---Удаление из массива мёртвых тикетов
Array_Size = ArrayRange(Arr_Position,0);
All_Position = PositionsTotal();
//--- for(int e = 0; e < Array_Size; e++)
{
int tickt = Arr_Position[e][0];
bool dead_pos = true;
for(int i = 0; i < All_Position; i++)
{
if(m_position.SelectByIndex(i))
{
if(tickt == PositionGetInteger(POSITION_TICKET))
{
dead_pos = false;
n++;
break;
}
}
}
if(dead_pos)ArrayRemove(Arr_Position,e,2);
ArrayResize(Arr_Position,All_Position);
}
//--- return(n);
}
//+------------------------------------------------------------------+//Проверка на наличие нового бара//+------------------------------------------------------------------+bool Checking_NewBar()
{
//--- переменная для возврата функцииbool new_bar_opened = false;
//--- статическая переменная для хранения времени открытия последнего бара staticdatetime last_bar_time=0;
//--- если статическая переменная еще неинициализирована if(last_bar_time==0)
{
//--- это первый вызов, запишем время открытия и выйдем
last_bar_time=(datetime)SeriesInfoInteger(_Symbol,Period(),SERIES_LASTBAR_DATE);
if(InpPrintLog)
PrintFormat("Инициализировали переменную last_bar_time значением %s",TimeToString(last_bar_time));
}
//--- получим время открытия последнего бара по своему символу datetime curr_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);
//--- если время открытия текущего бара не совпадает с тем, что хранится в last_bar_time то открылся новый барif(curr_time!=last_bar_time)
{
new_bar_opened = true;
//--- запомним время открытия нового бара в статической переменной
last_bar_time=curr_time;
//--- выведем сообщение об этом событии if(InpPrintLog)
PrintFormat("На символе %s открылся новый бар в %s",_Symbol,TimeToString(TimeCurrent()));
}
return(new_bar_opened);
}
//+------------------------------------------------------------------+//Обновление котировок//+------------------------------------------------------------------+bool Refresh_Rates()
{
//--- refresh ratesif(!m_symbol.RefreshRates())
{
if(InpPrintLog)
Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
return(false);
}
//--- protection against the return value of "zero"if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
{
if(InpPrintLog)
Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
return(false);
}
//---return(true);
}
//+------------------------------------------------------------------+void ModifySLTP_1_range(int stplss,
int tkprfit,
ulong mgc)
{
double sl = 0.0,
tp = 0.0;
double slbuy = 0.0,
slsell = 0.0,
tpbuy = 0.0,
tpsell = 0.0;
Refresh_Rates();
if(stplss>0)
{
slbuy = m_symbol.Bid() - stplss*m_symbol.Point();
slsell = m_symbol.Ask() + stplss*m_symbol.Point();
}
if(tkprfit>0)
{
tpbuy = m_symbol.Bid() + tkprfit*m_symbol.Point();
tpsell = m_symbol.Ask() - tkprfit*m_symbol.Point();
}
for(int i=PositionsTotal()-1;i>=0;i--)
{
if(m_position.SelectByIndex(i))
{
if(m_position.Symbol()==Symbol())
{
if(m_position.Magic() == mgc)
{
if(m_position.PositionType()==POSITION_TYPE_BUY)
{
sl = m_position.StopLoss() > 0 ? m_position.StopLoss() : slbuy;
tp = m_position.TakeProfit() > 0 ? m_position.TakeProfit() : tpbuy;
m_trade.PositionModify(m_position.Ticket(),NormalizeDouble(sl,Digits()),NormalizeDouble(tp,Digits()));
}
if(m_position.PositionType()==POSITION_TYPE_SELL)
{
sl = m_position.StopLoss() > 0 ? m_position.StopLoss() : slsell;
tp = m_position.TakeProfit() > 0 ? m_position.TakeProfit() : tpsell;
m_trade.PositionModify(m_position.Ticket(),NormalizeDouble(sl,Digits()),NormalizeDouble(tp,Digits()));
}
}
}
}
}
}
//+------------------------------------------------------------------+
Pour la clarté du processus, il est préférable de mettre StLoss 0, TProf doit rester 50, et l'EA doit être placé sur le graphique horaire de n'importe quelle devise. C'est dans le testeur.
Sur la démo d'Onlan, bien sûr, les minutes sont meilleures.
Pour la clarté du processus, il est préférable de mettre StLoss 0, TProf doit rester 50, et l'EA doit être placé sur le graphique horaire de n'importe quelle devise. C'est dans le testeur.
Sur la démo d'Onlan, bien sûr, les minutes sont meilleures.
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в...
Mieux encore, si vous savez comment supprimer les éléments d'un tableau à deux dimensions qui ne sont plus nécessaires.
J'ai perdu la tête, j'ai essuyé le livre de référence sur le sol. C'est une honte que je n'aie pas le cerveau pour ça.
Copie du tableau "en lui-même", en partant de la position située à côté de l'effacé et écriture à partir de l'effacé. Et puis redimensionnez comme Grigori.S.B l'a suggéré.
int src_data[10];
//--- Не важно как заполнен массив//--- Удалим индекс 4ArrayCopy(src_data, src_data, 4, 5);
ArrayResize(src_data, ArraySize(src_data)-1);
Pour un tableau à 2 dimensions, multipliez le numéro de la ligne à supprimer par 2. Pour un tableau à 3 dimensions, multipliez par 3...
Je suppose que vous n'avez pas remarqué, vous pouvez regarder ci-dessus, toutes les questions concernaient MQL5.
Je comprends que la différence n'est pas cruciale parfois, mais néanmoins. La fonction que vous avez citée redimensionne le tableau, en coupant éventuellement des éléments supplémentaires si la taille est réduite.
Ce n'est pas ce qu'il faut. Vous devez supprimer un élément en le trouvant par valeur. J'ai aussi essayé cette fonction, j'en ai parlé dans le numéro 23. Merci quand mê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.
Hourra, je pense que j'ai obtenu un résultat acceptable.
Le tableau se remplit avec les données requises au fur et à mesure que les positions sont ouvertes.
Si j'exécute l'EA dans le testeur, je peux voir les quatre premières entrées dans les commentaires, si le testeur est à faible vitesse, et une pause est utilisée - tout est clair.
Je joins le fichier avec le code.
J'essaie maintenant de jouer avec la première condition et d'attribuer N_Caste = 1 aux positions qui remplissent cette condition ;
Les critiques sont les bienvenues.
Merci à tous ceux qui ne sont pas indifférents.
... Ces choses sont soit auto-écrites, soit commandées en freelance.
Désolé, je n'ai pas pu passer outre. Il n'y a pas des choses comme ça ?
Bonne nuit.
Pour faire suite aux messages ci-dessus - apprenez à l'EA à créer un tableau à deux dimensions, entrez-y les valeurs du ticket et du rang pour chaque position, au fur et à mesure que les positions s'ouvrent.
À l'avenir, lorsque des signaux ou des conditions se présenteront, les rangs des positions correspondantes changeront. C'est ainsi que j'envisage de gérer les positions.
Il y a un problème - je demande aux professionnels de réagir. Aidez-moi à traiter la suppression d'éléments d'un tableau.
Au fur et à mesure que les postes sont fermés, les élites s'accumulent dans le tableau, qui stocke le ticket et le rang d'un poste "mort" déjà fermé, comment le supprimer je ne sais pas.
L'opération sur les pp. 172-173 ne fonctionne pas.
Dans OnTick() à chaque chandelier, les positions sont ouvertes, leurs stops sont modifiés, leurs ticks sont entrés dans un tableau, et le rang zéro d'origine est assigné.
Au fur et à mesure que les arrêts se déclenchent, le tableau accumule des éléments inutiles. Pour plus de clarté, j'ai ajouté les commentaires nécessaires et tout est visible en ligne.
Le code est petit, donc je vais le poster ici et attacher le fichier aussi.
S'il te plaît, aide-moi à organiser le nettoyage du tableau.
Pour la clarté du processus, il est préférable de mettre StLoss 0, TProf doit rester 50, et l'EA doit être placé sur le graphique horaire de n'importe quelle devise. C'est dans le testeur.
Sur la démo d'Onlan, bien sûr, les minutes sont meilleures.
Pour la clarté du processus, il est préférable de mettre StLoss 0, TProf doit rester 50, et l'EA doit être placé sur le graphique horaire de n'importe quelle devise. C'est dans le testeur.
Sur la démo d'Onlan, bien sûr, les minutes sont meilleures.
St.Loss † ©Sur votre mur !
Je suis tombé de ma chaise)
St. La perte est inévitable.
Hmmm... nous avons quelqu'un sur le sujet, enfin †, déjà sur le forum.... )
St.Loss † © Sur votre mur !
Je suis tombé de ma chaise)
Apparemment St.Loss est inévitable.
Hmmm... quelqu'un que nous avons sur un tel sujet, bien †, déjà sur le forum.... )
Je suis d'accord, ça semble ridicule. Mais c'est juste un modèle pour élaborer une partie de l'algorithme. Content d'avoir pu améliorer votre humeur.
Si cela ne vous dérange pas de jeter un lien vers ".... quelqu'un sur ce sujet, bien †, est déjà sur le forum ... " plz.
Si cela ne vous dérange pas de jeter un lien vers ".... quelqu'un sur un sujet comme celui-ci, eh bien †, est déjà sur le forum ... " s'il vous plaît.
Et mieux encore, dites-moi si vous savez comment supprimer les éléments d'un tableau à deux dimensions qui ne sont plus nécessaires ?
J'ai cassé la tête, le répertoire a été essuyé jusqu'aux trous. C'est une honte que je n'aie pas le cerveau pour ça.
comment supprimer les éléments d'un tableau bidimensionnel qui ne sont plus nécessaires ? ??
ArrayResize();
Mieux encore, si vous savez comment supprimer les éléments d'un tableau à deux dimensions qui ne sont plus nécessaires.
J'ai perdu la tête, j'ai essuyé le livre de référence sur le sol. C'est une honte que je n'aie pas le cerveau pour ça.
Copie du tableau "en lui-même", en partant de la position située à côté de l'effacé et écriture à partir de l'effacé. Et puis redimensionnez comme Grigori.S.B l'a suggéré.
Pour un tableau à 2 dimensions, multipliez le numéro de la ligne à supprimer par 2. Pour un tableau à 3 dimensions, multipliez par 3...ArrayResize();
Bonjour, merci pour la réponse.
Je suppose que vous n'avez pas remarqué, vous pouvez regarder ci-dessus, toutes les questions concernaient MQL5.
Je comprends que la différence n'est pas cruciale parfois, mais néanmoins. La fonction que vous avez citée redimensionne le tableau, en coupant éventuellement des éléments supplémentaires si la taille est réduite.
Ce n'est pas ce qu'il faut. Vous devez supprimer un élément en le trouvant par valeur. J'ai aussi essayé cette fonction, j'en ai parlé dans le numéro 23. Merci quand même.