Wenn ich den EA im Tester ausführe, kann ich die ersten vier Einträge in den Kommentaren sehen, wenn der Tester mit niedriger Geschwindigkeit läuft und eine Pause verwendet wird - alles ist klar.
Ich füge die Datei mit dem Code bei.
Nun versuche ich, mit der ersten Bedingung herumzuspielen und den Positionen, die diese Bedingung erfüllen, N_Caste = 1 zuzuweisen;
Als Follow-up zu den obigen Meldungen - lehrte den EA, ein zweidimensionales Array zu erstellen, geben Sie darin die Werte des Tickets und Rang für jede Position, wie die Positionen öffnen.
In der Zukunft, wenn Signale oder Bedingungen eintreten, werden sich die Ränge der entsprechenden Positionen ändern. So will ich Positionen verwalten.
Es gibt ein Problem - ich bitte die Fachleute zu antworten. Helfen Sie mir, mit dem Löschen von Elementen aus dem Array umzugehen.
Wenn Positionen geschlossen werden, sammeln sich Eliten im Array an, das das Ticket und den Rang einer "toten", bereits geschlossenen Position speichert; wie man sie entfernt, weiß ich nicht.
In OnTick() werden bei jedem Candlestick die Positionen geöffnet, ihre Stops geändert, ihre Ticks in das Array eingetragen und der ursprüngliche Nullrang zugewiesen.
Wenn die Stopps ausgelöst werden, sammelt das Array unnötige Elemente an. Der Übersichtlichkeit halber habe ich die notwendigen Kommentare ausgegeben und alles ist online sichtbar.
Der Code ist klein, deshalb werde ich ihn hier posten und die Datei anhängen.
Bitte helfen Sie mir bei der Organisation der Feldreinigung.
//+------------------------------------------------------------------+//| 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()));
}
}
}
}
}
}
//+------------------------------------------------------------------+
Für die Klarheit des Prozesses ist es besser, StLoss 0 zu setzen, TProf sollte 50 lassen, und der EA sollte auf dem Stundenchart einer beliebigen Währung gesetzt werden. Dies ist im Testgerät.
Für die Klarheit des Prozesses ist es besser, StLoss 0 zu setzen, TProf sollte 50 lassen, und der EA sollte auf dem Stundenchart einer beliebigen Währung gesetzt werden. Dies ist im Testgerät.
Bei der onlan-Demo sind natürlich die Minuten besser.
Hmmm... jemanden haben wir zu so einem Thema, na ja †, schon im Forum... )
Ich stimme zu, das klingt lächerlich. Aber es ist nur ein Modell, um einen Teil des Algorithmus auszuarbeiten. Freut mich, dass ich Ihre Stimmung verbessern konnte.
Wenn Sie nichts dagegen haben, einen Link zu ".... jemand zu diesem Thema, gut †, ist bereits auf dem Forum... " plz.
При успешном выполнении функция возвращает количество всех элементов, содержащихся в массиве после изменения размера; в противном случае возвращает -1 и массив не меняет размеры. Функция может быть применена только к динамическим массивам. При этом необходимо иметь ввиду, что нельзя изменять размер для динамических массивов, назначенных в...
Noch besser ist es, wenn Sie wissen, wie man nicht mehr benötigte Elemente aus einem zweidimensionalen Array entfernt.
Ich habe den Kopf verloren, ich habe das Nachschlagewerk auf den Boden gewischt. Schade, dass ich nicht den Verstand dafür habe.
Kopieren des Arrays "in sich", ausgehend von der Position neben dem gelöschten und Schreiben ab dem gelöschten. Und dann die Größe anpassen, wie Grigori.S.B vorgeschlagen hat
int src_data[10];
//--- Не важно как заполнен массив//--- Удалим индекс 4ArrayCopy(src_data, src_data, 4, 5);
ArrayResize(src_data, ArraySize(src_data)-1);
Bei einem 2-dimensionalen Array multiplizieren Sie die zu löschende Zeilennummer mit 2. Für ein 3-dimensionales Feld multiplizieren Sie mit 3...
Ich schätze, Sie haben es nicht bemerkt, Sie können oben nachsehen, alle Fragen bezogen sich auf MQL5.
Ich verstehe, dass der Unterschied manchmal nicht entscheidend ist, aber trotzdem. Die von Ihnen zitierte Funktion ändert die Größe des Arrays und schneidet möglicherweise zusätzliche Elemente ab, wenn die Größe verringert wird.
Das ist nicht notwendig. Sie müssen ein Element entfernen, indem Sie es nach seinem Wert suchen. Ich habe diese Funktion auch ausprobiert, ich habe darüber in #23 geschrieben. Trotzdem vielen Dank.
Hurra, ich glaube, ich habe ein akzeptables Ergebnis erzielt.
Das Array füllt sich mit den erforderlichen Daten, wenn die Positionen geöffnet werden.
Wenn ich den EA im Tester ausführe, kann ich die ersten vier Einträge in den Kommentaren sehen, wenn der Tester mit niedriger Geschwindigkeit läuft und eine Pause verwendet wird - alles ist klar.
Ich füge die Datei mit dem Code bei.
Nun versuche ich, mit der ersten Bedingung herumzuspielen und den Positionen, die diese Bedingung erfüllen, N_Caste = 1 zuzuweisen;
Die Kritiker sind willkommen.
Danke an alle, die nicht gleichgültig sind.
... Solche Dinge werden entweder selbst geschrieben oder bei Freiberuflern in Auftrag gegeben.
Tut mir leid, ich kam nicht daran vorbei. Gibt es nicht auch solche Dinge?
Gute Nacht.
Als Follow-up zu den obigen Meldungen - lehrte den EA, ein zweidimensionales Array zu erstellen, geben Sie darin die Werte des Tickets und Rang für jede Position, wie die Positionen öffnen.
In der Zukunft, wenn Signale oder Bedingungen eintreten, werden sich die Ränge der entsprechenden Positionen ändern. So will ich Positionen verwalten.
Es gibt ein Problem - ich bitte die Fachleute zu antworten. Helfen Sie mir, mit dem Löschen von Elementen aus dem Array umzugehen.
Wenn Positionen geschlossen werden, sammeln sich Eliten im Array an, das das Ticket und den Rang einer "toten", bereits geschlossenen Position speichert; wie man sie entfernt, weiß ich nicht.
Die Operation auf S. 172-173 funktioniert nicht.
In OnTick() werden bei jedem Candlestick die Positionen geöffnet, ihre Stops geändert, ihre Ticks in das Array eingetragen und der ursprüngliche Nullrang zugewiesen.
Wenn die Stopps ausgelöst werden, sammelt das Array unnötige Elemente an. Der Übersichtlichkeit halber habe ich die notwendigen Kommentare ausgegeben und alles ist online sichtbar.
Der Code ist klein, deshalb werde ich ihn hier posten und die Datei anhängen.
Bitte helfen Sie mir bei der Organisation der Feldreinigung.
Für die Klarheit des Prozesses ist es besser, StLoss 0 zu setzen, TProf sollte 50 lassen, und der EA sollte auf dem Stundenchart einer beliebigen Währung gesetzt werden. Dies ist im Testgerät.
Auf der onlan-Demo sind Minuten natürlich besser
Für die Klarheit des Prozesses ist es besser, StLoss 0 zu setzen, TProf sollte 50 lassen, und der EA sollte auf dem Stundenchart einer beliebigen Währung gesetzt werden. Dies ist im Testgerät.
Bei der onlan-Demo sind natürlich die Minuten besser.
St.Loss † ©An deiner Wand!
Ich bin von meinem Stuhl gefallen)
St. Der Verlust ist unvermeidlich.
Hmmm... wir haben schon jemanden zu diesem Thema, na ja †, im Forum... )
St.Loss † © An deiner Wand!
Ich bin von meinem Stuhl gefallen)
Offenbar ist St. Loss unvermeidlich.
Hmmm... jemanden haben wir zu so einem Thema, na ja †, schon im Forum... )
Ich stimme zu, das klingt lächerlich. Aber es ist nur ein Modell, um einen Teil des Algorithmus auszuarbeiten. Freut mich, dass ich Ihre Stimmung verbessern konnte.
Wenn Sie nichts dagegen haben, einen Link zu ".... jemand zu diesem Thema, gut †, ist bereits auf dem Forum... " plz.
Wenn es Ihnen nichts ausmacht, einen Link zu ".... jemandem zu einem Thema wie diesem, nun ja †, bereits im Forum zu geben... " bitte.
Und noch besser, sagen Sie mir, ob Sie wissen, wie man Elemente aus einem zweidimensionalen Array entfernt, die nicht mehr benötigt werden?
Brach mir den Kopf, wischte das Verzeichnis zu den Löchern. Schade, dass ich nicht den Verstand dafür habe.
Wie entfernt man Elemente aus einem zweidimensionalen Array, die nicht mehr benötigt werden?
ArrayResize();
Noch besser ist es, wenn Sie wissen, wie man nicht mehr benötigte Elemente aus einem zweidimensionalen Array entfernt.
Ich habe den Kopf verloren, ich habe das Nachschlagewerk auf den Boden gewischt. Schade, dass ich nicht den Verstand dafür habe.
Kopieren des Arrays "in sich", ausgehend von der Position neben dem gelöschten und Schreiben ab dem gelöschten. Und dann die Größe anpassen, wie Grigori.S.B vorgeschlagen hat
Bei einem 2-dimensionalen Array multiplizieren Sie die zu löschende Zeilennummer mit 2. Für ein 3-dimensionales Feld multiplizieren Sie mit 3...ArrayResize();
Guten Morgen, danke für die Antwort.
Ich schätze, Sie haben es nicht bemerkt, Sie können oben nachsehen, alle Fragen bezogen sich auf MQL5.
Ich verstehe, dass der Unterschied manchmal nicht entscheidend ist, aber trotzdem. Die von Ihnen zitierte Funktion ändert die Größe des Arrays und schneidet möglicherweise zusätzliche Elemente ab, wenn die Größe verringert wird.
Das ist nicht notwendig. Sie müssen ein Element entfernen, indem Sie es nach seinem Wert suchen. Ich habe diese Funktion auch ausprobiert, ich habe darüber in #23 geschrieben. Trotzdem vielen Dank.