Kismuz / btgym

Scalable, event-driven, deep-learning-friendly backtesting library
https://kismuz.github.io/btgym/
GNU Lesser General Public License v3.0
984 stars 260 forks source link

Running example and encounting error "State observation shape/range mismatch!" #56

Closed deencat closed 6 years ago

deencat commented 6 years ago

Hi Andrew,

Can you please help out on this one? I have been debugging for days without success. Thanks a lot. I have noted that the difference of space by env and returned from server is the extra metadata, as I am still trying to understand how the program operates, I have no idea about what this metadata is for. Appreciate your help in this.

Errors on files : rendering_howto, setting_up_environment_basic, setting_up_environment_full Running environment : Windows 10 (VirtualBox) -> Ubuntu 16.04 - Python 3.6.3 on Conda with Jupyter-notebook

Errors log capture:

[2018-07-11 05:07:35.173161] INFO: BTgymAPIshell_0: Data domain reset() called prior to reset_data() with [possibly inconsistent] defaults. [2018-07-11 05:07:35.181768] DEBUG: BTgymAPIshell_0: FORCE CONTROL MODE attempt: 1. Response: {'ctrl': 'send control keys: <_reset>, <_getstat>, <_render>, <_stop>.'} [2018-07-11 05:07:35.198265] DEBUG: BTgymAPIshell_0: Dataset seems ready with response: <{'ctrl': 'Reset with kwargs: {}'}> [2018-07-11 05:07:35.205795] DEBUG: BTgymAPIshell_0: FORCE CONTROL MODE attempt: 1. Response: {'ctrl': 'send control keys: <_reset>, <_getstat>, <_render>, <_stop>.'} [2018-07-11 05:07:35.608016] DEBUG: BTgymAPIshell_0: Response checker received: ({'raw_state': array([[1.11696, 1.11696, 1.11694, 1.11695], [1.11694, 1.11695, 1.11693, 1.11694], [1.11696, 1.11696, 1.11693, 1.11693], [1.11694, 1.11696, 1.11694, 1.11695], [1.11694, 1.11694, 1.1169 , 1.1169 ], [1.11689, 1.11689, 1.11667, 1.11668], [1.11669, 1.11671, 1.11661, 1.11664], [1.11664, 1.11664, 1.11656, 1.11664], [1.11662, 1.11662, 1.11659, 1.1166 ], [1.11662, 1.1167 , 1.11662, 1.11669], [1.11669, 1.11671, 1.11666, 1.11669], [1.11667, 1.11676, 1.11667, 1.11675], [1.11675, 1.11678, 1.11674, 1.11677], [1.11675, 1.11677, 1.11645, 1.11664], [1.11666, 1.11668, 1.11657, 1.11661], [1.11663, 1.11681, 1.11663, 1.11681], [1.11681, 1.11681, 1.11676, 1.11676], [1.11678, 1.11682, 1.11673, 1.11676], [1.11677, 1.11687, 1.11675, 1.11683], [1.11684, 1.11691, 1.11684, 1.11685], [1.11686, 1.1169 , 1.11685, 1.11687], [1.1169 , 1.11691, 1.11671, 1.11671], [1.11672, 1.11675, 1.11643, 1.11657], [1.11657, 1.11667, 1.11657, 1.11661], [1.11664, 1.11676, 1.11664, 1.11676], [1.11677, 1.11677, 1.1166 , 1.11661], [1.11668, 1.11668, 1.11662, 1.11665], [1.11666, 1.11666, 1.11661, 1.11661], [1.1166 , 1.11661, 1.11654, 1.11656], [1.11656, 1.11661, 1.11649, 1.11655]]), 'metadata': {'type': array(0), 'trial_num': array(0), 'trial_type': array(0), 'sample_num': array(0), 'first_row': array(0), 'timestamp': array(1.4725377e+09)}}, 0.0, False, [{'step': 0, 'time': datetime.datetime(2016, 8, 30, 2, 15), 'action': 'hold', 'brokermessage': '', 'broker_cash': 100.0, 'broker_value': 100.0, 'drawdown': 0.0, 'max_drawdown': 0.0}]) as type: <class 'tuple'> [2018-07-11 05:07:35.613350] ERROR: BTgymAPIshell_0: State observation shape/range mismatch! Space set by env:

raw_state: Box(30, 4), low: 1.03522, high: 1.1616

Space returned by server:

raw_state: array of shape: (30, 4), low: 1.11643, high: 1.11696

metadata: type: array of shape: (), low: 0, high: 0

trial_num: array of shape: (), low: 0, high: 0

trial_type: array of shape: (), low: 0, high: 0

sample_num: array of shape: (), low: 0, high: 0

first_row: array of shape: (), low: 0, high: 0

timestamp: array of shape: (), low: 1472537700.0, high: 1472537700.0

Full response: {'raw_state': array([[1.11696, 1.11696, 1.11694, 1.11695], [1.11694, 1.11695, 1.11693, 1.11694], [1.11696, 1.11696, 1.11693, 1.11693], [1.11694, 1.11696, 1.11694, 1.11695], [1.11694, 1.11694, 1.1169 , 1.1169 ], [1.11689, 1.11689, 1.11667, 1.11668], [1.11669, 1.11671, 1.11661, 1.11664], [1.11664, 1.11664, 1.11656, 1.11664], [1.11662, 1.11662, 1.11659, 1.1166 ], [1.11662, 1.1167 , 1.11662, 1.11669], [1.11669, 1.11671, 1.11666, 1.11669], [1.11667, 1.11676, 1.11667, 1.11675], [1.11675, 1.11678, 1.11674, 1.11677], [1.11675, 1.11677, 1.11645, 1.11664], [1.11666, 1.11668, 1.11657, 1.11661], [1.11663, 1.11681, 1.11663, 1.11681], [1.11681, 1.11681, 1.11676, 1.11676], [1.11678, 1.11682, 1.11673, 1.11676], [1.11677, 1.11687, 1.11675, 1.11683], [1.11684, 1.11691, 1.11684, 1.11685], [1.11686, 1.1169 , 1.11685, 1.11687], [1.1169 , 1.11691, 1.11671, 1.11671], [1.11672, 1.11675, 1.11643, 1.11657], [1.11657, 1.11667, 1.11657, 1.11661], [1.11664, 1.11676, 1.11664, 1.11676], [1.11677, 1.11677, 1.1166 , 1.11661], [1.11668, 1.11668, 1.11662, 1.11665], [1.11666, 1.11666, 1.11661, 1.11661], [1.1166 , 1.11661, 1.11654, 1.11656], [1.11656, 1.11661, 1.11649, 1.11655]]), 'metadata': {'type': array(0), 'trial_num': array(0), 'trial_type': array(0), 'sample_num': array(0), 'first_row': array(0), 'timestamp': array(1.4725377e+09)}} Reward: 0.0 Done: False Info: {'step': 0, 'time': datetime.datetime(2016, 8, 30, 2, 15), 'action': 'hold', 'brokermessage': '', 'broker_cash': 100.0, 'broker_value': 100.0, 'drawdown': 0.0, 'max_drawdown': 0.0}

Hint: Wrong Strategy.get_state() parameters? Traceback (most recent call last): File "../btgym/envs/backtrader.py", line 679, in reset assert self.observation_space.contains(self.env_response[0]) AssertionError [2018-07-11 05:07:35.625214] DEBUG: BTgymAPIshell_0: FORCE CONTROL MODE attempt: 1. Response: _DONE SIGNAL RECEIVED [2018-07-11 05:07:37.482174] DEBUG: BTgymAPIshell_0: FORCE CONTROL MODE attempt: 2. Response: {'ctrl': 'send control keys: <_reset>, <_getstat>, <_render>, <_stop>.'} [2018-07-11 05:07:37.498069] INFO: BTgymAPIshell_0: Exiting. Exit code: None


AssertionError Traceback (most recent call last) ~/Documents/btgym/btgym/envs/backtrader.py in reset(self, **kwargs) 678 try: --> 679 assert self.observation_space.contains(self.env_response[0]) 680

AssertionError:

During handling of the above exception, another exception occurred:

AssertionError Traceback (most recent call last)

in () ----> 1 o = env.reset() 2 #render_all_modes(env) ~/Documents/btgym/btgym/envs/backtrader.py in reset(self, **kwargs) 704 self.log.exception(msg) 705 self._stop_server() --> 706 raise AssertionError(msg) 707 708 return self.env_response[0] AssertionError: State observation shape/range mismatch! Space set by env: raw_state: Box(30, 4), low: 1.03522, high: 1.1616 Space returned by server: raw_state: array of shape: (30, 4), low: 1.11643, high: 1.11696 metadata: type: array of shape: (), low: 0, high: 0 trial_num: array of shape: (), low: 0, high: 0 trial_type: array of shape: (), low: 0, high: 0 sample_num: array of shape: (), low: 0, high: 0 first_row: array of shape: (), low: 0, high: 0 timestamp: array of shape: (), low: 1472537700.0, high: 1472537700.0
Kismuz commented 6 years ago

@deencat , thank you for report. It is indeed backward incompatibility bug I have unintentionally introduced. Basic notebooks seems to be broken, sorry for that. I plan to push major rework update in a week or so and it will be gone.

Don't mind metadata - it is not used in base examples, just need to be explicitly declared, so as a quick and dirty solution you can change environment declaration for notebooks you mentioned in a way like this(for rendering_how_to):

# additional imports:

import numpy as np
from btgym.spaces import DictSpace

# environment declaration with full explicit observation state shape:

env = BTgymEnv(
    filename='../examples/data/DAT_ASCII_EURUSD_M1_2016.csv',
    # This param is the only one changed:
    state_shape={
            'raw_state': spaces.Box(
                shape=(30, 4),
                low=-100, 
                high=100,
                dtype=np.float32,
            ),
            'metadata': DictSpace(
                {
                    'type': spaces.Box(
                        shape=(),
                        low=0,
                        high=1,
                        dtype=np.uint32
                    ),
                    'trial_num': spaces.Box(
                        shape=(),
                        low=0,
                        high=10 ** 10,
                        dtype=np.uint32
                    ),
                    'trial_type': spaces.Box(
                        shape=(),
                        low=0,
                        high=1,
                        dtype=np.uint32
                    ),
                    'sample_num': spaces.Box(
                        shape=(),
                        low=0,
                        high=10 ** 10,
                        dtype=np.uint32
                    ),
                    'first_row': spaces.Box(
                        shape=(),
                        low=0,
                        high=10 ** 10,
                        dtype=np.uint32
                    ),
                    'timestamp': spaces.Box(
                        shape=(),
                        low=0,
                        high=np.finfo(np.float64).max,
                        dtype=np.float64
                    ),
                }
            )
        },
    skip_frame=5,
    start_cash=100,
    render_ylabel='Price Lines',
    render_size_episode=(12,8),
    render_size_human=(8, 3.5),
    render_size_state=(10, 3.5),
    render_dpi=75,
    verbose=0,
)
deencat commented 6 years ago

Thanks a lot Andrew, it worked, finally I can sleep well :+1:

Please keep up the good work

Kismuz commented 6 years ago

@deencat , update, should be fixed