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.00from 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 yfclass 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.
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.
-
 @ab_trader said in No trades happened:
Your script looks correct and works fine for me for data feed from the csv file.
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:
 @ab_trader said in No trades happened:
Your script looks correct and works fine for me for data feed from the csv file.
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,500I 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?
-
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/
-
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.
- 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')
- 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, )
- 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.