A matriz se preenche com os dados necessários à medida que as posições são abertas.
Se eu executar o EA no testador, posso ver as primeiras quatro entradas nos comentários, se o testador estiver em baixa velocidade, e se for usada uma pausa - tudo está claro.
Eu anexei o arquivo com o código.
Agora eu tento brincar com a primeira condição e atribuir N_Caste = 1 a posições que atendam a esta condição;
Como um seguimento das mensagens acima - ensinou a EA a criar uma matriz bidimensional, digite nela os valores do bilhete e a classificação para cada posição, conforme as posições abertas.
No futuro, quando sinais ou condições vierem, as posições correspondentes serão alteradas. É assim que pretendo administrar as posições.
Há um problema - peço aos profissionais que respondam. Ajude-me a lidar com a eliminação de elementos da matriz.
À medida que as posições são fechadas, as elites se acumulam na matriz, que armazena o bilhete e a classificação de uma posição"morta" já fechada, como remover não sei.
No OnTick() em cada castiçal, as posições são abertas, suas paradas são modificadas, seus ticks são inseridos em um array, e a classificação original de zero é atribuída.
medida que as paradas acionam, elementos extras se acumulam na matriz. Para maior clareza, produzi os comentários necessários e tudo é visível on-line.
O código é pequeno, por isso vou colocá-lo aqui e anexarei o arquivo também.
Por favor, ajude-me a organizar a limpeza da matriz.
//+------------------------------------------------------------------+//| 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()));
}
}
}
}
}
}
//+------------------------------------------------------------------+
Para a clareza do processo é melhor colocar StLoss 0, TProf deve deixar 50, e a EA deve ser colocada na tabela horária de qualquer moeda. Isto está no testador.
Na demonstração da onlan, é claro que minutos é melhor
Para a clareza do processo é melhor colocar StLoss 0, TProf deve permanecer 50, e a EA deve ser colocada na tabela horária de qualquer moeda. Isto está no testador.
Na demonstração da onlan, é claro que minutos é melhor.
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в...
Melhor ainda, se você souber como remover elementos de uma matriz bidimensional que não são mais necessários?
Perdi a cabeça, limpei o livro de referência para o chão. É uma pena que eu não tenha miolos para isso.
Cópia da matriz "em si", começando da posição ao lado da eliminada e escrevendo a partir da eliminada. E depois redimensionar como sugerido por Grigori.S.B
int src_data[10];
//--- Не важно как заполнен массив//--- Удалим индекс 4ArrayCopy(src_data, src_data, 4, 5);
ArrayResize(src_data, ArraySize(src_data)-1);
Para uma matriz bidimensional, multiplique o número da linha a ser apagada por 2. Para uma matriz tridimensional multiplicar por 3...
Acho que você não notou, você pode olhar acima, todas as perguntas eram sobre a MQL5.
Entendo que a diferença não é crucial às vezes, mas mesmo assim. A função que você citou redimensiona a matriz, talvez cortando elementos extras se o tamanho for reduzido.
Isto não é o que é necessário. É preciso remover um elemento, encontrando-o por valor. Eu também tentei esta função, escrevi sobre ela em #23. De qualquer forma, obrigado.
Hurra, acho que alcancei um resultado aceitável.
A matriz se preenche com os dados necessários à medida que as posições são abertas.
Se eu executar o EA no testador, posso ver as primeiras quatro entradas nos comentários, se o testador estiver em baixa velocidade, e se for usada uma pausa - tudo está claro.
Eu anexei o arquivo com o código.
Agora eu tento brincar com a primeira condição e atribuir N_Caste = 1 a posições que atendam a esta condição;
Os críticos são bem-vindos.
Graças a todos não é indiferente.
... Tais coisas ou são autoescritas ou encomendadas por freelancer.
Desculpe, não consegui passar por isso. Não existem coisas assim?
Boa noite.
Como um seguimento das mensagens acima - ensinou a EA a criar uma matriz bidimensional, digite nela os valores do bilhete e a classificação para cada posição, conforme as posições abertas.
No futuro, quando sinais ou condições vierem, as posições correspondentes serão alteradas. É assim que pretendo administrar as posições.
Há um problema - peço aos profissionais que respondam. Ajude-me a lidar com a eliminação de elementos da matriz.
À medida que as posições são fechadas, as elites se acumulam na matriz, que armazena o bilhete e a classificação de uma posição"morta" já fechada, como remover não sei.
A operação em pp. 172-173 não funciona.
No OnTick() em cada castiçal, as posições são abertas, suas paradas são modificadas, seus ticks são inseridos em um array, e a classificação original de zero é atribuída.
medida que as paradas acionam, elementos extras se acumulam na matriz. Para maior clareza, produzi os comentários necessários e tudo é visível on-line.
O código é pequeno, por isso vou colocá-lo aqui e anexarei o arquivo também.
Por favor, ajude-me a organizar a limpeza da matriz.
Para a clareza do processo é melhor colocar StLoss 0, TProf deve deixar 50, e a EA deve ser colocada na tabela horária de qualquer moeda. Isto está no testador.
Na demonstração da onlan, é claro que minutos é melhor
Para a clareza do processo é melhor colocar StLoss 0, TProf deve permanecer 50, e a EA deve ser colocada na tabela horária de qualquer moeda. Isto está no testador.
Na demonstração da onlan, é claro que minutos é melhor.
St.Loss † ©Em sua parede!
Eu caí de minha cadeira)
St.Loss é inevitável.
Hmmm... temos alguém sobre o assunto, bem †, já no fórum... )
St.Loss † © Em sua parede!
Eu caí da minha cadeira)
Aparentemente, o St.Loss é inevitável.
Hmmm... alguém que temos sobre tal tópico, bem †, já no fórum... )
Concordo, soa ridículo. Mas é apenas um modelo a ser trabalhado em parte do algoritmo. Ainda bem que pude melhorar seu estado de espírito.
Se você não se importa de lançar um link para ".... alguém sobre este tópico, bem †, já está no fórum... " plz.
Se você não se importa de lançar um link para ".... alguém sobre um tópico como este, bem †, já no fórum... "por favor.
E melhor ainda, me diga se você sabe como remover elementos de uma matriz bidimensional, que não são mais necessários?
Quebrei a cabeça, o diretório limpou os buracos. É uma pena que eu não tenha miolos para isso.
como remover elementos de uma matriz bidimensional que não são mais necessários ???
ArrayResize();
Melhor ainda, se você souber como remover elementos de uma matriz bidimensional que não são mais necessários?
Perdi a cabeça, limpei o livro de referência para o chão. É uma pena que eu não tenha miolos para isso.
Cópia da matriz "em si", começando da posição ao lado da eliminada e escrevendo a partir da eliminada. E depois redimensionar como sugerido por Grigori.S.B
Para uma matriz bidimensional, multiplique o número da linha a ser apagada por 2. Para uma matriz tridimensional multiplicar por 3...ArrayResize();
Bom dia, obrigado pela resposta.
Acho que você não notou, você pode olhar acima, todas as perguntas eram sobre a MQL5.
Entendo que a diferença não é crucial às vezes, mas mesmo assim. A função que você citou redimensiona a matriz, talvez cortando elementos extras se o tamanho for reduzido.
Isto não é o que é necessário. É preciso remover um elemento, encontrando-o por valor. Eu também tentei esta função, escrevi sobre ela em #23. De qualquer forma, obrigado.