Cash balance as a trading condition
I searched this community to figure out whether a strategy based on my cash balance is possible.
Let's say I have 100K cash, I want to throttle stock buying based on my current cash balance.
It seems getcash() is part of broker class. Can I use this to implement what I explained?
@jinwook-jang I went through the documentation. Now I have a better understanding. Does anybody know whether creating an Indicator out of getcash() is possible?
@jinwook-jang I think I have to use "dynamic indictor". https://www.backtrader.com/blog/posts/2018-02-06-dynamic-indicator/dynamic-indicator/
run-out last edited by
@run-out Thank you run-out! Yes. I was playing with it.
I noticed one thing. I was trying to copy and reuse the dynamic indicator example.
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) # Import the backtrader platform import backtrader as bt class DynamicHighest(bt.Indicator): lines = ('dyn_highest',) params = dict(tradeopen=False) def next(self): print('Indicator next execution') if self.p.tradeopen: self.lines.dyn_highest = max(self.data, self.dyn_highest[-1]) class MyStrategy(bt.Strategy): def __init__(self): self.dyn_highest = DynamicHighest(self.data.high) def notify_trade(self, trade): self.dyn_highest.p.tradeopen = trade.isopen def next(self): if self.dyn_highest > 150.00: self.buy() print('ABOUT TO DO SOMETHING') if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(MyStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere modpath = os.getcwd() datapath = os.path.join(modpath, 'TQQQ.csv') # Create a Data Feed data = bt.feeds.YahooFinanceCSVData( dataname=datapath, # Do not pass values before this date fromdate=datetime.datetime(2020, 1, 1), # Do not pass values before this date todate=datetime.datetime(2020, 1, 10), # Do not pass values after this date reverse=False) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(1000.0) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=10) # 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()) # Plot the result cerebro.plot()
It appears next() function of Indicator runs first and then the Strategy next() runs. Here is the print out from the source code.
I expected Indicator.next()->Strategy.next()->.... Indicator.next()->Strategy.next(). However this is finishing the Indicator next() first, and then doing Strategy next().
Starting Portfolio Value: 1000.00 Indicator next execution Indicator next execution Indicator next execution Indicator next execution Indicator next execution Indicator next execution Strategy next execution Strategy next execution Strategy next execution Strategy next execution Strategy next execution Strategy next execution Final Portfolio Value: 1000.00
I think this is not expected behavior, right?
@jinwook-jang Ok. I found the answer. runonce=False is required.
cerebro = bt.Celibro(runonce=False)