For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

No trades happened



  • I wrote my first Trading system using an example from a book. But no traders happened. Where am I mistaking?

    runfile('/Users/giovannicaridi/.spyder-py3/Trading System', wdir='/Users/giovannicaridi/.spyder-py3')
    [100%**] 1 of 1 completed
    Valore iniziale Portafoglio: 100000.00
    Valore del Portafoglio finale: 100000.00

    from future import (absolute_import, division, print_function,unicode_literals)
    import backtrader as bt
    import backtrader.indicators as btind
    import backtrader.analyzers as btanalyzers
    import datetime # For datetime objects
    import os.path # To manage paths
    import sys # To find out the script name (in argv[0])

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    pd.core.common.is_list_like = pd.api.types.is_list_like
    from pandas_datareader import data, wb
    import yfinance as yf

    class Cross_Medie(bt.Strategy):
    
    # Definisco la media veloce e la media lenta (utile per l'ottimizzazione)
    params = (('Med_vel',50), ('Med_len', 100))
    
    # Inizializzo le due medie
    def __init__(self):
        self.sma_vel = btind.SMA(period = self.p.Med_vel)
        self.sma_len = btind.SMA(period = self.p.Med_len)
        
        # Definisco il segnale di acquisto/vendita
        self.buysig = btind.CrossOver(self.sma_vel, self.sma_len)
        
        # Salvo i dati di closing (self.datas[0] è l'orologio del sistema, 
        # utile per verificare se una candela in chiusura rompre una media/indicatore)
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        
       
    
    def next(self):
    
    if  self.position.size:    # verifico se sono in posizione
        
          if self.buysig < 0:  # vuol dire che sono dentro long (incrocio a ribasso)
              self.close()     # chiudo la posizione esistente
              self.sell()      
            
          elif self.buysig > 0: # vuol dire che sono dentro short (incrocio a rialzo)
              self.close()      # chiudo la posizione esistente
              self.buy()
            
    else:                     # non sono in posizione
             
        if self.buysig > 0:   # segnale positivo 
            self.buy()        # acquisto
            
        elif self.buysig < 0: # segnale negativo
            self.sell()       # vendo
            
           
    
    def stampa(self, txt, dt=None):
    
    # Funzione di stampa per capire cosa sta succedendo
    dt = dt or self.datas[0].datetime.date(0)  
    print('%s, %s' % (dt.isoformat(), txt))    
    
    
    def notify_order(self, order):
    
    if order.status in [order.Submitted, order.Accepted]:
        # ordine acquisto/vendita accettato
        return
    
    # Verifica se ordine completato
    if order.status in [order.Completed]:
        if order.isbuy():
            # Stampo dettaglio di quantità, prezzo e commissioni
            self.stampa('ACQ ESEGUITO, QTY: %.2f, PREZZO: %.2f, COSTO: %.2f, COMM: %.2f' 
                        % (order.executed.size,order.executed.price,order.executed.comm))
    
            self.buyprice = order.executed.price
            self.buycomm = order.executed.comm
    
        else: # Vendita
            self.stampa('VEND ESEGUITA, QTY: %.2f, PREZZO: %.2f, COSTO: %.2f, COMM: %.2f' 
                        % (order.executed.size,order.executed.price,order.executed.comm))
    
            self.bar_executed = len(self)
            
    elif order.status in [order.Canceled, order.Margin, order.Rejected]:
      self.stampa('Ordine Cancellato')
     
    self.order = None    
      
         
          
    def notify_trade(salef, trade):
    if not trade.isclosed:
        return
    self.stampa('PROFITTO OPERAZIONE, LORDO %.2f, NETTO %.2f' % (trade.pnl, trade.pnlcomm))        
            
     
     dataFCA = yf.download("FCA", start="2010-01-01", end="2019-04-30")
     dataFCA.to_csv('/Users/giovannicaridi/.spyder-py3/FCA.csv')
    
          
    
      if __name__ == '__main__':        
                               
    
    # Inizializzo istanza Cerebro
    cerebro = bt.Cerebro() 
    
    # Aggiungo una strategia
    cerebro.addstrategy(Cross_Medie)
    
    # Inizializzo il file (inserisco i dati storici mettendo il percorso completo del file
    modpath = os.path.basename(os.path.abspath(sys.argv[0]))  
    datapath = os.path.join(modpath, '/Users/giovannicaridi/.spyder-py3/FCA.csv')
    
    
    # Salvo i dati nella variabile data (Create a Data Feed)
    data = bt.feeds.YahooFinanceCSVData(dataname = datapath, fromdate = datetime.datetime(2011,1,1),
                                        todate = datetime.datetime(2018,12,31),reverse = False)   
    
    # Aggiungiamo i dati a Cerebro
    cerebro.adddata(data)
    
    # Imposto il portafoglio depositando il capitale iniziale
    cerebro.broker.setcash(100000) 
    
    # Imposto il numero di azioni che traderò
    cerebro.addsizer(bt.sizers.FixedSize, stake=1000)
    
    # Imposto il valore delle commissioni
    cerebro.broker.setcommission(commission=0.0002)
    
    # Stampo le condizioni iniziali
    print('Valore iniziale Portafoglio: %.2f' % cerebro.broker.getvalue())
    
    # Avvio l'instanza (il programma)
    cerebro.run()    
    
    # Stampo le condizioni finali
    print('Valore del Portafoglio finale: %.2f' % cerebro.broker.getvalue())
    cerebro.broker.getvalue() 
    
    cerebro.plot()


  • Your script looks correct and works fine for me for data feed from the csv file.
    bt-community-3.png

    Typical reason to skip trades is not enough capital to buy the size of shares. Try to buy/sell one share at the beginning. Also print prices in the next() call, maybe data feed is added incorrectly.



  • ![0_1595496204692_FCA.csv.png](Uploading 0%) @ab_trader said in No trades happened:

    Your script looks correct and works fine for me for data feed from the csv file.
    bt-community-3.png

    Typical reason to skip trades is not enough capital to buy the size of shares. Try to buy/sell one share at the beginning. Also print prices in the next() call, maybe data feed is added incorrectly.

    I tried one share but nothing happened. Below one row of CSV coming from Yahoo, maybe there is some issue in the number's format?

    Date,Open,High,Low,Close,Adj Close,Volume
    2011-04-21,30.889999389648438,30.889999389648438,30.850000381469727,30.850000381469727,23.56662940979004,500



  • @Giovanni-Caridi said in No trades happened:

    ![0_1595496204692_FCA.csv.png](Uploading 0%) @ab_trader said in No trades happened:

    Your script looks correct and works fine for me for data feed from the csv file.
    bt-community-3.png

    Typical reason to skip trades is not enough capital to buy the size of shares. Try to buy/sell one share at the beginning. Also print prices in the next() call, maybe data feed is added incorrectly.

    I tried one share but nothing happened. Below one row of CSV coming from Yahoo, maybe there is some issue in the number's format?

    Date,Open,High,Low,Close,Adj Close,Volume
    2011-04-21,30.889999389648438,30.889999389648438,30.850000381469727,30.850000381469727,23.56662940979004,500

    I tried also this code to retrieve online data from Yahoo, but no trades happened:

    data = bt.feeds.YahooFinanceData(dataname = 'FB', fromdate =datetime.datetime(2011,1,1),todate = datetime.datetime(2018,12,31),reverse = False)
    


  • I'm not sure why you are not getting an appropriate signal from YahooFinance. Try to print out the OHLCV from next to see what data you are getting.



  • @run-out which code I need to insert?



  • @Giovanni-Caridi

    print(
        "date {}\to {:.2f} \th {:.2f} \tl {:.2f} \tc {:.2f}\tv {:9.0f}".format(
            self.datas[0].datetime.datetime(0),
            self.data.open[0],
            self.data.high[0],
            self.data.low[0],
            self.data.close[0],
            self.data.volume[0],
        )
    )
    
    


  • @run-out No print and trades

    runfile('/Users/giovannicaridi/.spyder-py3/Trading System', wdir='/Users/giovannicaridi/.spyder-py3')
    Valore iniziale Portafoglio: 100000.00
    Valore del Portafoglio finale: 100000.00
    <IPython.core.display.Javascript object>
    <IPython.core.display.HTML object>
    


  • Did you put that directly under def next(self): ?? You should have had something. Look can you copy all of your code, and put it between triple back space, so we can see all of it properly at once? Then we can help you.

    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/



  • @run-out

    from __future__ import (absolute_import, division, print_function,unicode_literals)
    import backtrader as bt
    import backtrader.indicators as btind
    import backtrader.analyzers as btanalyzers
    import datetime   # For datetime objects
    import os.path    # To manage paths
    import sys        # To find out the script name (in argv[0])
    
    
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    pd.core.common.is_list_like = pd.api.types.is_list_like
    from pandas_datareader import data, wb
    import yfinance as yf
    
    
    
     class Cross_Medie(bt.Strategy):
    
    # Definisco la media veloce e la media lenta (utile per l'ottimizzazione)
    params = (('Med_vel',50), ('Med_len', 100))
    
    # Inizializzo le due medie
    def __init__(self):
        self.sma_vel = btind.SMA(period = self.p.Med_vel)
        self.sma_len = btind.SMA(period = self.p.Med_len)
        
        # Definisco il segnale di acquisto/vendita
        self.buysig = btind.CrossOver(self.sma_vel, self.sma_len)
        
        # Salvo i dati di closing (self.datas[0] è l'orologio del sistema, 
        # utile per verificare se una candela in chiusura rompre una media/indicatore)
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        
     
    
    def next(self):
    
    print("date {}\to {:.2f} \th {:.2f} \tl {:.2f} \tc {:.2f}\tv {:9.0f}".format(
        self.datas[0].datetime.datetime(0),
        self.data.open[0],
        self.data.high[0],
        self.data.low[0],
        self.data.close[0],
        self.data.volume[0],
          ))
    
    if  self.position.size:    # verifico se sono in posizione
        
          if  self.buysig < 0:  # vuol dire che sono dentro long (incrocio a ribasso)
              self.close()     # chiudo la posizione esistente
              self.sell()      
            
          elif self.buysig > 0: # vuol dire che sono dentro short (incrocio a rialzo)
               self.close()      # chiudo la posizione esistente
               self.buy()
            
    else:                     # non sono in posizione
             
        if self.buysig > 0:   # segnale positivo 
            self.buy()        # acquisto
            
        elif self.buysig < 0: # segnale negativo
            self.sell()       # vendo
            
            
    
    
    def stampa(self, txt, dt=None):
    
    dt = dt or self.datas[0].datetime.date(0)  
    print('%s, %s' % (dt.isoformat(), txt))    
    
    
    
    def notify_order(self, order):
    
    if order.status in [order.Submitted, order.Accepted]:
        # ordine acquisto/vendita accettato
        return
    
    # Verifica se ordine completato
    if order.status in [order.Completed]:
        if order.isbuy():
            # Stampo dettaglio di quantità, prezzo e commissioni
            self.stampa('ACQ ESEGUITO, QTY: %.2f, PREZZO: %.2f, COSTO: %.2f, COMM: %.2f' 
                        % (order.executed.size,order.executed.price,order.executed.value,order.executed.comm))
    
            self.buyprice = order.executed.price
            self.buycomm = order.executed.comm
    
        else: # Vendita
            self.stampa('VEND ESEGUITA, QTY: %.2f, PREZZO: %.2f, COSTO: %.2f, COMM: %.2f' 
                        % (order.executed.size,order.executed.price,order.executed.value,order.executed.comm))
    
            self.bar_executed = len(self)
            
    elif order.status in [order.Canceled, order.Margin, order.Rejected]:
      self.stampa('Ordine Cancellato')
     
    self.order = None    
       
    
    
    def notify_trade(self, trade):
    if not trade.isclosed:
        return
    self.stampa('PROFITTO OPERAZIONE, LORDO %.2f, NETTO %.2f' % (trade.pnl, 
    trade.pnlcomm))        
            
        
    
    dataFCA = yf.download("FCA", start="2010-01-01", end="2019-04-30")
    dataFCA.to_csv('/Users/giovannicaridi/.spyder-py3/FCA.csv')
    
          
    
    if __name__ == '__main__':           
                                
    
    # Inizializzo istanza Cerebro
    cerebro = bt.Cerebro() 
    
    # Aggiungo una strategia
    cerebro.addstrategy(Cross_Medie)
    
    # Inizializzo il file (inserisco i dati storici mettendo il percorso completo del file
    modpath = os.path.basename(os.path.abspath(sys.argv[0]))  
    datapath = os.path.join(modpath, '/Users/giovannicaridi/.spyder-py3/FCA.csv')
    
    
    # Salvo i dati nella variabile data (Create a Data Feed)
    data = bt.feeds.YahooFinanceCSVData(dataname = datapath, fromdate = datetime.datetime(2011,1,1),
                                        todate = datetime.datetime(2018,12,31),reverse = False)   
    
    # Aggiungiamo i dati a Cerebro
    cerebro.adddata(data)
    
    # Imposto il portafoglio depositando il capitale iniziale
    cerebro.broker.setcash(100000) 
    
    # Imposto il numero di azioni che traderò
    cerebro.addsizer(bt.sizers.FixedSize, stake=1)
    
    # Imposto il valore delle commissioni
    cerebro.broker.setcommission(commission=0.0002)
    
    # Stampo le condizioni iniziali
    print('Valore iniziale Portafoglio: %.2f' % cerebro.broker.getvalue())
    
    # Avvio l'instanza (il programma)
    cerebro.run()    
    
    # Stampo le condizioni finali
    print('Valore del Portafoglio finale: %.2f' % cerebro.broker.getvalue())
    cerebro.broker.getvalue() 
    
    cerebro.plot()
    


  • When you put in the printout code for OHLCV I gave you, what output did you get? Did you get pricing data? Is it sorted dates going up? How does this data compare to the data that is on your hard drive that is working?



  • @run-out said in No trades happened:

    When you put in the printout code for OHLCV I gave you, what output did you get? Did you get pricing data? Is it sorted dates going up? How does this data compare to the data that is on your hard drive that is working?

    I don't have output changed with your code. Some output as before:

    [100%**] 1 of 1 completed
    Valore iniziale Portafoglio: 100000.00
    Valore del Portafoglio finale: 100000.00
    <IPython.core.display.Javascript object>
    <IPython.core.display.HTML object>



  • l've copied your code and got it printing out. Three things.

    1. Remove or comment out this:
        # dataFCA = yf.download("FCA", start="2010-01-01", end="2019-04-30")
        # dataFCA.to_csv('/Users/giovannicaridi/.spyder-py3/FCA.csv')
    
    1. Take CSV out of YahoFinanceData and you'll be able to download directly from the net.
     # Salvo i dati nella variabile data (Create a Data Feed)
        data = bt.feeds.YahooFinanceData(
            dataname="FCA",
            fromdate=datetime.datetime(2011, 1, 1),
            todate=datetime.datetime(2018, 12, 31),
            reverse=False,
        )
    
    1. I cannot tell if this is just the formatting in this forum, or your code is like this, so forgive me if I'm wrong. Your code is imporperly indented. Underneath your strategy, all your functions and init need to move in 4 spaces.
    class Cross_Medie(bt.Strategy):
    
        # Definisco la media veloce e la media lenta (utile per l'ottimizzazione)
        params = (("Med_vel", 50), ("Med_len", 100))
    
        # Inizializzo le due medie
        def __init__(self):
            self.sma_vel = btind.SMA(period=self.p.Med_vel)
            self.sma_len = btind.SMA(period=self.p.Med_len)
    

    That is all I changed, and the OHLCV are pringint out.

    Valore iniziale Portafoglio: 100000.00
    date 2011-09-14 23:59:59.999989	o 16.20 	h 16.20 	l 16.05 	c 16.12	v      2838
    date 2011-09-15 23:59:59.999989	o 16.28 	h 16.28 	l 16.27 	c 16.27	v      1290
    date 2011-09-16 23:59:59.999989	o 16.27 	h 16.27 	l 16.27 	c 16.27	v         0
    date 2011-09-19 23:59:59.999989	o 16.27 	h 16.27 	l 16.27 	c 16.27	v         0
    date 2011-09-20 23:59:59.999989	o 16.27 	h 16.27 	l 16.27 	c 16.27	v         0
    date 2011-09-21 23:59:59.999989	o 16.27 	h 16.27 	l 16.27 	c 16.27	v         0
    date 2011-09-22 23:59:59.999989	o 13.43 	h 13.43 	l 13.43 	c 13.43	v      4515
    date 2011-09-23 23:59:59.999989	o 13.43 	h 13.43 	l 13.43 	c 13.43	v         0
    date 2011-09-26 23:59:59.999989	o 13.43 	h 13.43 	l 13.43 	c 13.43	v         0
    date 2011-09-27 23:59:59.999989	o 13.43 	h 13.43 	l 13.43 	c 13.43	v         0
    

    Full code running on my machine:

    from __future__ import absolute_import, division, print_function, unicode_literals
    import backtrader as bt
    import backtrader.indicators as btind
    import backtrader.analyzers as btanalyzers
    import datetime  # For datetime objects
    import os.path  # To manage paths
    import sys  # To find out the script name (in argv[0])
    
    
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    pd.core.common.is_list_like = pd.api.types.is_list_like
    # from pandas_datareader import data, wb
    import yfinance as yf
    
    
    class Cross_Medie(bt.Strategy):
    
        # Definisco la media veloce e la media lenta (utile per l'ottimizzazione)
        params = (("Med_vel", 50), ("Med_len", 100))
    
        # Inizializzo le due medie
        def __init__(self):
            self.sma_vel = btind.SMA(period=self.p.Med_vel)
            self.sma_len = btind.SMA(period=self.p.Med_len)
    
            # Definisco il segnale di acquisto/vendita
            self.buysig = btind.CrossOver(self.sma_vel, self.sma_len)
    
            # Salvo i dati di closing (self.datas[0] è l'orologio del sistema,
            # utile per verificare se una candela in chiusura rompre una media/indicatore)
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
    
        def next(self):
            print(
                "date {}\to {:.2f} \th {:.2f} \tl {:.2f} \tc {:.2f}\tv {:9.0f}".format(
                    self.datas[0].datetime.datetime(0),
                    self.data.open[0],
                    self.data.high[0],
                    self.data.low[0],
                    self.data.close[0],
                    self.data.volume[0],
                )
            )
    
            if self.position.size:  # verifico se sono in posizione
    
                if self.buysig < 0:  # vuol dire che sono dentro long (incrocio a ribasso)
                    self.close()  # chiudo la posizione esistente
                    self.sell()
    
                elif self.buysig > 0:  # vuol dire che sono dentro short (incrocio a rialzo)
                    self.close()  # chiudo la posizione esistente
                    self.buy()
    
            else:  # non sono in posizione
    
                if self.buysig > 0:  # segnale positivo
                    self.buy()  # acquisto
    
                elif self.buysig < 0:  # segnale negativo
                    self.sell()  # vendo
    
        def stampa(self, txt, dt=None):
    
            dt = dt or self.datas[0].datetime.date(0)
            print("%s, %s" % (dt.isoformat(), txt))
    
        def notify_order(self, order):
    
            if order.status in [order.Submitted, order.Accepted]:
                # ordine acquisto/vendita accettato
                return
    
            # Verifica se ordine completato
            if order.status in [order.Completed]:
                if order.isbuy():
                    # Stampo dettaglio di quantità, prezzo e commissioni
                    self.stampa(
                        "ACQ ESEGUITO, QTY: %.2f, PREZZO: %.2f, COSTO: %.2f, COMM: %.2f"
                        % (
                            order.executed.size,
                            order.executed.price,
                            order.executed.value,
                            order.executed.comm,
                        )
                    )
    
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
    
                else:  # Vendita
                    self.stampa(
                        "VEND ESEGUITA, QTY: %.2f, PREZZO: %.2f, COSTO: %.2f, COMM: %.2f"
                        % (
                            order.executed.size,
                            order.executed.price,
                            order.executed.value,
                            order.executed.comm,
                        )
                    )
    
                    self.bar_executed = len(self)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.stampa("Ordine Cancellato")
    
            self.order = None
    
        def notify_trade(self, trade):
            if not trade.isclosed:
                return
    
            self.stampa(
                "PROFITTO OPERAZIONE, LORDO %.2f, NETTO %.2f" % (trade.pnl, trade.pnlcomm)
            )
    
        #
        # dataFCA = yf.download("FCA", start="2010-01-01", end="2019-04-30")
        # dataFCA.to_csv('/Users/giovannicaridi/.spyder-py3/FCA.csv')
    
    
    if __name__ == "__main__":
    
        # Inizializzo istanza Cerebro
        cerebro = bt.Cerebro()
    
        # Aggiungo una strategia
        cerebro.addstrategy(Cross_Medie)
    
        # Inizializzo il file (inserisco i dati storici mettendo il percorso completo del file
        modpath = os.path.basename(os.path.abspath(sys.argv[0]))
        datapath = os.path.join(modpath, "/Users/giovannicaridi/.spyder-py3/FCA.csv")
    
        # Salvo i dati nella variabile data (Create a Data Feed)
        data = bt.feeds.YahooFinanceData(
            dataname="FCA",
            fromdate=datetime.datetime(2011, 1, 1),
            todate=datetime.datetime(2018, 12, 31),
            reverse=False,
        )
    
        # Aggiungiamo i dati a Cerebro
        cerebro.adddata(data)
    
        # Imposto il portafoglio depositando il capitale iniziale
        cerebro.broker.setcash(100000)
    
        # Imposto il numero di azioni che traderò
        cerebro.addsizer(bt.sizers.FixedSize, stake=1)
    
        # Imposto il valore delle commissioni
        cerebro.broker.setcommission(commission=0.0002)
    
        # Stampo le condizioni iniziali
        print("Valore iniziale Portafoglio: %.2f" % cerebro.broker.getvalue())
    
        # Avvio l'instanza (il programma)
        cerebro.run()
    
        # Stampo le condizioni finali
        print("Valore del Portafoglio finale: %.2f" % cerebro.broker.getvalue())
        cerebro.broker.getvalue()
    
        cerebro.plot()
    
    


  • @run-out Ok I copy and paste your code and works fine. I tried also to change feed from offline version of Yahoo CSV and it works.
    I think that the issue was on formatting, I didn't think bad formatting could lead to coding errors



  • @Giovanni-Caridi said in No trades happened:

    I didn't think bad formatting could lead to coding errors

    Python is highly space/formatting dependent. Try downloading black formatter. It automatically formats your code and will try to help you if you are off.


Log in to reply
 

});