@backtrader So obvious (when you know how) got it. Removed the globals and try except and got it to work! Thank you sir!
Latest posts made by j45p41
-
RE: Optimize Stop-Trail order values
-
RE: Bokeh Integration - Interactive Webbrowser Plotting
Many thanks! got it working now - great work.
-
RE: Bokeh Integration - Interactive Webbrowser Plotting
Hi,
thanks for the hard work here.
when installing I get the error:
byte-compiling build\bdist.win-amd64\egg\backtrader_plotting\bokeh\bokeh.py to bokeh.cpython-35.pyc File "build\bdist.win-amd64\egg\backtrader_plotting\bokeh\bokeh.py", line 41 self.figures: List[Figure] = [] ^ SyntaxError: invalid syntax
Any ideas what I am doing wrong pls?
-
Optimize Stop-Trail order values
Hi,
after posting "Create orders from CSV file" and getting quick and helpful feedabck. I have started using backtrader again and thanks to the great documentation I have now gotten to the stage where I can push in my own orders. I am now trying to:
Optimize against stop order entry price and trailing stop distance.
I have :
- declared parameters to be optimized
- referenced them under self.params.x
- added the “Strategy” hook stop method
- called the cerebro.optstategy function
However I keep getting the same value back from the broker for all variances of the optimization parameters.
Here is my code:
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) # Import the backtrader platform import backtrader as bt import backtrader.feeds as btfeed import pandas as pd class PlotScheme(object): def __init__(self): # Default plotstyle for the OHLC bars which (line -> line on close) # Other options: 'bar' and 'candle' self.style = 'line' class dataFeed(btfeed.GenericCSVData): params = ( ('dtformat', '%Y-%m-%d %H:%M:%S'), ('datetime', 0), ('open', 1), ('high', 2), ('low', 3), ('close', 4), ('volume', 5), ('openinterest', -1) ) # Create a Stratey class TestStrategy(bt.Strategy): params = ( ('trail', 10), ('distance', 3),) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataopen = self.datas[0].open self.datahigh = self.datas[0].high self.datalow = self.datas[0].low self.dataclose = self.datas[0].close self.datavolume = self.datas[0].volume # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do # print('Submitted/Accepted: ', str(self.data.datetime.time(0))) return # Check if an order has been completed # Attention: broker could reject order if not enough cash if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) print(str(self.data.datetime.time(0))) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) print(str(self.data.datetime.time(0))) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): global i,dt # Get datetime dt = self.datas[0].datetime.datetime() # Check if we are in the market try: # if not self.position: if orders['DATE'][i] == dt.strftime('%Y-%m-%d %H:%M:%S'): if orders['DIRECTION'][i] == 'BUY': self.log('OPEN BUY ORDER, %.2f' % self.dataclose[0]) self.order = self.buy(exectype=bt.Order.StopTrail, price=float(self.dataclose[0] + self.params.distance), trailamount=self.params.trail, valid=bt.Order.DAY) elif orders['DIRECTION'][i] == 'SELL': self.log('OPEN SELL ORDER, %.2f' % self.dataclose[0]) self.order = self.sell(exectype=bt.Order.StopTrail, price=float(self.dataclose[0] - self.params.distance), trailamount=self.params.trail, valid=bt.Order.DAY) i = i + 1 if dt.strftime('%H:%M') == '21:00': self.close() except: pass def stop(self): self.log('(Start distance %2d, Trail distance %2d) Ending Value %.2f' % (self.params.distance, self.params.trail, self.broker.getvalue())) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() i = 0 state = False # Add a strategy # cerebro.addstrategy(TestStrategy) strats = cerebro.optstrategy(TestStrategy,distance=range(3,8), trail=range(3,8)) datapath = os.path.join('backtrader/deepanalysis/US500/US50015m_bid_chart_data_with_vol.csv') # Create a Data Feed data = dataFeed(dataname=datapath, timeframe=bt.TimeFrame.Minutes, compression=15) # Read Orders orders = pd.read_csv('backtrader/deepanalysis/US500/US500_orders_20180601_to_20180815_Norm_priority.csv') # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(5000.0) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=1) # Set the commission cerebro.broker.setcommission(commission=0.0) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run() # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
Here is the output that i get:
C:\Users\jaspa\AppData\Local\conda\conda\envs\backtrader\python.exe C:/Users/jaspa/PycharmProjects/backtrader/US500_backtest_1.py Starting Portfolio Value: 5000.00 2018-08-15, (Start distance 3, Trail distance 6) Ending Value 5000.00 2018-08-15, (Start distance 3, Trail distance 7) Ending Value 5000.00 2018-08-15, (Start distance 6, Trail distance 7) Ending Value 5000.00 2018-08-15, (Start distance 4, Trail distance 6) Ending Value 5000.00 2018-08-15, (Start distance 3, Trail distance 3) Ending Value 5000.00 2018-08-15, (Start distance 3, Trail distance 4) Ending Value 5000.00 2018-08-15, (Start distance 4, Trail distance 3) Ending Value 5000.00 2018-08-15, (Start distance 5, Trail distance 5) Ending Value 5000.00 2018-08-15, (Start distance 4, Trail distance 5) Ending Value 5000.00 2018-08-15, (Start distance 5, Trail distance 6) Ending Value 5000.00 2018-08-15, (Start distance 4, Trail distance 4) Ending Value 5000.00 2018-08-15, (Start distance 3, Trail distance 5) Ending Value 5000.00 2018-08-15, (Start distance 6, Trail distance 4) Ending Value 5000.00 2018-08-15, (Start distance 7, Trail distance 4) Ending Value 5000.00 2018-08-15, (Start distance 5, Trail distance 4) Ending Value 5000.00 2018-08-15, (Start distance 5, Trail distance 3) Ending Value 5000.00 2018-08-15, (Start distance 7, Trail distance 6) Ending Value 5000.00 2018-08-15, (Start distance 6, Trail distance 6) Ending Value 5000.00 2018-08-15, (Start distance 4, Trail distance 7) Ending Value 5000.00 2018-08-15, (Start distance 5, Trail distance 7) Ending Value 5000.00 2018-08-15, (Start distance 6, Trail distance 3) Ending Value 5000.00 2018-08-15, (Start distance 7, Trail distance 5) Ending Value 5000.00 2018-08-15, (Start distance 7, Trail distance 7) Ending Value 5000.00 2018-08-15, (Start distance 6, Trail distance 5) Ending Value 5000.00 2018-08-15, (Start distance 7, Trail distance 3) Ending Value 5000.00 Final Portfolio Value: 5000.00 Process finished with exit code 0
Here is the output I get when I run the strategy with the default parameter values:
C:\Users\jaspa\AppData\Local\conda\conda\envs\backtrader\python.exe C:/Users/jaspa/PycharmProjects/backtrader/US500_backtest_1.py Starting Portfolio Value: 5000.00 2018-06-05, OPEN BUY ORDER, 2748.13 2018-06-05, BUY EXECUTED, Price: 2749.75, Cost: 2749.75, Comm 0.00 19:45:00 2018-06-05, SELL EXECUTED, Price: 2751.51, Cost: 2749.75, Comm 0.00 21:15:00 2018-06-05, OPERATION PROFIT, GROSS 1.76, NET 1.76 2018-06-06, OPEN SELL ORDER, 2755.69 2018-06-07, OPEN BUY ORDER, 2775.99 2018-06-07, BUY EXECUTED, Price: 2771.76, Cost: 2771.76, Comm 0.00 20:30:00 2018-06-07, SELL EXECUTED, Price: 2771.60, Cost: 2771.76, Comm 0.00 21:15:00 2018-06-07, OPERATION PROFIT, GROSS -0.16, NET -0.16 2018-06-08, OPEN SELL ORDER, 2765.90 2018-06-12, OPEN SELL ORDER, 2784.50 2018-06-13, OPEN SELL ORDER, 2788.59 2018-06-13, SELL EXECUTED, Price: 2780.88, Cost: -2780.88, Comm 0.00 19:00:00 2018-06-13, BUY EXECUTED, Price: 2773.30, Cost: -2780.88, Comm 0.00 21:15:00 2018-06-13, OPERATION PROFIT, GROSS 7.58, NET 7.58 2018-06-14, OPEN BUY ORDER, 2783.62 2018-06-15, OPEN BUY ORDER, 2769.40 2018-06-15, BUY EXECUTED, Price: 2776.40, Cost: 2776.40, Comm 0.00 19:15:00 2018-06-15, SELL EXECUTED, Price: 2779.87, Cost: 2776.40, Comm 0.00 21:15:00 2018-06-15, OPERATION PROFIT, GROSS 3.47, NET 3.47 2018-06-18, OPEN SELL ORDER, 2761.90 2018-06-19, OPEN SELL ORDER, 2752.10 2018-06-20, OPEN BUY ORDER, 2770.13 2018-06-21, OPEN BUY ORDER, 2762.47 2018-06-21, BUY EXECUTED, Price: 2760.22, Cost: 2760.22, Comm 0.00 16:45:00 2018-06-21, SELL EXECUTED, Price: 2749.00, Cost: 2760.22, Comm 0.00 21:15:00 2018-06-21, OPERATION PROFIT, GROSS -11.22, NET -11.22 2018-06-25, OPEN SELL ORDER, 2733.98 2018-06-25, SELL EXECUTED, Price: 2720.98, Cost: -2720.98, Comm 0.00 15:00:00 2018-06-25, BUY EXECUTED, Price: 2719.10, Cost: -2720.98, Comm 0.00 21:15:00 2018-06-25, OPERATION PROFIT, GROSS 1.88, NET 1.88 2018-06-26, OPEN BUY ORDER, 2724.19 2018-06-26, BUY EXECUTED, Price: 2730.26, Cost: 2730.26, Comm 0.00 18:00:00 2018-06-26, SELL EXECUTED, Price: 2725.91, Cost: 2730.26, Comm 0.00 21:15:00 2018-06-26, OPERATION PROFIT, GROSS -4.35, NET -4.35 2018-06-27, OPEN SELL ORDER, 2730.00 2018-06-27, SELL EXECUTED, Price: 2734.02, Cost: -2734.02, Comm 0.00 16:00:00 2018-06-27, BUY EXECUTED, Price: 2702.05, Cost: -2734.02, Comm 0.00 21:15:00 2018-06-27, OPERATION PROFIT, GROSS 31.97, NET 31.97 2018-06-28, OPEN BUY ORDER, 2699.73 2018-06-28, BUY EXECUTED, Price: 2707.06, Cost: 2707.06, Comm 0.00 16:00:00 2018-06-28, SELL EXECUTED, Price: 2717.05, Cost: 2707.06, Comm 0.00 21:15:00 2018-06-28, OPERATION PROFIT, GROSS 9.99, NET 9.99 2018-06-29, OPEN BUY ORDER, 2735.20 2018-06-29, BUY EXECUTED, Price: 2743.16, Cost: 2743.16, Comm 0.00 16:00:00 2018-06-29, SELL EXECUTED, Price: 2720.23, Cost: 2743.16, Comm 0.00 21:15:00 2018-06-29, OPERATION PROFIT, GROSS -22.93, NET -22.93 2018-07-30, OPEN BUY ORDER, 2812.63 2018-07-31, OPEN BUY ORDER, 2813.06 2018-07-31, BUY EXECUTED, Price: 2819.25, Cost: 2819.25, Comm 0.00 16:45:00 2018-07-31, SELL EXECUTED, Price: 2822.88, Cost: 2819.25, Comm 0.00 21:15:00 2018-07-31, OPERATION PROFIT, GROSS 3.63, NET 3.63 2018-08-01, OPEN SELL ORDER, 2819.48 2018-08-01, SELL EXECUTED, Price: 2814.76, Cost: -2814.76, Comm 0.00 16:45:00 2018-08-01, BUY EXECUTED, Price: 2809.82, Cost: -2814.76, Comm 0.00 21:15:00 2018-08-01, OPERATION PROFIT, GROSS 4.94, NET 4.94 2018-08-02, OPEN SELL ORDER, 2799.40 2018-08-03, OPEN BUY ORDER, 2830.09 2018-08-03, BUY EXECUTED, Price: 2838.84, Cost: 2838.84, Comm 0.00 20:00:00 2018-08-03, SELL EXECUTED, Price: 2838.85, Cost: 2838.84, Comm 0.00 21:15:00 2018-08-03, OPERATION PROFIT, GROSS 0.01, NET 0.01 2018-08-06, OPEN SELL ORDER, 2837.96 2018-08-07, OPEN SELL ORDER, 2858.17 2018-08-08, OPEN BUY ORDER, 2855.45 2018-08-09, OPEN SELL ORDER, 2856.91 2018-08-09, SELL EXECUTED, Price: 2851.92, Cost: -2851.92, Comm 0.00 20:45:00 2018-08-09, BUY EXECUTED, Price: 2851.81, Cost: -2851.92, Comm 0.00 21:15:00 2018-08-09, OPERATION PROFIT, GROSS 0.11, NET 0.11 2018-08-10, OPEN SELL ORDER, 2838.98 2018-08-10, SELL EXECUTED, Price: 2829.47, Cost: -2829.47, Comm 0.00 18:45:00 2018-08-10, BUY EXECUTED, Price: 2835.86, Cost: -2829.47, Comm 0.00 21:15:00 2018-08-10, OPERATION PROFIT, GROSS -6.39, NET -6.39 2018-08-13, OPEN BUY ORDER, 2837.68 2018-08-13, BUY EXECUTED, Price: 2831.50, Cost: 2831.50, Comm 0.00 19:15:00 2018-08-13, SELL EXECUTED, Price: 2824.10, Cost: 2831.50, Comm 0.00 21:15:00 2018-08-13, OPERATION PROFIT, GROSS -7.40, NET -7.40 2018-08-14, OPEN BUY ORDER, 2831.96 2018-08-14, BUY EXECUTED, Price: 2840.96, Cost: 2840.96, Comm 0.00 15:45:00 2018-08-14, SELL EXECUTED, Price: 2839.56, Cost: 2840.96, Comm 0.00 21:15:00 2018-08-14, OPERATION PROFIT, GROSS -1.40, NET -1.40 2018-08-15, OPEN SELL ORDER, 2822.43 2018-08-15, SELL EXECUTED, Price: 2809.43, Cost: -2809.43, Comm 0.00 15:00:00 2018-08-15, (Start distance 3, Trail distance 10) Ending Value 5010.83 Final Portfolio Value: 5010.83 Process finished with exit code 0
I'm sure it is probably something obvious but we all have to start somewhere :) All help greatly appreciated!
-
RE: Create orders from CSV file
@backtrader great! And thank you. Can’t wait to get stuck into this in the morning!
-
Create orders from CSV file
Hi,
I have an external strategy that has already created my orders which have date/time stamps and order sizes.
I would like to:
- import these orders and test against OHLC data that I have in CSV files
- use backtrader to optimise with different stop and limit values
- if possible test with trailing stops
- if possible implement a mechanism that has a "trailing start" - where I monitor the status of the last closing bar and decide whether or not execute the order in this CSV file.
could somebody kindly tell me which of the above is possible with backtrader, and if possible, advise on how to implement?
-
RE: Furtures data with missing days - how to handle
@j45p41 Hi guys, with the additional info provided can you help me understand why my code is not processing trades? - thanks.
-
RE: Furtures data with missing days - how to handle
My apologies - i thought there was a problem due to discontinues dates.
here is my code in which I have disabled my analysers as they end up giving me a keyerror. When disabled I get a graph that does not execute trades.
import datetime import time import os.path import sys import backtrader as bt import backtrader.feeds as btfeed import ccxt import csv import io import pandas as pd from collections import OrderedDict from multiprocessing import Pool, cpu_count import math import os # DECLARE MODE FOR PROGRAM - OPTOMISATION OR STRATEGY opt_mode = False DEBUG = False # LOG OUTPUT TO FILE class Logger(object): def __init__(self, filename="Default.log"): self.terminal = sys.stdout self.log = open(filename, "a") def write(self, message): self.terminal.write(message) self.log.write(message) def flush(self): pass # CSV INPUT FILE FORMAT CONFIGURATION class dataFeed(btfeed.GenericCSVData): params = ( ('dtformat', '%Y%m%d'), ('datetime', 0), ('open', 1), ('high', 2), ('low', 3), ('close', 4), ('volume', 5), ('openinterest', 6) ) class OrderObserver(bt.observer.Observer): lines = ('created', 'expired',) plotinfo = dict(plot=True, subplot=True, plotlinelabels=True) plotlines = dict( created=dict(marker='*', markersize=8.0, color='lime', fillstyle='full'), expired=dict(marker='s', markersize=8.0, color='red', fillstyle='full') ) def next(self): for order in self._owner._orderspending: if order.data is not self.data: continue if not order.isbuy(): continue # Only interested in "buy" orders, because the sell orders # in the strategy are Market orders and will be immediately # executed if order.status in [bt.Order.Accepted, bt.Order.Submitted]: self.lines.created[0] = order.created.price elif order.status in [bt.Order.Expired]: self.lines.expired[0] = order.created.price # MAIN STRATEGY DEFINITION - DEFINE VALUES HERE FOR NON-OPTOMISATION MODE class firstStrategy(bt.Strategy): params = ( ("period", 28), ("rsi_low", 30), ("rsi_high", 70), ) #TRADE LOGGING FUNCTION def log(self, txt, dt=None): ''' Logging function fot this strategy''' if not opt_mode: dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.startcash = self.broker.getvalue() self.rsi = bt.indicators.RSI_SMA(self.data.close, period=self.params.period, safediv=True) #TRADE LOGGING FUNCTION def notify_trade(self, trade): if not trade.isclosed and not opt_mode: return self.log('TRADE INFO, PRICE %.2f, GROSS %.2f, NET %.2f' % (trade.price, trade.pnl, trade.pnlcomm)) def next(self): if not self.position: if self.rsi < self.params.rsi_low: self.buy(size=10) else: if self.rsi > self.params.rsi_high: self.sell(size=10) if opt_mode and DEBUG: print('period: {}, rsi low: {}, rsi high {}'.format(self.params.period,self.params.rsi_low,self.params.rsi_high)) # if opt_mode == False: # def printTradeAnalysis(analyzer): # ''' # Function to print the Technical Analysis results in a nice format. # ''' # #Get the results we are interested in # total_open = analyzer.total.open # total_closed = analyzer.total.closed # total_won = analyzer.won.total # total_lost = analyzer.lost.total # win_streak = analyzer.streak.won.longest # lose_streak = analyzer.streak.lost.longest # pnl_net = round(analyzer.pnl.net.total,2) # strike_rate = round((total_won / total_closed) * 100,2) # #Designate the rows # h1 = ['Total Open', 'Total Closed', 'Total Won', 'Total Lost'] # h2 = ['Strike Rate','Win Streak', 'Losing Streak', 'PnL Net'] # r1 = [total_open, total_closed,total_won,total_lost] # r2 = [strike_rate, win_streak, lose_streak, pnl_net] # #Check which set of headers is the longest. # if len(h1) > len(h2): # header_length = len(h1) # else: # header_length = len(h2) # #Print the rows # print_list = [h1,r1,h2,r2] # row_format ="{:<15}" * (header_length + 1) # print("Trade Analysis Results:") # for row in print_list: # print(row_format.format('',*row)) # # def printSQN(analyzer): # sqn = round(analyzer.sqn,2) # print('SQN: {}'.format(sqn)) # INPUT CONDITIONS TO FEED INTO CEREBRO IS ADDED HERE if __name__ == '__main__': sys.stdout = Logger("strat_evaluator.log") #periods = pd.DataFrame(columns=['FROM','TO'],index=[1,2,3,4,5,6,7,8,9,10,11,12]) periods = pd.DataFrame(columns=['FROM','TO'],index=[1]) periods.loc[1] = ('1990-1-01','2017-12-31') #periods.loc[2] = ('2017-02-01','2017-03-01') #periods.loc[3] = ('2017-03-01','2017-04-01') #periods.loc[4] = ('2017-04-01','2017-05-01') #periods.loc[5] = ('2017-05-01','2017-06-01') #periods.loc[6] = ('2017-06-01','2017-07-01') #periods.loc[7] = ('2017-07-01','2017-08-01') #periods.loc[8] = ('2017-08-01','2017-09-01') #periods.loc[9] = ('2017-09-01','2017-10-01') #periods.loc[10] = ('2017-10-01','2017-11-01') #periods.loc[11] = ('2017-11-01','2017-12-01') #periods.loc[12] = ('2017-12-01','2017-12-31') for index, row in periods.iterrows(): # Variable for our starting cash startcash = 10000 # Create an instance of cerebro cerebro = bt.Cerebro(optreturn=False) # Timing the whole operation time_at_start = time.time() if opt_mode: # ADD STRATEGY OPTIMISATION #cerebro.optstrategy(firstStrategy, period=range(11, 20), rsi_low=range(10, 50), rsi_high=range(51, 85)) cerebro.optstrategy(firstStrategy, period=range(13, 14), rsi_low=range(20, 21), rsi_high=range(40, 41)) cerebro.addanalyzer(bt.analyzers.SharpeRatio) else: #ADD STRATEGY cerebro.addstrategy(firstStrategy) #format dates for datafeed object fy,fm,fd = periods['FROM'][index].split('-') ty,tm,td = periods['TO'][index].split('-') #READ DATA FROM CSV FILE filename = 'tickerData/F_BO.txt' modpath = os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.join(modpath,str(filename)) data = dataFeed(dataname=datapath, timeframe=bt.TimeFrame.Days, fromdate=datetime.datetime(int(fy),int(fm),int(fd)), todate=datetime.datetime(int(ty),int(tm),int(td)),) # Add the data to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(startcash) if not opt_mode: # Add the analyzers we are interested in cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta") cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn") #WRITER TEST #cerebro.addwriter(bt.WriterFile, csv=True, rounding=2) # RUN STRATEGY THROUGH CEREBRO USING INPUT DATA # Timing the operation time_at_end = time.time() time_elapsed = round(time_at_end - time_at_start,2) print('Time elapsed: {} seconds'.format(time_elapsed)) print ('Running Cerebro') if not opt_mode: opt_runs = cerebro.run(tradehistory=False) else: opt_runs = cerebro.run(tradehistory=False, runonce = False, Exactbars=True) firstStrat = opt_runs[0] if opt_mode: # CREATE A LIST VARIABLE THAT CONTAINS RESULTS final_results_list = [] for run in opt_runs: for strategy in run: value = round(strategy.broker.get_value(), 2) PnL = round(value - startcash, 2) period = strategy.params.period rsi_low = strategy.params.rsi_low rsi_high = strategy.params.rsi_high final_results_list.append([period, rsi_low, rsi_high, PnL]) # Sort Results List by_period = sorted(final_results_list, key=lambda x: x[0]) by_PnL = sorted(final_results_list, key=lambda x: x[3], reverse=True) # PRINT RESULTS IN OPTIMISATION AND FILTER TOP 3 result_number = 0 print('Results: Ordered by Profit:') for result in by_PnL: if result_number < 3: print('Asset: {} Start: {}, End: {}, Period: {}, rsi_low: {}, rsi_high: {}, PnL: {}'.format(filename, periods['FROM'][index], periods['TO'][index], result[0], result[1], result[2], result[3])) result_number = result_number + 1 # Timing the operation time_at_end = time.time() time_elapsed = round(time_at_end - time_at_start,2) print('Time elapsed: {} seconds'.format(time_elapsed)) if opt_mode == False: # print the analyzers # printTradeAnalysis(firstStrat.analyzers.ta.get_analysis()) # printSQN(firstStrat.analyzers.sqn.get_analysis()) #Get final portfolio Value portvalue = cerebro.broker.getvalue() #Print out the final result print('Final Portfolio Value: ${}'.format(portvalue)) cerebro.plot(style='candlestick') #cerebro.plot(style='candlestick')
for completeness here is the data that I am using
DATE, OPEN, HIGH, LOW, CLOSE, VOL, OI, P, R, RINFO 19900102,11520.0000,11520.0000,11316.0000,11322.0000,19779,38563,0,0,0.0000 19900103,11322.0000,11460.0000,11298.0000,11442.0000,16270,39377,0,0,0.0000 19900104,11472.0000,11520.0000,11340.0000,11346.0000,12743,39220,0,0,0.0000 19900105,11298.0000,11466.0000,11286.0000,11418.0000,11808,39932,0,0,0.0000 19900108,11448.0000,11808.0000,11442.0000,11784.0000,20844,40091,0,0,0.0000 19900109,11730.0000,11820.0000,11682.0000,11778.0000,19457,39502,0,0,0.0000 19900110,11760.0000,11778.0000,11598.0000,11724.0000,16266,39703,0,0,0.0000 19900111,11712.0000,11790.0000,11706.0000,11754.0000,13699,39704,0,0,0.0000 19900112,11826.0000,11844.0000,11634.0000,11640.0000,12677,38444,0,0,0.0000 19900115,11598.0000,11688.0000,11580.0000,11652.0000,6067,38307,0,0,0.0000 19900116,11610.0000,11640.0000,11490.0000,11496.0000,13691,37511,0,0,0.0000 19900117,11484.0000,11616.0000,11484.0000,11502.0000,12378,38223,0,0,0.0000 19900118,11508.0000,11580.0000,11496.0000,11538.0000,8570,37584,0,0,0.0000 19900119,11562.0000,11568.0000,11400.0000,11406.0000,14732,36865,0,0,0.0000 19900122,11400.0000,11448.0000,11316.0000,11358.0000,15163,36837,0,0,0.0000 19900123,11382.0000,11508.0000,11376.0000,11466.0000,13141,36918,0,0,0.0000 19900124,11472.0000,11514.0000,11436.0000,11448.0000,10550,36551,0,0,0.0000 19900125,11472.0000,11478.0000,11340.0000,11340.0000,14579,35655,0,0,0.0000 19900126,11340.0000,11430.0000,11328.0000,11418.0000,7547,34389,0,0,0.0000 19900129,11430.0000,11544.0000,11370.0000,11538.0000,11285,34198,0,0,0.0000 19900130,11544.0000,11574.0000,11442.0000,11460.0000,12167,33318,0,0,0.0000 19900131,11460.0000,11544.0000,11430.0000,11502.0000,10708,32328,0,0,0.0000 19900201,11520.0000,11700.0000,11502.0000,11532.0000,17957,32443,0,0,0.0000 19900202,11544.0000,11580.0000,11508.0000,11568.0000,14151,31419,0,0,0.0000 19900205,11568.0000,11634.0000,11460.0000,11478.0000,14241,30695,0,0,0.0000
-
Furtures data with missing days - how to handle
Hi,
I am trying to read in futures data in the following fomat:
DATE, OPEN, HIGH, LOW, CLOSE, VOL, OI, P, R, RINFO 19900531,104687.5000,104850.0000,104387.5000,104525.0000,18592,32108,0,0,0.0000 19900601,104750.0000,105512.5000,104612.5000,104762.5000,26697,27205,0,0,0.0000 19900604,104250.0000,104562.5000,103937.5000,104437.5000,15315,25228,0,0,0.0000 19900605,104575.0000,105250.0000,104425.0000,105137.5000,18054,25452,0,0,0.0000 19900606,105187.5000,105437.5000,105112.5000,105300.0000,10104,24872,0,0,0.0000 19900607,105250.0000,105450.0000,105137.5000,105425.0000,9931,24237,199009,199009,0.0000 19900608,103562.5000,103562.5000,103125.0000,103437.5000,12791,9134,0,0,-1600.0000
I intend to trim the data so that it does not include the last three columns.
However when I run using this data, due to it not being continuous days cerebro does not process trades correctly - the graphs is plotted but the trades do not execute.
I suspect there is a setting somewhere which will allow this data to be handled.
I have read: https://www.backtrader.com/blog/posts/2016-08-31-rolling-over-futures/rolling-futures-over.html
but can't figure out how to handle this data - any suggestions pls?
-
RE: Strategy Library
@backtrader Thank you for your answer and I am sure a library will be coming together soon. I will certainly contribute as I get further into my backtrader journey :)