How to implement this strategy?
-
I previously was using the following code for my strategy.
It was buy at open and readjust the portfolio the next day and I used daily data.
My strategy has changed
-
I buy at the beginning of the trading day during the first tick at open. Either a buy long or sell short or a mix of positions.
-
I close either at 3:30pm, or at a take profit level called TPL of which I set everyday for different stocks, or at a stop loss which is different for each stock. All the above data is provided via dictionaries, either at % or absolute numbers.
-
and I am currently using minute level data.
How can I change my code here to accommodate my new strategy and the minute level data?
This is my old code.
import datetime import backtrader as bt class Strategy(bt.Strategy): params = ( ("buffer", 0.05), ("threshold", 0.025), ) def log(self, txt, dt=None): """ Logging function fot this strategy""" dt = dt or self.data.datetime[0] if isinstance(dt, float): dt = bt.num2date(dt) print("%s, %s" % (dt.date(), txt)) def print_signal(self): self.log( f"o {self.datas[0].open[0]:7.2f} " f"h {self.datas[0].high[0]:7.2f} " f"l {self.datas[0].low[0]:7.2f} " f"c {self.datas[0].close[0]:7.2f} " f"v {self.datas[0].volume[0]:7.0f} " ) def notify_order(self, order): """ Triggered upon changes to orders. """ # Suppress notification if it is just a submitted order. if order.status == order.Submitted: return # Print out the date, security name, order number and status. type = "Buy" if order.isbuy() else "Sell" self.log( f"{order.data._name:<6} Order: {order.ref:3d} " f"Type: {type:<5}\tStatus" f" {order.getstatusname():<8} \t" f"Size: {order.created.size:9.4f} Price: {order.created.price:9.4f} " f"Position: {self.getposition(order.data).size:5.2f}" ) if order.status == order.Margin: return # Check if an order has been completed if order.status in [order.Completed]: self.log( f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} " # f"EXECUTED for: {dn} " f"Price: {order.executed.price:6.2f} " f"Cost: {order.executed.value:6.2f} " f"Comm: {order.executed.comm:4.2f} " f"Size: {order.created.size:9.4f} " ) def notify_trade(self, trade): """Provides notification of closed trades.""" if trade.isclosed: self.log( "{} Closed: PnL Gross {}, Net {},".format( trade.data._name, round(trade.pnl, 2), round(trade.pnlcomm, 1), ) ) def __init__(self): for d in self.datas: d.target = { datetime.datetime.strptime(date, "%d-%b-%y").date(): allocation for date, allocation in d.target.items() } def next(self): date = self.data.datetime.date() track_trades = dict() total_value = self.broker.get_value() * (1 - self.p.buffer) for d in self.datas: if date not in d.target: if self.getposition(d): self.close(d) continue target_allocation = d.target[date] track_trades[d] = dict() value = self.broker.get_value(datas=[d]) current_allocation = value / total_value net_allocation = target_allocation - current_allocation units_to_trade = ( (net_allocation) * total_value / d.close[0] ) track_trades[d]["units"] = units_to_trade # Can check to make sure there is enough distance away from ideal to trade. track_trades[d]["threshold"] = abs(net_allocation) > self.p.threshold rebalance = False for values in track_trades.values(): if values["threshold"]: rebalance = True if not rebalance: return # Sell shares first for d, value in track_trades.items(): if value["units"] < 0: self.sell(d, size=value["units"]) # Buy shares second for d, value in track_trades.items(): if value["units"] > 0: self.buy(d, size=value["units"]) if __name__ == "__main__": cerebro = bt.Cerebro() allocations = [ ("AAPL", "4-Jan-21", 0.300), ("TSM", "4-Jan-21", 0.200), ("IBM", "4-Jan-21", 0.300), ("KO", "4-Jan-21", 0.2000), ("AMD", "4-Jan-21", 0.1000), ("DELL", "5-Jan-21", 0.200), ("TSM", "5-Jan-21", 0.20), ("IBM", "5-Jan-21", 0.1), ("KO", "5-Jan-21", 0.1), ("NKE", "5-Jan-21", 0.15), ("TSLA", "5-Jan-21", 0.10), ("CSCO", "5-Jan-21", 0.050), ("JPM", "5-Jan-21", 0.1), ("AMD", "6-Jan-21", 0.25), ("BA", "6-Jan-21", 0.25), ("ORCL", "6-Jan-21", 0.50), ("AAPL", "7-Jan-21", 0.5000), ("KO", "7-Jan-21", 0.5000), ] ticker_names = list(set([alls[0] for alls in allocations])) targets = {ticker: {} for ticker in ticker_names} for all in allocations: targets[all[0]].update({all[1]: all[2]}) for ticker, target in targets.items(): data = bt.feeds.YahooFinanceData( dataname=ticker, timeframe=bt.TimeFrame.Days, fromdate=datetime.datetime(2020, 12, 21), todate=datetime.datetime(2021, 1, 8), reverse=False, ) data.target = target cerebro.adddata(data, name=ticker) cerebro.addstrategy(Strategy) cerebro.broker.setcash(1000000) # Execute cerebro.run()
This is the new minute level data I have. Each company has it's own one.
datetime open high low close vol 2022-04-28 20:00:00 159.057356 159.146814 158.938077 159.047416 21258 2022-04-28 19:59:00 159.156754 159.156754 159.057356 159.087175 8309 2022-04-28 19:58:00 158.987777 159.186573 158.987777 159.146814 29998 2022-04-28 19:57:00 158.948017 159.007656 158.948017 158.987777 25346 2022-04-28 19:56:00 158.948017 158.977837 158.938077 158.948017 9495 ... ... ... ... ... ... 2022-03-30 04:05:00 176.670756 176.670756 176.630997 176.630997 1024 2022-03-30 04:04:00 177.068350 177.068350 177.068350 177.068350 1112 2022-03-30 04:03:00 177.088229 177.088229 177.088229 177.088229 714 2022-03-30 04:02:00 177.068350 177.177688 177.068350 177.177688 402 2022-03-30 04:01:00 177.426184 177.426184 177.028590 177.127989 3146
This is the dataframe of my allocations for each day
allocations = [ ("AAPL", "4-Jan-21", 0.300), ("TSM", "4-Jan-21", 0.200), ("IBM", "4-Jan-21", 0.300), ("KO", "4-Jan-21", 0.2000), ("AMD", "4-Jan-21", 0.1000), ("DELL", "5-Jan-21", 0.200), ("TSM", "5-Jan-21", 0.20), ("IBM", "5-Jan-21", 0.1), ("KO", "5-Jan-21", 0.1), ("NKE", "5-Jan-21", 0.15), ("TSLA", "5-Jan-21", 0.10), ("CSCO", "5-Jan-21", 0.050), ("JPM", "5-Jan-21", 0.1), ("AMD", "6-Jan-21", 0.25), ("BA", "6-Jan-21", 0.25), ("ORCL", "6-Jan-21", 0.50), ("AAPL", "7-Jan-21", 0.5000), ("KO", "7-Jan-21", 0.5000), ]
These are my take profit and stop loss levels.
takeprofit= [ ("AAPL", "4-Jan-21", 0.0700), ("TSM", "4-Jan-21", 0.02200), ........ ......... ]
stoploss= [ ("AAPL", "4-Jan-21", 0.100), ("TSM", "4-Jan-21", 0.0700), ........ ......... ]
How can I modify the code to accommodate the new strategy and data?
-