happydasch / btoandav20

Support for Oanda-V20 API in backtrader
Apache License 2.0
131 stars 52 forks source link

Is this expected `broker.getcash()` behavior? #76

Closed wayneadams closed 3 years ago

wayneadams commented 3 years ago

Hey @happydasch ,

Thanks for putting together this v20 implementation in Backtrader!

I have a question about the expected behavior of Cerebro.broker.getcash(). I was trying to test calling into my Oanda account (practice) and just return the account balance.

In the first attempt, I did not add data to cerebro.

from __future__ import (absolute_import, division, print_function,unicode_literals)

import json
from datetime import datetime

import backtrader as bt
import btoandav20 as bto

if __name__ == '__main__':

    with open("config.json", "r") as file:
        config = json.load(file)

    storekwargs = dict(
        token=config["oanda"]["token"],
        account=config["oanda"]["account"],
        practice=config["oanda"]["practice"]
    )
    store = bto.stores.OandaV20Store(**storekwargs)

    cerebro = bt.Cerebro()
    cerebro.setbroker(store.getbroker())

    print(f'Starting Portfolio Value: {cerebro.broker.getcash()}')
    cerebro.run()
    print(f'Final Portfolio Value: {cerebro.broker.getcash()}')

As my account has $999.93, I EXPECTED the print statements to output:

Starting Portfolio Value: 999.93
Final Portfolio Value: 999.93

Instead, the ACTUAL output was:

Starting Portfolio Value: 0.0
Final Portfolio Value: 0.0

In my second attempt, I added data to cerebro.

from __future__ import (absolute_import, division, print_function,unicode_literals)

import json
from datetime import datetime

import backtrader as bt
import btoandav20 as bto

if __name__ == '__main__':

    with open("config.json", "r") as file:
        config = json.load(file)

    storekwargs = dict(
        token=config["oanda"]["token"],
        account=config["oanda"]["account"],
        practice=config["oanda"]["practice"]
    )
    store = bto.stores.OandaV20Store(**storekwargs)

    datakwargs = dict(
        historical=True,
        fromdate=datetime(2021, 9, 16),
        todate=datetime(2021, 9, 17),
        timeframe=bt.TimeFrame.Minutes,
        compression=1  
    )
    data = store.getdata(dataname="EUR_USD", **datakwargs)

    cerebro = bt.Cerebro()
    cerebro.adddata(data)
    cerebro.setbroker(store.getbroker())

    print(f'Starting Portfolio Value: {cerebro.broker.getcash()}')
    cerebro.run()
    print(f'Final Portfolio Value: {cerebro.broker.getcash()}')

And the ACTUAL output was:

Starting Portfolio Value: 0.0
Final Portfolio Value: 999.9265

Is this expected?

wayneadams commented 3 years ago

Or, do you think this the expected behavior or all stores/brokers in Backtrader? If so, then sorry for the trouble, I'll go bother those maintainers 😅

happydasch commented 3 years ago

it will get available as soon as the store gets started which happens when you run cerebro. If you need the cash available before, you can just fetch it manually from oanda:

something like:

acc_summary = store.oapi.account.summary(account_no)