Appearance
question:riscrivi il codice con degli ordini di acquisto e vendita
answer:Per creare un EA funzionante che effettui ordini di acquisto e vendita in MT4 secondo le tue specifiche, è necessario estendere il codice con funzioni adatte per aprire, gestire e chiudere le posizioni. Ecco un esempio di codice migliorato che cerca di incorporare la logica di base della tua strategia di trading includendo anche la gestione degli ordini: ```mql4 //+------------------------------------------------------------------+ //| CustomTradingEA.mq4 | //+------------------------------------------------------------------+ #property strict extern double StopLoss = 50; extern double TakeProfit = 150; extern double TrailingStop = 40; double emaCurrent; double rsiCurrent; double stochKCurrent, stochDCurrent, stochKPrevious, stochDPrevious; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialization return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Update indicator values for the current symbol and chart period emaCurrent = iMA(NULL, 0, 150, 0, MODE_EMA, PRICE_CLOSE, 0); rsiCurrent = iRSI(NULL, 0, 3, PRICE_CLOSE, 0); stochKCurrent = iStochastic(NULL, 0, 6, 3, 3, MODE_SMA, 0, MODE_MAIN, 0); stochDCurrent = iStochastic(NULL, 0, 6, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 0); stochKPrevious = iStochastic(NULL, 0, 6, 3, 3, MODE_SMA, 0, MODE_MAIN, 1); stochDPrevious = iStochastic(NULL, 0, 6, 3, 3, MODE_SMA, 0, MODE_SIGNAL, 1); // Check for Buy condition if(Open[0] < emaCurrent && rsiCurrent < 20 && stochKCurrent > stochDCurrent && stochKPrevious < stochDPrevious && stochKCurrent < 20) { // Place Buy Order int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Ask - StopLoss * Point, Ask + TakeProfit * Point, "Buy Order", 12345, 0, Green); if(ticket > 0) SetTrailingStop(); } // Check for Sell condition else if(Open[0] > emaCurrent && rsiCurrent > 80 && stochKCurrent < stochDCurrent && stochKPrevious > stochDPrevious && stochKCurrent > 80) { // Place Sell Order int ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Bid + StopLoss * Point, Bid - TakeProfit * Point, "Sell Order", 12345, 0, Red); if(ticket > 0) SetTrailingStop(); } } //+------------------------------------------------------------------+ //| Set trailing stop for all open orders | //+------------------------------------------------------------------+ void SetTrailingStop() { for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i,SELECT_BY_POS) && OrderSymbol()==Symbol() && OrderMagicNumber()==12345) { double newStopLoss=0; // Calculate new StopLoss for Buy Orders if(OrderType()==OP_BUY) { newStopLoss=OrderOpenPrice()+(OrderProfit()/Point-TrailingStop)*Point; if(newStopLoss>OrderStopLoss() && newStopLoss<Bid-TrailingStop*Point) OrderModify(OrderTicket(),OrderOpenPrice(),newStopLoss,OrderTakeProfit(),0,CLR_NONE); } // Calculate new StopLoss for Sell Orders else if(OrderType()==OP_SELL) { newStopLoss=OrderOpenPrice()-(OrderProfit()/Point-TrailingStop)*Point; if(newStopLoss<OrderStopLoss() && newStopLoss>Ask+TrailingStop*Point) OrderModify(OrderTicket(),OrderOpenPrice(),newStopLoss,OrderTakeProfit(),0,CLR_NONE); } } } } //+------------------------------------------------------------------+ ``` Questo codice va considerato solo come un punto di partenza. Il modo in cui vengono gestite le modifiche dello stop loss in seguito a profitti fluttuanti potrebbe non corrispondere esattamente alla logica di un "trailing stop" ufficiale, ma è inteso per dimostrare un possibile approccio. Ci sono diversi aspetti da tenere in mente: 1. Gestione degli errori: il codice sopra non gestisce gli errori come la connessione persa, richieste frequenti, e altri problemi che possono sorgere quando si inviano richieste al server. 2. Slippage: dovresti gestire lo slippage nella funzione OrderSend. 3. Lotti (size): il lotto è fissato a 0.1 nel codice ed è importante gestire la dimensione del lotto dinamicamente in base alla tua gestione del rischio. 4. Magic Number: ho usato 12345 come magic number nella funzione OrderSend e OrderSelect per identificare gli ordini da questo specifico EA. Ricorda, lo sviluppo di un EA richiede un approccio sistematico e rigoroso. È fondamentale testare qualsiasi EA in un ambiente demo prima di metterlo in produzione per assicurarsi che funzioni secondo le tue intenzioni e senza errori inaspettati.
question:ho questo errore: 'Point' - some operator expected RSI3.mq4 65 76
answer:L'errore che ricevi indica che c'è un problema con l'uso della variabile `Point`. Potrebbe essere che ci sia un errore di digitazione o una confusione con la funzione o l'operatore previsto. Assicurati che nell'indicatore dell'EA `Point` venga usata correttamente. `Point` è una variabile predefinita in MQL4 che rappresenta il valore di un punto per il simbolo attuale nel grafico attuale. Se viene utilizzato in un'operazione matematica, deve essere accompagnato da operazioni valide. Qui di seguito, rivedo il codice per la parte di impostazione dello stop loss e del take profit nell'ordine, facendo attenzione all'uso di `Point`: ```mql4 // Place Buy Order int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, NormalizeDouble(Ask - StopLoss * Point, _Digits), NormalizeDouble(Ask + TakeProfit * Point, _Digits), "Buy Order", 12345, 0, Green); if(ticket > 0) SetTrailingStop(); // Place Sell Order int ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, NormalizeDouble(Bid + StopLoss * Point, _Digits), NormalizeDouble(Bid - TakeProfit * Point, _Digits), "Sell Order", 12345, 0, Red); if(ticket > 0) SetTrailingStop(); ``` In questi esempi, ho aggiunto `NormalizeDouble` attorno alle formule per calcolare gli stop loss e i take profit. `NormalizeDouble` è una funzione in MQL4 che serve a formattare un numero con un certo numero di cifre decimali, dove `_Digits` è una variabile predefinita in MQL4 che rappresenta il numero di cifre decimali del prezzo del simbolo corrente. Assicurati di avere un approccio simile quando usi `Point` in tutte le parti del tuo codice e verifica che non vi siano operatori mancanti o in eccesso, errori di digitazione, o altri problemi simili nella tua logica di calcolo. Se il problema persiste, condividi la riga di codice esatta dove appare l'errore per ulteriore assistenza.
question:l'errore è in questa sezione if(OrderType()==OP_BUY) { newStopLoss=OrderOpenPrice()+(OrderProfit()/Point-TrailingStop)Point; if(newStopLoss>OrderStopLoss() && newStopLoss<Bid-TrailingStopPoint) OrderModify(OrderTicket(),OrderOpenPrice(),newStopLoss,OrderTakeProfit(),0,CLR_NONE); } // Calculate new StopLoss for Sell Orders else if(OrderType()==OP_SELL) { newStopLoss=OrderOpenPrice()-(OrderProfit()/Point-TrailingStop)Point; if(newStopLoss<OrderStopLoss() && newStopLoss>Ask+TrailingStopPoint) OrderModify(OrderTicket(),OrderOpenPrice(),newStopLoss,OrderTakeProfit(),0,CLR_NONE);
answer:L'errore sta avvenendo perché sembra mancare un operatore tra i termini `(OrderProfit()/Point - TrailingStop)` e `Point`. Per correggere l'errore dovresti aggiungere l'operatore di moltiplicazione `*` tra i due termini. Ecco come dovrebbe apparire il tuo codice corretto (notare gli asterischi `*` aggiunti): ```mql4 if(OrderType() == OP_BUY) { newStopLoss = OrderOpenPrice() + (OrderProfit() / Point - TrailingStop) * Point; if(newStopLoss > OrderStopLoss() && newStopLoss < Bid - TrailingStop * Point) OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(newStopLoss, _Digits), OrderTakeProfit(), 0, CLR_NONE); } // Calculate new StopLoss for Sell Orders else if(OrderType() == OP_SELL) { newStopLoss = OrderOpenPrice() - (OrderProfit() / Point - TrailingStop) * Point; if(newStopLoss < OrderStopLoss() && newStopLoss > Ask + TrailingStop * Point) OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(newStopLoss, _Digits), OrderTakeProfit(), 0, CLR_NONE); } ``` Inoltre, per prevenire altri potenziali errori, è consigliabile normalizzare i valori dei prezzi quando si chiamano funzioni come `OrderModify` usando `NormalizeDouble` e fornendo il corretto numero di cifre decimali (indicato in MQL4 dalla variabile `_Digits`). Questo assicura che i valori di stop loss e take profit rispettino il formato richiesto dal broker. Ho aggiunto `NormalizeDouble` in entrambe le chiamate `OrderModify` per assicurarti di avere valori corretti per i prezzi.
question:c'è un errore poichè l'EA apre molte posizioni nello stesso istante. Trova l'errore e correggi il codice
answer:L'errore che menzioni si verifica quando l'Expert Advisor (EA) non tiene traccia delle posizioni aperte e quindi apre più posizioni senza controllo ogni volta che vengono soddisfatte le condizioni di ingresso. Per evitare questo comportamento, occorre implementare una logica per controllare se esiste già una posizione aperta per una certa direzione di trading prima di inviare un nuovo ordine. Aggiungo qui sotto una sezione di codice migliorato per garantire che l'EA non apra più posizioni di quante intende. ```mql4 void OnTick() { // Update indicator values for the current symbol and chart period ... // Check for Buy condition if(IsTradeContextBusy() || !IsMarketInfoLoaded()) { Print("Trade context is busy or Market Info not loaded."); return; } bool hasOpenBuyOrder = HasOpenOrder(OP_BUY); bool hasOpenSellOrder = HasOpenOrder(OP_SELL); if(shouldOpenBuyOrder && !hasOpenBuyOrder) { // Place Buy Order OpenBuyOrder(); } if(shouldOpenSellOrder && !hasOpenSellOrder) { // Place Sell Order OpenSellOrder(); } // ... The rest of your OnTick implementation } bool HasOpenOrder(int orderType) { for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol() == Symbol() && OrderMagicNumber() == 12345) { if(OrderType() == orderType) { return true; } } } return false; } void OpenBuyOrder() { double sl = NormalizeDouble(Ask - StopLoss * Point, _Digits); double tp = NormalizeDouble(Ask + TakeProfit * Point, _Digits); int ticket = OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, sl, tp, "Buy Order", 12345, 0, Green); if(ticket > 0) { Print("Buy order opened successfully!"); SetTrailingStop(); } else { Print("Buy order failed to open. Error: ", GetLastError()); } } void OpenSellOrder() { double sl = NormalizeDouble(Bid + StopLoss * Point, _Digits); double tp = NormalizeDouble(Bid - TakeProfit * Point, _Digits); int ticket = OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, sl, tp, "Sell Order", 12345, 0, Red); if(ticket > 0) { Print("Sell order opened successfully!"); SetTrailingStop(); } else { Print("Sell order failed to open. Error: ", GetLastError()); } } ``` Nel codice sopra, ho aggiunto alcune funzioni ausiliarie: 1. `HasOpenOrder(int orderType)` - Questa funzione controlla se esiste un ordine aperto per un certo tipo (OP_BUY o OP_SELL) con lo stesso "magic number" per identificare ordini che appartengono a questo EA. 2. `OpenBuyOrder()` e `OpenSellOrder()` - Funzioni per aprire ordini di acquisto e vendita. Queste funzioni includono anche la gestione degli errori e il logging nell'output della console. Inoltre, ho aggiunto due nuovi flag di controllo, `shouldOpenBuyOrder` e `shouldOpenSellOrder`, che determinano se le condizioni di ingresso per l'acquisto o la vendita sono vere. Assicurati di definire queste variabili e di assegnarle le condizioni corrispondenti che ti interessano. Questo codice dovrebbe evitare che l'EA apra più posizioni contemporaneamente se ne esiste già una aperta per quella direzione di mercato. Ricorda che ogni EA deve essere testato su un conto demo prima di essere utilizzato in un ambiente reale di trading.