Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistencies in asset visualisation #244

Open
hom-bahrani opened this issue Sep 7, 2023 · 1 comment
Open

Inconsistencies in asset visualisation #244

hom-bahrani opened this issue Sep 7, 2023 · 1 comment

Comments

@hom-bahrani
Copy link

hom-bahrani commented Sep 7, 2023

Description

I am running the basic RSI example from your documentation and observed some strange behaviour

def price_event(price, symbol, state: blankly.StrategyState):
    """This function will give an updated price every 15 seconds from our definition below"""
    state.variables["history"].append(price)
    rsi = blankly.indicators.rsi(state.variables["history"])
    if rsi[-1] < 30 and not state.variables["owns_position"]:
        # Dollar cost average buy
        buy = int(state.interface.cash / price)
        state.interface.market_order(symbol, side="buy", size=buy)
        state.variables["owns_position"] = True
    elif rsi[-1] > 70 and state.variables["owns_position"]:
        # Dollar cost average sell
        curr_value = state.interface.account[state.base_asset].available
        state.interface.market_order(symbol, side="sell", size=int(curr_value))
        state.variables["owns_position"] = False

def init(symbol, state: blankly.StrategyState):
    # Download price data to give context to the algo
    state.variables["history"] = state.interface.history(
        symbol, to=150, return_as="deque", resolution=state.resolution
    )["close"]
    state.variables["owns_position"] = False

if __name__ == "__main__":
    exchange = blankly.Oanda()

    # Use our strategy helper on coinbase pro
    strategy = blankly.Strategy(exchange)

    # Run the price event function every time we check for a new price - by default that is 15 seconds
    # strategy.add_price_event(price_event, symbol="XAU-USD", resolution="15m", init=init)
    strategy.add_price_event(price_event, symbol="BCO-USD", resolution="15m", init=init)

    # Start the strategy. This will begin each of the price event ticks
    # strategy.start()
    # Or backtest using this
    results = strategy.backtest(to="1y")
    print(results)

I get a nice html plot at the end of backtesting, I noticed that the code above is using all the cash in my account [state.interface.cash](http://state.interface.cash) and that number is being used to determine buy size. But say I want a stake of e.g. $1000 rather than use all the cash in my account, when I change the code to calculate the buy size using the stake it has a bizarre effect on the BCO (crude oil) plot - the y axis is completely different? (I’ve attached the plots)

stake = 1000  # 1000 USD
buy = int(stake / price)
state.interface.market_order(symbol, side="buy", size=buy)

Any idea why this might be case? everything else is the same in both cases so I would expect the BCO plot to remain the same. The same thing happens if I manually set the size e.g. to 1 state.interface.market_order(symbol, side="buy", size=1) In this case I see the BCO plot bars are all set to 1?

Screenshot 2023-09-07 at 16 16 49 Screenshot 2023-09-07 at 16 16 21 Screenshot 2023-09-07 at 16 16 14
@EmersonDove
Copy link
Member

This seems like correct behavior, I dont't know the value of your account of course so I can't really explain why it's only trading one share, maybe by default you have slightly more cash than 1 share and its getting trunced to an int? I would have to see the numbers to get a better idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants