Tag: algotrading

Dynamic Range Revert Money Management

Ciao, la strategia Dynamic Range Revert Money Management è una miglioria alla strategia Dynamic Range Revert! (Pazzesco vero?! 😀 ) Si tratta della stessa strategia dove però i lotti cambiano in percentuale.

Ciao sono Drilon e sono un programmatore con la passione per la finanza personale. In questa strategia si imposta quanto del nostro capitale si vuole rischiare ad ogni trade, ad esempio l’1%! La logica che c’è sotto poi è la stessa che trovi qui (no dovevi cliccare QUI, c’è il link, non in questo, dai te lo rimetto qui, stasera mi è presa così…non sono simpatico scusa)

Risultati

Andiamo al sodo e vediamo il risultato!

dynamic range revert money management – risultati

Questo grafico è l’equityline, ovvero l’andamento. Partendo da 450$ si arriva a circa 3400$.

Aspetta non è così semplice, questa vale solo per EURCAD a timeframe 1 minuto!

Niente male lo so, ma non farti ingannare dai, ovviamente questo è un backtest, in live i risultati non saranno così, per via dello spread e le commissioni che qui è sono statiche (non zero, non mi ricordo che valore di preciso).

Ok abbiamo visto il grafico, vediamo più nel dettaglio però.

Un dato molto importante per me è sempre il Drawdown poiché devo essere in grado di sostenerlo sia economicamente che mentalmente (terribile veder scendere il valore dei soldi). In questo caso si tratta di circa un 12% di drawdown.

Non è tantissimo, però non è nemmeno poco, anche se per un guadagno del genere ne potrebbe valere la pena!

Vediamo che ha aperto circa 3000 ordini, quindi i dati sono abbastanza affidabile. Se un backtest di una strategia si fa su 10 ordini i dati che ottieni puoi evidenziarli, sottolinearli, accartocciare il foglio e buttare tutto! NON SONO ABBASTANZA! NON è ATTENDIBILE!

Un altro valore importante sono gli ordini consecutivi che sono andati in stopLoss, anche questo principalmente per una questione mentale (il rischio rendimento vedrai che non è come ti aspetti).

Personalmente, preferisco fare piccoli profitti costanti e prendere una batosta raramente, rispetto a prendere tanti stopLoss e un grande takeProfit. Mentalmente mi ammazza e mi porterebbe a fare cazzate!

Vabbè basta, io il mio l’ho detto, tieni il codice!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class IIDynamicRangeBreakoutREVERTMM : Robot
    {
        [Parameter(DefaultValue = 10)]
        public double takeProfit { get; set; }

        [Parameter(DefaultValue = 10)]
        public double stopLoss { get; set; }

        [Parameter(DefaultValue = 8)]
        public int hourEnter { get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourExit { get; set; }
        
        [Parameter(DefaultValue = 8)]
        public int hourClosingOpen{ get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourClosingExit { get; set; }
        
        [Parameter(DefaultValue = 1)]
        public int maxOrder { get; set; }
        
        [Parameter(DefaultValue = 0)]
        public double maxRange { get; set; }
        
        [Parameter(DefaultValue = 999999)]
        public double minRange { get; set; }
        
        [Parameter(DefaultValue = 0.01)]
        public double lots { get; set; }
        
        [Parameter(DefaultValue = 3)]
        public int stopLossRiskPercent { get; set; }
        
        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;
        }

        protected override void OnTick()
        {
            // Handle price updates here
            if(!checkTime()){
                // Break Range
                if(Bars.LastBar.Close > maxRange && maxRange != 0){
                    // Open BUY
                    lots = DisplayPositionSizeRiskOnChart();
                    if(lots >= 0.00){
                        Open(TradeType.Sell, lots);
                        maxRange = 0;
                        minRange = 999999;
                    }
                }  
                
                if(Bars.LastBar.Close < minRange && minRange != 999999){
                    // Open SELL
                    lots = DisplayPositionSizeRiskOnChart();
                    if(lots >= 0.00){
                        Open(TradeType.Buy, lots);
                        maxRange = 0;
                        minRange = 999999;
                    }
                }
            }
            
            /*if(checkClosingTime()){
                CloseAll();
            }*/
        }
        
        protected override void OnBar()
        {
        
            if(checkTime()){
                // Set Range
                if(Bars.LastBar.High > maxRange ){
                    maxRange = Bars.LastBar.High;
                }  
                
                if(Bars.LastBar.Low < minRange ){
                    minRange = Bars.LastBar.Low;
                }
            }    
        }

        protected override void OnStop()
        {
            CloseAll();
        }
        
        private bool checkTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourEnter && date.Hour <= hourExit && hourEnter <= hourExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private bool checkClosingTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourClosingOpen && date.Hour <= hourClosingExit && hourClosingOpen <= hourClosingExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private void CloseAll()
        {
            foreach (var position in Positions.FindAll("DynamicRangeBreakoutREVERT", SymbolName))
            {
                ClosePosition(position);
            }
        }
        
        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("DynamicRangeBreakoutREVERT", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType, double lots)
        {
            var position = Positions.FindAll("DynamicRangeBreakoutREVERT", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);
            if (position == null || position.Length < maxOrder)
                ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "DynamicRangeBreakoutREVERT", stopLoss, takeProfit);
        }
        
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Print("Closed positions");
            var position = args.Position;

           /* if (position.NetProfit > 0)
            {
                lots = 0.03;
            }
            else
            {
                lots *= 2;
            }*/
        }
        
        
        private double DisplayPositionSizeRiskOnChart()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;
 
            double positionSizeForRisk = (Account.Balance * stopLossRiskPercent / 100) / (stopLoss * costPerPip);
            Print(Account.Balance, " ",positionSizeForRisk, " ",(stopLoss * costPerPip));
            
            string text = stopLossRiskPercent + "% x " + stopLoss + "pip = " + Math.Round(positionSizeForRisk, 2) + " lot";
 
            ChartObjects.DrawText("positionRisk", text, StaticPosition.TopRight, Colors.Yellow);
            return Math.Round(positionSizeForRisk, 2);
        }
    }
} 

questi sono i parametri che devi impostare:

  • takeProfit: 15
  • stopLoss: 40
  • hourEnter: 18
  • hourExit: 19
  • hourClosingEnter: 18
  • hourClosingExit: 23
  • maxOrder: 1
  • minRange: 99999
  • lots: 0.01
  • stopLossRisk: 1

Mi raccomando, la strategia può funzionare anche con altre valute, ma con questi parametri specifici funziona sono in EURCAD a 1 minuto!

Da qui puoi vedere come utilizzare cTrader (piattaforma che utilizzo): LINK

Se hai dubbi o domande fammele pure su Telegram: https://t.me/+0xQYD3WKIAA5Mjg8

Seguimi su instagram: https://www.instagram.com/investoinvestigando.it/

Dynamic Breakout – Scalping

Ciao oggi ti vado a parlare di una strategia di scalping (Dynamic Breakout – Scalping) che ho trovato online e che ho un po’ ridefinito secondo le mie idee.

Logica di base

La logica di base è quella di definire un range di max e min durante un determinato periodo della giornata, ad esempio dalle 2 di notte alle 7 di mattina, dopodiché se il prezzo va sopra o sotto questi range entrare a mercato.

Esempio di breakout dinamico

In quest’immagine vediamo un esempio di un caso ideale della strategia.

Ma quando chiudere l’operazione?

Per questo ho messo due possibilità, una al raggiungimento di un TakeProfit e l’altra è una chiusura a tempo, ovvero in un determinato orario della giornata!

La strategia l’ho trovata in questo canale YouTube: https://www.youtube.com/c/RenéBalke/videos

Andiamo nel codice

A questo punto ho codificato la strategia e sono andato a ottimizzarla per USDJPY (quello utilizzato nel video) però non ho ottenuto dei buoni risultati. Si sempre profittevole, però troppo volatile per i miei gusti.

USDJPY

Sono andato a provarla in un’altra coppia, ovvero EURUSD e qui le cose si sono fatte interessanti.

EURUSD - Brakout strategy
EURUSD – Brakout strategy

Come puoi vedere dall’immagine c’è una crescita costante e un rischio minimo. Questo è stato ottenuto con 0.01 lotti e vediamo che c’è un drawdown di $42 e un guadagno di $437, tutto questo in un periodo di 11 anni.

Come dico tutte le volte, non guardare tanto il fatto che in 11 anni 400$ siano pochi, bisogna vedere se la strategia è profittevole in un tempo abbastanza lungo, dopo sei sempre in tempo ad aumentare i lotti e ad aumentare il guadagno…ma anche il drawdown possibile.

I parametri migliori che sono venuti fuori per questa strategia, in EURUSD sono i seguenti:

TimeFrame: 1m
TakeProfit: 5
StopLoss: 100000 (è senza stop loss la strategia)
hourEnter: 6
hourExit: 8
hourClosingOpen: 19
hourClosingExit: 19
maxOrder: 1
maxRange: 0
minRange: 999999
lots: 0.01

Ti ricordo di testarla anche in altre coppie e trovare i settaggi migliori prima di operare veramente.

Ed ecco il codice della strategia, se vuoi sapere come inserirlo e utilizzare la piattaforma guarda qui: https://www.investoinvestigando.it/come-usare-ctrader/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class IIDynamicRangeBreakout : Robot
    {
        [Parameter(DefaultValue = 10)]
        public double takeProfit { get; set; }

        [Parameter(DefaultValue = 10)]
        public double stopLoss { get; set; }

        [Parameter(DefaultValue = 8)]
        public int hourEnter { get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourExit { get; set; }
        
        [Parameter(DefaultValue = 8)]
        public int hourClosingOpen{ get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourClosingExit { get; set; }
        
        [Parameter(DefaultValue = 1)]
        public int maxOrder { get; set; }
        
        [Parameter(DefaultValue = 0)]
        public double maxRange { get; set; }
        
        [Parameter(DefaultValue = 999999)]
        public double minRange { get; set; }
        
        [Parameter(DefaultValue = 0.01)]
        public double lots { get; set; }
        

        protected override void OnTick()
        {
            // Handle price updates here
            if(!checkTime()){
                // Break Range
                if(Bars.LastBar.Close > maxRange && maxRange != 0){
                    // Open BUY
                    Open(TradeType.Buy, lots);
                    maxRange = 0;
                    minRange = 999999;
                }  
                
                if(Bars.LastBar.Close < minRange && minRange != 999999){
                    // Open SELL
                    Open(TradeType.Sell, lots);
                    maxRange = 0;
                    minRange = 999999;
                }
            }
            
            if(checkClosingTime()){
                CloseAll();
            }
        }
        
        protected override void OnBar()
        {
        
            if(checkTime()){
                Print("DENTRO");
                // Set Range
                if(Bars.LastBar.High > maxRange ){
                    maxRange = Bars.LastBar.High;
                }  
                
                if(Bars.LastBar.Low < minRange ){
                    minRange = Bars.LastBar.Low;
                }
            }    
        }

        protected override void OnStop()
        {
            CloseAll();
        }
        
        private bool checkTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourEnter && date.Hour <= hourExit && hourEnter <= hourExit && hourClosingOpen > hourExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private bool checkClosingTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourClosingOpen && date.Hour <= hourClosingExit && hourClosingOpen <= hourClosingExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        
        private void CloseAll()
        {
            foreach (var position in Positions)
            {
                ClosePosition(position);
            }
        }
        
        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("Order", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType, double lots)
        {
            var position = Positions.FindAll("Order", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);
            if (position == null || position.Length < maxOrder)
                ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "Order", stopLoss, takeProfit);
        }
    }
}

Se vuoi vedere delle strategie da utilizzare inizia da qui: https://www.investoinvestigando.it/una-strategia-per-sempre-algotrading/

Se hai dubbi o domande fammele pure su Telegram: https://t.me/+0xQYD3WKIAA5Mjg8

Seguimi su instagram: https://www.instagram.com/investoinvestigando.it/

Una strategia per sempre? – AlgoTrading

Ciao, oggi torno a parlarti di una strategia automatica che ho scritto e testato personalmente, siamo sempre a una strategia da utilizzare sempre. Sono Drilon e sono un programmatore con la passione per la finanza personale!

La strategia ha dato risultati veramente interessanti, utilizzabile per ogni tipologia di portafoglio.

Idea

L’idea di base è quella di una “toccata e fuga” poiché noi siamo dei piccoli pesci per il mercato, non possiamo immaginare di combattere gli squali. L’imitiamoci a prendere il nostro e stare tranquilli.

Attenzione però, non è scalping perché non si punta tanto in pochissimo tempo per poter guadagnare qualcosa.

L’idea è di prendere una piccola parte di un grande movimento, infatti l’obiettivo è quello di prendere 10/15 pips e fine.

Vedi questo grafico? Indica la probabilità di arrivare al target (lato sinistro asse delle Y) in un numero di candele (lato basso asse delle X). Quindi perchè puntare a fare 200 pips se statisticamente è provato che è molto difficile? Andiamo a fare operazioni quasi certe!

Quindi, tornando alla strategia, l’idea è di utilizzare un qualcosa che ci indichi il trend principale (Media Mobile Esponenziale) e qualcosa che ci indichi quando entrare a mercato e per quanto starci, il 100% di probabilità di arrivare a target non c’è! Utilizzerò lo Stochastic! Quindi avremo qualcosa del genere:

Come si opera?

Allora si entra a mercato quando le medie mobili esponenziali sono verso lo stesso trend e lo stochastic incrocia ed entra nella zona azzurra, con un piccolo dettaglio però, bisogna entrare a mercato solo se l’intreccio attuale dello stochastic è avvenuto seguendo il trend rispetto all’intreccio precedente.

Mi spiego meglio!

Esempio di operazione di SELL

Abbiamo le medie mobili esponenziali tutte tendenti verso il basso, entriamo nel punto 3 perché l’intreccio precedente dello stochastic è avvenuto nel punto 2 ed il prezzo nel punto 2 era maggiore rispetto al punto 3, quindi conferma il trend ribassista sul quale noi vogliamo puntare.

Nel punto 2 non si entra poiché c’è stato un intreccio precedente nel punto 1 che è avvenuto a un prezzo più basso, quindi nel punto 2 poteva esserci un’inversione (Poi è sceso ma è l’incertezza del mercato).

Se si guarda più indietro in realtà noi si sarebbe entrati nel punto 1 perché il precedente intreccio dello stochastic era a un prezzo più alto, ma questo era giusto per farti un esempio e capire la strategia.

Ma quando esco? L’obiettivo è 10 pips di target oppure quando lo stochastic arriva nella zona opposta alla nostra, nel caso del sell si esce quando lo stochastic arriva sotto i 20.

Stessa cosa, capovolta, per quanto riguarda il buy

Codice

Dopo aver fatto l’optimization questo è il risultato:

In 11 anni ha eseguito 181 ordini, di cui 170 andati a target e 11 chiusi in negativo!

Non male eh? Il profitto però, come vedi, non è altissimo, è di 228$ che in 11 anni fanno abbastanza schifo, però questo a noi ci serve solo come test per capire se la strategia funziona o no! Questo è stato fatto puntando sempre il minimo (0.01 lotti)

Vuoi sapere la cosa bella? Che ha un drawdown di soli 33$!

Quindi se hai un capitale di 100$ puoi già partire con questa strategia, se hai un capitale di 1k puoi aumentare i lotti e utilizzarne (0.1) e otterresti un guadagno di circa 2280$ rischiando 330$.

Quindi dipende anche dal budget personale!

Questi sono i parametri da utilizzare:

Poi comunque puoi sbizzarrirti come più credi, facendo altri test e altri parametri.

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class IIScalping : Robot
    {

        [Parameter("Source", Group = "Data series")]
        public DataSeries Source { get; set; }

        [Parameter(DefaultValue = 10)]
        public double takeProfit { get; set; }

        [Parameter(DefaultValue = 10)]
        public double stopLoss { get; set; }

        [Parameter(DefaultValue = 8)]
        public int hourEnter { get; set; }

        [Parameter(DefaultValue = 18)]
        public int hourExit { get; set; }

        [Parameter(DefaultValue = 60)]
        public int fastPeriod { get; set; }

        [Parameter(DefaultValue = 240)]
        public int slowPeriod { get; set; }

        [Parameter(DefaultValue = 0.01)]
        public double lots { get; set; }

        [Parameter(DefaultValue = 2)]
        public int multiplier { get; set; }

        [Parameter(DefaultValue = 1)]
        public int maxOrder { get; set; }

        [Parameter(DefaultValue = 8)]
        public int stochLength { get; set; }

        [Parameter(DefaultValue = 3)]
        public int stochParams { get; set; }

        private ExponentialMovingAverage emaFast;
        private ExponentialMovingAverage emaSlow;
        private StochasticOscillator stoch;
        
        double stochLevel = 0.0;


        protected override void OnStart()
        {
            // Put your initialization logic here

        }

        protected override void OnBar()
        {
            // Put your core logic here
            emaFast = Indicators.ExponentialMovingAverage(Source, fastPeriod);
            emaSlow = Indicators.ExponentialMovingAverage(Source, slowPeriod);
            stoch = Indicators.StochasticOscillator(stochLength, stochParams, stochParams, MovingAverageType.Exponential);
            
            
            int currentBar = Bars.Count - 1;
            bool check = checkTime();
            var positions = Positions.FindAll("Order");
            if (check == true)
            {
                

                //Open(TradeType.Buy, lots);
                
                if(emaFast.Result.LastValue > emaSlow.Result.LastValue && stoch.PercentK[currentBar] > stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] <= 20 && stochLevel == 0.0){
                    stochLevel = Bars.LastBar.Close;
                }
                
                if(emaFast.Result.LastValue < emaSlow.Result.LastValue && stoch.PercentK[currentBar] < stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] >= 80 && stochLevel == 0.0){
                    stochLevel = Bars.LastBar.Close;
                }

                if (emaFast.Result.LastValue > emaSlow.Result.LastValue && stoch.PercentK[currentBar] > stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] <= 20 && Bars.LastBar.Close > stochLevel)
                {
                    stochLevel = 0.0;
                    //stopLoss = (Bars[currentBar-1].Close - Bars[currentBar-1].Low)*100000;
                    Open(TradeType.Buy, lots);
                }

                if (emaFast.Result.LastValue < emaSlow.Result.LastValue && stoch.PercentK[currentBar] < stoch.PercentD[currentBar] && stoch.PercentK[currentBar - 1] >= 80 && Bars.LastBar.Close < stochLevel)
                {
                    stochLevel = 0.0;
                    //stopLoss = (Bars[currentBar-1].High - Bars[currentBar-1].Close)*100000;
                    Open(TradeType.Sell, lots);
                }

            }
            
            if(positions.Length>0 && (positions[0].TradeType == TradeType.Buy)){
                if(stoch.PercentK[currentBar] >= 80){
                    Close(TradeType.Buy);
                }
            }
            
            
            if(positions.Length>0 && (positions[0].TradeType == TradeType.Buy)){
                if(stoch.PercentK[currentBar] <= 20){
                    Close(TradeType.Sell);
                }
            }

        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }

        private bool checkTime()
        {
            DateTime date = Server.Time;
            if (date.Hour >= hourEnter && date.Hour <= hourExit)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("Order", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType, double lots)
        {
            var position = Positions.FindAll("Order", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);
            if (position == null || position.Length < maxOrder)
                ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "Order", stopLoss, takeProfit);
        }
    }


}

Questo è il broker che utilizzo: https://www.icmarkets.eu/en/

Questa è un’altra strategia: https://www.investoinvestigando.it/algotrading-macd-ema/

Cosa cazzo è Keras? – Guida Keras #1

Cosa cazzo è Keras? Keras è il framework di deep learning più utilizzato poiché Keras semplifica l’esecuzione di nuovi esperimenti, ti consente di provare più idee rispetto ad altri e in modo più veloce.

Basato su TensorFlow2 è un framework di livello industriale in grado di fare tantissime cose, poi TensorFlow è di Google, quindi 😉

Possiamo fare del Reinforcement learning (ovvero che impara da solo e si migliora da solo), classificazione delle immagini, previsioni (anche sul prezzo di azioni ecc… ).

Nel deep learning è importante realizzare di model validi costituiti da diversi layer

Cosa cazzo è Keras?

Come vediamo dall’immagine una rete neurale è composta da alcuni dati in input (input layer) che vengono gestiti e manipolati da altri layer (hidden layer) per poi tirare fuori il dato che a noi ci interessa.

Facciamo un esempio

Nel caso degli investimenti i dati in input saranno composti da tutto lo storico dei prezzi (Prezzo di apertura, Prezzo di chiusura, Prezzo più alto, Prezzo più basso) giornalieri.

I layer nascosti faranno cose che poteranno a un output che sarà ciò che noi vorremmo. Ad esempio il prezzo che avrà lo stock domani!

stock prediction price

Come vediamo dal grafico, abbiamo la parte in blu che è lo storico effettivo del NASDAQ, in giallo abbiamo la predizione fatta dal nostro programmino fantastico di intelligenza artificiale, mentre in rosso abbiamo il prezzo effettivo che il nasdaq ha avuto in quel periodo. Molto vicino vero? Si molto figo tutto questo…

Vedremo che però non è così semplice… si capisce che è di fondamentale importanza che i dati sul quale il model viene “allenato” siano il più corretti possibile.

Hai capito un minimo Cosa cazzo è Keras?

Per qualsiasi dubbio o domanda non esitare a scrivermi su instagram:

https://www.instagram.com/investoinvestigando.it/

Oppure lascia un commento sul post, sarò lieto di aiutarti 🙂

Prossimo articolo (Ancora non disponibile)