For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Easier way to access "active" orders
-
Hi everyone in the Backtrader Community,
I just started using Backtrader and the more I learn the more I love it! I've messed around with some simple algorithms and figured I wanted to implement a "max holding period" such that if a criteria for a centain stock hasn't been met, it'll just sell if it passes the period.
Right now I have a working implementation like this:
from datetime import datetime import pandas as pd import backtrader as bt from collections import defaultdict # Create a subclass of Strategy to define the indicators and logic class SmaCross(bt.Strategy): # list of parameters which are configurable for the strategy params = dict( pfast=10, pslow=30 ) def __init__(self): self.bar_executed = {} self.inds = defaultdict(dict) for d in self.datas: self.inds[d]['smaf'] = bt.ind.SMA(d, period=self.p.pfast) self.inds[d]['smas'] = bt.ind.SMA(d, period=self.p.pslow) self.inds[d]['crossover'] = bt.ind.CrossOver(self.inds[d]['smaf'], self.inds[d]['smas']) def notify_order(self, order): if order.status in [order.Completed, order.Margin]: if order.isbuy(): self.bar_executed[order.data._name] = bt.num2date(order.executed.dt) print(['Order',order.data._name, 'BUY EXECUTED', 'Price', '{:.4f}'.format(order.executed.price), 'Cost', '{:.4f}'.format(order.executed.value), 'Time', '{}'.format(bt.num2date(order.executed.dt))]) else: if order.data._name in self.bar_executed.keys(): self.bar_executed.pop(order.data._name) print(['Order',order.data._name, 'SELL EXECUTED', 'Price', '{:.4f}'.format(order.executed.price), 'Cost', '{:.4f}'.format(order.executed.value), 'Time', '{}'.format(bt.num2date(order.executed.dt))]) def next(self): # for every stock in my data for d in self.datas: # if no position is open on this stock if not self.broker.getposition(d): if self.inds[d]['crossover'] > 0: self.buy(d) elif self.inds[d]['crossover'] < 0: self.close(d) elif self.broker.getposition(d): timeNow = d.datetime.datetime() holdingTime = (timeNow - self.bar_executed.get(d._name, timeNow)).days if holdingTime > 100: self.close(d)
So basically I keep track of open positions in the bar_executed dictionary which is being populated in the notify_order function, with their ._name and the time they where executed.
Is this the right way to do it?
-
if it works correct, than yes.