A strategy where a simple Moving Average crossing of SPX (data0) on the close of one day makes a trade on the open next day: Crossing upward: 1) sell order of TQQQ (data1) and 2) a buy order of SQQQ (data2) (with the cash from sell included.) And the opposite trade when crossing downward. Am supposed to be "all in" (or 97% for margin issues) on either TQQQ or SQQQ at all time.
How can I include the cash from the sell-order (of TQQQ) when the size of the buy-order (of SQQQ) is calculated?
Are these two orders defined as the same trade, is that the issue? Can I somehow define them as two separate trades, would that solve it?
(From Jupyter Notebook:)
# creating strategy
class SmaCross(bt.Strategy):
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.dataclose = self.datas[0].close
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
# To keep track of pending orders
self.order = None
# parameters
self.sma1 = bt.ind.EMA(data0, period=14)
self.sma2 = bt.ind.SMA(data0, period=40)
self.crossover = bt.ind.CrossOver(self.sma1, self.sma2)
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
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, at %.2f, shares: %.2f, total$: %.2f' %
(order.executed.price, order.executed.size, order.executed.value))
elif order.issell():
self.log('SELL EXECUTED, at %.2f, shares: %.2f, total$: %.2f' %
(order.executed.price, order.executed.size, order.executed.value))
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
# Write down: no pending order
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))
# define the logic of strategy
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close: %.2f' % self.dataclose[0])
self.log('Sma1: %.2f Sma2: %.2f Crossover?: %.1f' % (self.sma1[0], self.sma2[0], self.crossover[0]))
# Check if an order is pending ... if yes, we cannot send a 2nd one
if self.order:
return
if self.crossover > 0: #if fast crosses slow to upside
self.log('SELL SQQQ and BUY TQQQ. Crossover, %.2f' % self.crossover[0])
if self.broker.getposition(data2).size:
self.order = self.close(data2)
if not self.broker.getposition(data1).size:
self.order = self.buy(data1)
if self.crossover < 0: #crossing to the downside
self.log('SELL TQQQ and BUY SQQQ. Crossover, %.2f' % self.crossover[0])
if self.broker.getposition(data1).size:
self.order = self.close(data1)
if not self.broker.getposition(data2).size:
self.order = self.buy(data2)
####
cerebro.addsizer(bt.sizers.PercentSizer, percents=97)
cerebro.broker.set_cash(100000)
# Set the commission - 0.1% ... divide by 100 to remove the %
cerebro.broker.setcommission(commission=0.001)
####
I expected the sell to execute first, then add the cash to the account value, and then execute the buy, with size calculated from 97% av the new account value. It seems to calculate the size of the buy from 97% of the 3% that are left from the previous 97% buy-order. In this log example below you see the cash from the sell gives: 322.083,28 But the buy only use: 31.216,72 (which is from what is left of the 97% previous buy of TQQQ). And then the opposite happens on the next trade.
2021-09-20, Sma1: 4460.34 Sma2: 4456.64 Crossover?: 0.0
2021-09-21, Close: 4354.19
2021-09-21, Sma1: 4446.18 Sma2: 4454.93 Crossover?: -1.0
2021-09-21, SELL TQQQ and BUY SQQQ. Crossover, -1.00
2021-09-22, SELL EXECUTED, at 67.43, shares: -8596.34, total$: 322083.28
2021-09-22, BUY EXECUTED, at 40.25, shares: 775.57, total$: 31216.72
2021-09-22, OPERATION PROFIT, GROSS 257567.78, NET 256666.05
2021-09-22, Close: 4395.64
2021-09-22, Sma1: 4439.44 Sma2: 4454.79 Crossover?: 0.0
2021-09-23, Close: 4448.98
.........
2021-10-20, Sma1: 4437.17 Sma2: 4439.22 Crossover?: 0.0
2021-10-21, Close: 4549.78
2021-10-21, Sma1: 4452.19 Sma2: 4440.56 Crossover?: 1.0
2021-10-21, SELL SQQQ and BUY TQQQ. Crossover, 1.00
2021-10-22, SELL EXECUTED, at 36.90, shares: -775.57, total$: 31216.72
2021-10-22, BUY EXECUTED, at 71.74, shares: 7767.03, total$: 557168.13
2021-10-22, OPERATION PROFIT, GROSS -2598.16, NET -2658.00
2021-10-22, Close: 4544.90
2021-10-22, Sma1: 4464.55 Sma2: 4442.43 Crossover?: 0.0