when I add print (BV[0])
, i get:
IndexError: array index out of range
when I add print (BV)
, i get:
<backtrader.functions.If object at 0x7f1565ab8310>
- an object somewhere in memory?
when I add print (BV[0])
, i get:
IndexError: array index out of range
when I add print (BV)
, i get:
<backtrader.functions.If object at 0x7f1565ab8310>
class tester(bt.Strategy):
def __init__(self):
h = self.data.high
l= self.data.low
c = self.data.close
BBBV = bt.And(h(-3) > h(-2), h(-2) > h(-1)) # 3 highs down in row
BBV = bt.If(BBBV, h(-1), float('Inf')) # returns h(-1) or Inf
BV = bt.If(BBV < float('Inf'), BBV, float('Inf')) # returns only non-Inf BBV? or does this do something else?
self.buy = c(0) > BV
BV = value created with bt.If
as a line in __init__
every value in this line should be < float('Inf')
buy = if c(0) > BV
scenario 1:
data = 5min ohlc
BV occurs at 9:05 am
c(0) > BV
occurs at 9:10 am
buy signal occurs
scenario 2:
data = 5min ohlc
BV occurs at 9:05 am
c(0) > BV
occurs at 9:35 am
(all prices between 9:05 and 9:35 < BV
)
buy signal does NOT occur
If c(0) > BV
occurs in the 5min bar that comes immediately after BV
then buy signal happens.
but if c(0) > BV
occurs in a 5min bar not immediately after BV
the buy signal does not happen.
Shouldn't c(0)
be compared to the last value created in the BV
line, no matter how long ago it
was created?
Why does scenario 2 happen?
How to enable a buy signal in scenario 2?
Thanks.
Test_A
def __init__(self):
self.data.high
self.data.low
self.data.close
def next(self):
h = self.data.high
l = self.data.low
c = self.data.close
buy_signal = self.data.buy_signal = c[0] > h[-1] and (h[-3] > h[-2] > h[-1])
if buy_signal:
self.buy()
elif self.position:
if c[0] < min(l[-3], l[-2], l[-1]):
self.close()
Test_B
def __init__(self):
self.data.high
self.data.low
self.data.close
def next(self):
h = self.data.high
l = self.data.low
c = self.data.close
# is the result of this logic below same as Test_A? if not,
# how to implement Test_A logic w/ bt.If/bt.And?
pattern = self.data.pattern = bt.And(h(-3) > h(-2), h(-2) > h(-1))
A = self.data.A = bt.If(pattern, h(-1), float('Inf'))
B = self.data.B = bt.If(A < float('Inf'), A(-1), float('Inf'))
buy_signal = self.data.buy_signal = bt.If(B < float('Inf'), c(0) > B(-1), False)
if buy_signal[0]: # error here: "IndexError: array index out of range"
self.buy()
elif self.position:
if c[0] < min(l[-3], l[-2], l[-1]):
self.close()
Test_B is my attempt to implement the same strategy as Test_A with the use of bt.If and bt.And.
I get this error: "IndexError: array index out of range "
Where are the flaws in the logic?
How would I compose Test_A using bt.If and bt.And?
Thanks.
@ab_trader said in IndexError: array index out of range:
def __init__(self):
Can bt.And
be used like this?:
condition = bt.And(A < float('Inf'), A > b(-1), A < c(-2), A > d(-3))
would all the A
's after the A < float('Int')
be smaller than infinity?
Thanks.
NameError: name 'buy_signal' is not defined
Get this error: NameError: name 'buy_signal' is not defined
even though I have defined 'buy_signal' in def __init__(self):
def __init__(self):
buy_signal = bt.If(A < float('Inf'), c(0) > B, False)
sell_signal = bt.If(C < float('Inf'), c(0) < D, False)
def next(self):
if buy_signal[0]:
self.buy()
elif sell_signal[0] and self.position > 0:
self.close()
Thanks.
Is bt.And
only allowed to have 2 elements for the condition description as well?
Would I be able to build or chain together a higher number of elements with and
?
for example:
condition = bt.And(d(-3) > e(-2), e(-2) > f(-1)) \
and bt.And(i(-5) > g(-4), g(-4) > d(-3))
Thanks.
@ab_trader said in IndexError: array index out of range:
infline = bt.LineNum(float('Inf'))
thanks, but the change to infline
still produces the same error:
TypeError: __bool__ should return bool, returned LineOwnOperation
x
is different from y
, because it returns d(-1)
instead of e(-1)
,
unless I am stating the bt.If
incorrectly.
Thank you, I have replaced the []
with ()
and the out of range error has gone, but now I have another error:
def __init__(self):
x = bt.If(d(-3) > e(-2) > f(-1), d(-1), float('Inf')) # new error here
# error message: TypeError: __bool__ should return bool, returned LineOwnOperation
Thanks again.
Why is this error message coming up with this line?
# error message:
return self.array[self.idx + ago]
IndexError: array index out of range
def __init__(self):
x = bt.If(d[-3] > e[-2] > f[-1], d[-1], float('Inf'))
y = bt.If(d[-3] > e[-2] > f[-1], e[-1], float('Inf'))
z = bt.If(y < float('Inf'), y[-1], float('Inf')) # error message line
Thanks.
When BackTrader is connected to a broker api (https://github.com/ftomassetti/backtrader-oandav20),
does BackTrader keep track of existing positions locally/internally, or does it retrieve that data from the broker api?
Can the user choose which option?
Thanks.
@backtrader
thank you very much for your time and assistance, you have been very helpful.
@ab_trader
I have no coding experience at all, everything i've posted here is just what I took from the documentation, so if you have time; could you show me how to only have the self.data.low
results in the line?
self.variable
that represents only the True return of a function/operator? in def __init__(self):
?if only_low[-1]>only_low[-2]:
self.buy() # enter long
"Say element [-2] has no low value (condition didn't meet) and element[-1] has low value. What do you expect from the script?"
That statement was just to show I wanted to use the most recent previous low value and the one before that for trading logic; it already assumes I have created a line without the false value (9000)return.
thanks for you help.
@ab_trader said in bt.If operator/function:
low_or_9000 = bt.If(sma1(-2) > self.data.close(-1), self.data.low, 9000.0)
Wouldn't that create a "line" with the value "9000" in it still?
I would like to create a line from function/operator result without "9000" and a line with only "self.data.low".
Is there a version of bt.If
function that only returns the True value? (instead of the True value or False value)
and
can an indexed value be used within bt.If
?
and
would I be able to call previous occurrences of function result with [-1], [-2], for a strategy?
From the documentation:
https://backtrader.com/docu/concepts/#some-non-overriden-operatorsfunctions
class MyStrategy(bt.Strategy):
def __init__(self):
sma1 = btind.SMA(self.data.close, period=15)
high_or_low = bt.If(sma1 > self.data.close, self.data.low, self.data.high)# returns Low if True, High if False
sma2 = btind.SMA(high_or_low, period=15)
I would like to use the function/operator like this:
class MyStrategy(bt.Strategy):
def __init__(self):
sma1 = btind.SMA(self.data.close, period=15)
only_low = bt.If(sma1[-2] > self.data.close[-1], self.data.low) # if sma1[-2]>close[-1] then return just the Low value
sma2 = btind.SMA(high_or_low, period=15)
and then use it in strategy like this:
def next(self):
if only_low[-1]>only_low[-2]:
self.buy() # enter long
If bt.If
cannot do this, which other function/operator would be able to?
or how would I modify bt.If
to do this?
I tried to filter out 2nd result with below, but it does not work:
class MyStrategy(bt.Strategy):
def __init__(self):
sma1 = btind.SMA(self.data.close, period=15)
low_or_9000 = bt.If(sma1[-2] > self.data.close[-1], self.data.low, 9000.0) # if sma1>close ture then return Low, false returns 9000.0
sma2 = btind.SMA(high_or_low, period=15)
self.data.only_low = low_or_9000 < 9000.0