Come seguito ai messaggi di cui sopra - ha insegnato all'EA a creare un array bidimensionale, inserirvi i valori del ticket e del rank per ogni posizione, man mano che le posizioni si aprono.
In futuro, quando arriveranno segnali o condizioni, i ranghi delle posizioni corrispondenti cambieranno. Questo è il modo in cui ho intenzione di gestire le posizioni.
C'è un problema - chiedo ai professionisti di rispondere. Aiutatemi a gestire la cancellazione di elementi dall'array.
Man mano che le posizioni vengono chiuse, le élite si accumulano nell'array, che memorizza il biglietto e il rango di una posizione"morta" già chiusa, come rimuovere non lo so.
In OnTick() ad ogni candela, le posizioni vengono aperte, i loro stop vengono modificati, i loro tick vengono inseriti in una matrice e viene assegnato il rango zero originale.
Man mano che gli arresti si innescano, l'array accumula elementi inutili. Per chiarezza ho emesso i commenti necessari e tutto è visibile online.
Il codice è piccolo, quindi lo posterò qui e allegherò anche il file.
Per favore, aiutatemi a organizzare la pulizia dell'array.
//+------------------------------------------------------------------+//| 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()));
}
}
}
}
}
}
//+------------------------------------------------------------------+
Per la chiarezza del processo è meglio mettere StLoss 0, TProf dovrebbe rimanere 50, e l'EA dovrebbe essere posizionato sul grafico orario di qualsiasi valuta. Questo è nel tester.
Sulla demo di onlan, ovviamente i minuti sono migliori
Per la chiarezza del processo è meglio mettere StLoss 0, TProf dovrebbe rimanere 50, e l'EA dovrebbe essere posizionato sul grafico orario di qualsiasi valuta. Questo è nel tester.
Sulla demo di onlan, ovviamente i minuti sono migliori.
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в...
Meglio ancora, se sapete come rimuovere elementi da un array bidimensionale che non sono più necessari.
Ho perso la testa, ho buttato a terra il libro di riferimento. È un peccato che io non abbia il cervello per farlo.
Copia dell'array "in sé", a partire dalla posizione accanto alla cancellata e scrittura a partire dalla cancellata. E poi ridimensionare come suggerito da Grigori.S.B
int src_data[10];
//--- Не важно как заполнен массив//--- Удалим индекс 4ArrayCopy(src_data, src_data, 4, 5);
ArrayResize(src_data, ArraySize(src_data)-1);
Per una matrice a 2 dimensioni, moltiplicate il numero di riga da cancellare per 2. Per una matrice tridimensionale moltiplicare per 3...
Immagino che non l'abbiate notato, potete guardare sopra, tutte le domande riguardavano MQL5.
Capisco che la differenza non è cruciale a volte, ma tuttavia. La funzione che hai citato ridimensiona l'array, forse tagliando elementi extra se la dimensione è ridotta.
Questo non è ciò che è necessario. È necessario rimuovere un elemento trovandolo per valore. Ho provato anch'io questa funzione, ne ho scritto nel #23. Grazie comunque.
Urrà, credo di aver raggiunto un risultato accettabile.
L'array si riempie con i dati richiesti man mano che le posizioni vengono aperte.
Se eseguo l'EA nel tester, posso vedere le prime quattro voci nei commenti, se il tester è a bassa velocità, e si usa una pausa - tutto è chiaro.
Allego il file con il codice.
Ora provo a scherzare con la prima condizione e assegno N_Caste = 1 alle posizioni che soddisfano questa condizione;
Le critiche sono benvenute.
Grazie a tutti non indifferente.
... Queste cose sono o auto-scritte o commissionate da freelance.
Mi dispiace, non sono riuscito a superarlo. Non ci sono cose del genere?
Buonanotte.
Come seguito ai messaggi di cui sopra - ha insegnato all'EA a creare un array bidimensionale, inserirvi i valori del ticket e del rank per ogni posizione, man mano che le posizioni si aprono.
In futuro, quando arriveranno segnali o condizioni, i ranghi delle posizioni corrispondenti cambieranno. Questo è il modo in cui ho intenzione di gestire le posizioni.
C'è un problema - chiedo ai professionisti di rispondere. Aiutatemi a gestire la cancellazione di elementi dall'array.
Man mano che le posizioni vengono chiuse, le élite si accumulano nell'array, che memorizza il biglietto e il rango di una posizione"morta" già chiusa, come rimuovere non lo so.
L'operazione su pp. 172-173 non funziona.
In OnTick() ad ogni candela, le posizioni vengono aperte, i loro stop vengono modificati, i loro tick vengono inseriti in una matrice e viene assegnato il rango zero originale.
Man mano che gli arresti si innescano, l'array accumula elementi inutili. Per chiarezza ho emesso i commenti necessari e tutto è visibile online.
Il codice è piccolo, quindi lo posterò qui e allegherò anche il file.
Per favore, aiutatemi a organizzare la pulizia dell'array.
Per la chiarezza del processo è meglio mettere StLoss 0, TProf dovrebbe rimanere 50, e l'EA dovrebbe essere posizionato sul grafico orario di qualsiasi valuta. Questo è nel tester.
Sulla demo di onlan, ovviamente i minuti sono migliori
Per la chiarezza del processo è meglio mettere StLoss 0, TProf dovrebbe rimanere 50, e l'EA dovrebbe essere posizionato sul grafico orario di qualsiasi valuta. Questo è nel tester.
Sulla demo di onlan, ovviamente i minuti sono migliori.
Santa Perdita † ©Sul tuo muro!
Sono caduto dalla sedia)
La perdita è inevitabile.
Hmmm... abbiamo qualcuno sull'argomento, beh †, già sul forum... )
Santa Perdita † © Sul tuo muro!
Sono caduto dalla sedia)
A quanto pare St.Loss è inevitabile.
Hmmm... qualcuno che abbiamo su un tale argomento, bene †, già sul forum... )
Sono d'accordo, sembra ridicolo. Ma è solo un modello per elaborare una parte dell'algoritmo. Sono contento di aver potuto migliorare il tuo umore.
Se non ti dispiace lanciare un link a ".... qualcuno su questo argomento, beh †, è già sul forum... "plz".
Se non ti dispiace buttare un link a ".... qualcuno su un argomento come questo, beh †, è già sul forum... per favore".
E meglio ancora, ditemi se sapete come rimuovere elementi da un array bidimensionale, che non sono più necessari?
Mi ha rotto la testa, l'elenco ha cancellato i buchi. È un peccato che io non abbia il cervello per farlo.
come rimuovere elementi da un array bidimensionale che non sono più necessari?
ArrayResize();
Meglio ancora, se sapete come rimuovere elementi da un array bidimensionale che non sono più necessari.
Ho perso la testa, ho buttato a terra il libro di riferimento. È un peccato che io non abbia il cervello per farlo.
Copia dell'array "in sé", a partire dalla posizione accanto alla cancellata e scrittura a partire dalla cancellata. E poi ridimensionare come suggerito da Grigori.S.B
Per una matrice a 2 dimensioni, moltiplicate il numero di riga da cancellare per 2. Per una matrice tridimensionale moltiplicare per 3...ArrayResize();
Buongiorno, grazie per la risposta.
Immagino che non l'abbiate notato, potete guardare sopra, tutte le domande riguardavano MQL5.
Capisco che la differenza non è cruciale a volte, ma tuttavia. La funzione che hai citato ridimensiona l'array, forse tagliando elementi extra se la dimensione è ridotta.
Questo non è ciò che è necessario. È necessario rimuovere un elemento trovandolo per valore. Ho provato anch'io questa funzione, ne ho scritto nel #23. Grazie comunque.