Совместимость окружения Anytrading Gym с TF-Agents

Вопрос или проблема

Все стандартные окружения Gym/Gymnasium совместимы с агентами TwnsorFlow RL, но когда я пытался использовать TF-Agents с anytrading, я получал ошибки, потому что некоторые необходимые методы и атрибуты, похоже, отсутствуют. Например, этот код, который работает для CartoPole и других окружений Gym


env = gym.make('stocks-v0') #, df=df_features, frame_bound=(5,100), window_size=5)

def my_process_data(env):
    start = env.frame_bound[0] - env.window_size
    end = env.frame_bound[1]
    prices = env.df.loc[:, 'Close'].to_numpy()[start:end]
    signal_features = env.df.loc[:, ['volume', 'volume_delta', 'day_of_the_week', 'US_market', 'EU_market', 'AS_market', 'POC_volume', 'DPOC_buy_volume', 'DPOC_sell_volume', 'short_CVD', 'impulsive_CVD', 'avg_short_CVD', 'middle_CVD', 'middle_impulsive_CVD', 'avg_middle_CVD', 'close_delta', 'open_delta', 'high_delta', 'low_delta', 'close_%_change', 'open_%_change', 'high_%_change', 'low_%_change', 'H_shadow', 'L_shadow', 'BBANDS_short_3devdown', 'BBANDS_short_dev_delta', 'BBANDS_short_dev_delta_rolling_mean_7', 'BBANDS_short_dev_delta_rolling_mean_14', 'BBANDS_middle_dev_delta', 'BBANDS_middle_dev_delta_rolling_mean_7', 'BBANDS_middle_dev_delta_rolling_mean_14', 'RSI_14', 'RSI_7', 'ATR', 'HT_sine', 'HT_leadsine', 'HT_sine_over_leadsine', 'mfdelta', 'mfsign', 'SAR_UP_DWN', 'SAR_UP_DWN_STRENGHT', 'short_CVD_over_CVD_mean', 'middle_CVD_over_CVD_mean', 'VWAP_over_POC_price', 'VWAP_over_DPOC_buy_price', 'VWAP_over_DPOC_sell_price', 'POC_price_over_DPOC_buy_price', 'POC_price_over_DPOC_sell_price', 'DPOC_buy_price_over_DPOC_sell_price', 'short_CVD_over_CVD_mean-1', 'middle_CVD_over_CVD_mean-1', 'VWAP_over_POC_price-1', 'VWAP_over_DPOC_buy_price-1', 'VWAP_over_DPOC_sell_price-1', 'POC_price_over_DPOC_buy_price-1', 'POC_price_over_DPOC_sell_price-1', 'DPOC_buy_price_over_DPOC_sell_price-1', 'short_CVD_over_CVD_mean-2', 'middle_CVD_over_CVD_mean-2', 'VWAP_over_POC_price-2', 'VWAP_over_DPOC_buy_price-2', 'VWAP_over_DPOC_sell_price-2', 'POC_price_over_DPOC_buy_price-2', 'POC_price_over_DPOC_sell_price-2', 'DPOC_buy_price_over_DPOC_sell_price-2', 'short_CVD_over_CVD_mean-3', 'middle_CVD_over_CVD_mean-3', 'VWAP_over_POC_price-3', 'VWAP_over_DPOC_buy_price-3', 'VWAP_over_DPOC_sell_price-3', 'POC_price_over_DPOC_buy_price-3', 'POC_price_over_DPOC_sell_price-3', 'DPOC_buy_price_over_DPOC_sell_price-3', 'short_CVD_over_CVD_mean-4', 'middle_CVD_over_CVD_mean-4', 'VWAP_over_POC_price-4', 'VWAP_over_DPOC_buy_price-4', 'VWAP_over_DPOC_sell_price-4', 'POC_price_over_DPOC_buy_price-4', 'POC_price_over_DPOC_sell_price-4', 'DPOC_buy_price_over_DPOC_sell_price-4', 'high_%_change-1', 'low_%_change-1', 'open_%_change-1', 'close_%_change-1', 'high_%_change-2', 'low_%_change-2', 'open_%_change-2', 'close_%_change-2', 'high_%_change-3', 'low_%_change-3', 'open_%_change-3', 'close_%_change-3', 'high_%_change-4', 'low_%_change-4', 'open_%_change-4', 'close_%_change-4', 'high_%_change-5', 'low_%_change-5', 'open_%_change-5', 'close_%_change-5', 'impulsive_CVD_derivate', 'short_CVD_derivate', 'avg_short_CVD_derivate', 'middle_CVD_derivate', 'avg_middle_CVD_derivate', 'VWAP_derivate', 'volume_derivate', 'RSI_14_derivate', 'RSI_7_derivate', 'mama_derivate', 'impulsive_CVD_increasing', 'short_CVD_increasing', 'middle_CVD_increasing', 'avg_short_CVD_increasing', 'avg_middle_CVD_increasing', 'VWAP_increasing', 'RSI_14_increasing', 'RSI_7_increasing', 'doji', 'Engulfing', 'Marubozu', 'short_CVD_min_delayed', 'short_CVD_max_delayed', 'middle_CVD_min', 'middle_CVD_min_delayed', 'middle_CVD_max', 'middle_CVD_max_delayed', 'impulsive_CVD_min_delayed', 'impulsive_CVD_max_delayed', 'impulsive_CVD_derivate_min_delayed', 'impulsive_CVD_derivate_max_delayed', 'avg_short_CVD_min_delayed', 'avg_short_CVD_max_delayed', 'BBANDS_short_dev_delta_min_delayed', 'BBANDS_short_dev_delta_max_delayed', 'BBANDS_middle_dev_delta_min_delayed', 'BBANDS_middle_dev_delta_max_delayed', 'RSI_14_min_delayed', 'RSI_14_max_delayed', 'RSI_7_min_delayed', 'RSI_7_max_delayed', 'zero_crossing_short_CVD', 'zero_crossing_impulsive_CVD', 'zero_crossing_impulsive_CVD_derivate', 'zero_crossing_avg_short_CVD', 'H_shadow_mean_4', 'H_shadow_mean_7', 'H_shadow_mean_21', 'L_shadow_mean_4', 'L_shadow_mean_7', 'L_shadow_mean_21', 'high_delta_mean_4', 'high_shadow_mean_7', 'high_shadow_mean_21', 'low_shadow_mean_4', 'low_shadow_mean_7', 'low_shadow_mean_21', 'VWAP_mean_4_p_derivate', 'VWAP_mean_7_p_derivate', 'VWAP_mean_21_p_derivate', 'VWAP_mean_63_p_derivate', 'VWAP_mean_189_p_derivate', 'VWAP_mean_4_vs_7_delta', 'VWAP_mean_4_vs_21_delta', 'VWAP_mean_4_vs_63_delta', 'VWAP_mean_4_vs_189_delta', 'VWAP_mean_7_vs_21_delta', 'VWAP_mean_7_vs_63_delta', 'VWAP_mean_7_vs_189_delta', 'VWAP_mean_21_vs_63_delta', 'VWAP_mean_21_vs_189_delta', 'VWAP_mean_63_vs_189_delta', 'close_vs_VWAP_4', 'close_vs_VWAP_7', 'close_vs_VWAP_21', 'close_vs_VWAP_63', 'close_vs_VWAP_189', 'open_vs_VWAP_4', 'open_vs_VWAP_7', 'open_vs_VWAP_21', 'open_vs_VWAP_63', 'open_vs_VWAP_189', 'low_vs_VWAP_4', 'low_vs_VWAP_7', 'low_vs_VWAP_21', 'low_vs_VWAP_63', 'low_vs_VWAP_189', 'high_vs_VWAP_4', 'high_vs_VWAP_7', 'high_vs_VWAP_21', 'high_vs_VWAP_63', 'high_vs_VWAP_189', 'zigzag_trigger', 'CO/HL', 'CO_sign', 'HL_delta', 'CO_delta', 'CO_delta_ratio_-1', 'CO_delta_ratio_-2', 'CO_delta_ratio_-3', 'Bar_relative_POC_price', 'Bar_relative_VWAP_price', 'US_central_time_seconds', 'cumulative_volume_mean_delta', 'HL_rolling_fw_mean']].to_numpy()[start:end]
    return prices, signal_features


class MyForexEnv(StocksEnv):
    _process_data = my_process_data


env = MyForexEnv(df=df_features, window_size=512, frame_bound=(512, len(df_features)))

[...]


from tf_agents.environments import utils

utils.validate_py_environment(env, episodes=5)
env = tf_py_environment.TFPyEnvironment(env)


возвращает эту ошибку

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[154], line 3
      1 features_n = df_features.shape[1]-4
      2 from tf_agents.environments import utils
----> 3 utils.validate_py_environment(env, episodes=5)
      5 env = tf_py_environment.TFPyEnvironment(env)
      7 q_net = q_network.QNetwork(env.observation_spec(), 
      8                            env.action_spec(), 
      9                            fc_layer_params = (features_n, features_n*10, features_n/8), 
     10                            activation_fn = activation_function,
     11                            dropout_layer_params = None)

File ~\AppData\Roaming\Python\Python310\site-packages\tf_agents\environments\utils.py:58, in validate_py_environment(environment, episodes, observation_and_action_constraint_splitter)
     52 def validate_py_environment(
     53     environment: py_environment.PyEnvironment,
     54     episodes: int = 5,
     55     observation_and_action_constraint_splitter: Optional[
     56         types.Splitter] = None):
     57   """Validate the environment follows the defined specs."""
---> 58   time_step_spec = environment.time_step_spec()
     59   action_spec = environment.action_spec()
     61   random_policy = random_py_policy.RandomPyPolicy(
     62       time_step_spec=time_step_spec,
     63       action_spec=action_spec,
     64       observation_and_action_constraint_splitter=(
     65           observation_and_action_constraint_splitter))

AttributeError: 'MyForexEnv' object has no attribute 'time_step_spec

Можно ли использовать любое окружение trading с TF-Agents?

Я подготовил фрагмент кода, который может помочь.

Предоставленный код вводит класс GymWrapper, специально разработанный для адаптации любого (gym) окружения для бесшовной интеграции с TF-Agents. Используя этот класс GymWrapper, вы сможете легко преодолеть разрыв между anytrading и TF-Agents.

Он гарантирует, что все необходимые методы и атрибуты правильно реализованы, что позволяет вам использовать TF-Agents в вашем окружении anytrading.

Посмотрите на фрагмент кода ниже:

from tf_agents.environments.tf_py_environment import TFPyEnvironment
from tf_agents.trajectories import time_step as ts
from tf_agents.environments import py_environment
from tf_agents.specs import array_spec
import gym_anytrading.datasets as DS

class GymWrapper(py_environment.PyEnvironment):
    def __init__(self, gym_env):
        super(GymWrapper, self).__init__()
        self._gym_env = gym_env
        self._action_spec = self._get_action_spec()
        self._observation_spec = self._get_observation_spec()
    def _get_action_spec(self):
        action_space = self._gym_env.action_space
        if isinstance(action_space, gym.spaces.Box):
            return array_spec.BoundedArraySpec(
                shape=action_space.shape,
                dtype=action_space.dtype,
                minimum=action_space.low,
                maximum=action_space.high
            )
        elif isinstance(action_space, gym.spaces.Discrete):
            return array_spec.BoundedArraySpec(
                shape=(),
                dtype=action_space.dtype,
                minimum=0,
                maximum=action_space.n-1
            )
        else:
            raise ValueError(f"Unsupported action space type: {type(action_space)}")

    def _get_observation_spec(self):
        observation_space = self._gym_env.observation_space
        return array_spec.ArraySpec(
            shape=observation_space.shape,
            dtype=observation_space.dtype
        )

    def action_spec(self):
        return self._action_spec

    def observation_spec(self):
        return self._observation_spec

    def _reset(self):
        return ts.restart(self._gym_env.reset())

    def _step(self, action):
        obs, reward, done, info = self._gym_env.step(action)
        if done:
            return ts.termination(obs, reward)
        else:
            return ts.transition(obs, reward)
env = gym.make('forex-v0', df=DS.FOREX_EURUSD_1H_ASK, window_size = 10, frame_bound=(10, len(DS.FOREX_EURUSD_1H_ASK) - 1), unit_side="right");

train_py_env = GymWrapper(env);
eval_py_env = GymWrapper(env);

train_env = TFPyEnvironment(train_py_env);
eval_env = TFPyEnvironment(eval_py_env);

Примечание:

Frame Bound: При использовании параметра frame_bound убедитесь, что вы установили его как frame_bound=(10, len(DS.FOREX_EURUSD_1H_ASK)-1). Это гарантирует, что пределы кадров соответствуют размеру вашего набора данных anytrading. Уклонение от этого формата может привести к ошибкам. (Когда я использовал frame_bound=(10, 300), я получил ошибку.

Сброс окружения: Важно вызвать train_env.reset() в начале или в конце вашего цикла обучения, чтобы правильно инициализировать состояние окружения. Это гарантирует, что каждая серия начинается с чистого состояния.

Ответ или решение

Совместимость среды anytrading Gym с TF-Agents

Современная экосистема для разработки и тестирования алгоритмов машинного обучения и глубокого обучения предлагает множество инструментов и библиотек. Одними из таких инструментов являются библиотека Gym (включая Gymnasium) для создания стандартных сред и TF-Agents для работы с TensorFlow в области усиленного обучения. Однако совместимость между этими инструментами может вызвать затруднения, особенно когда дело касается среды anytrading.

Проблема совместимости

Ваша проблема заключается в том, что при попытке интеграции среды anytrading с TF-Agents возникают ошибки, указывающие на отсутствие определенных методов и атрибутов, которые TF-Agents ожидает от своей среды. В частности, ошибка AttributeError: 'MyForexEnv' object has no attribute 'time_step_spec' указывает на то, что у вашего класса MyForexEnv отсутствует необходимый метод time_step_spec.

Решение проблемы

Для корректного использования среды anytrading в TF-Agents рекомендуется обернуть Gym-среду в адаптер, который будет реализовывать необходимые спецификации и методы. Ниже представлено общее решение с использованием класса GymWrapper.

from tf_agents.environments.tf_py_environment import TFPyEnvironment
from tf_agents.trajectories import time_step as ts
from tf_agents.environments import py_environment
from tf_agents.specs import array_spec
import gym_anytrading.datasets as DS

class GymWrapper(py_environment.PyEnvironment):
    def __init__(self, gym_env):
        super(GymWrapper, self).__init__()
        self._gym_env = gym_env
        self._action_spec = self._get_action_spec()
        self._observation_spec = self._get_observation_spec()

    def _get_action_spec(self):
        action_space = self._gym_env.action_space
        if isinstance(action_space, gym.spaces.Box):
            return array_spec.BoundedArraySpec(
                shape=action_space.shape,
                dtype=action_space.dtype,
                minimum=action_space.low,
                maximum=action_space.high
            )
        elif isinstance(action_space, gym.spaces.Discrete):
            return array_spec.BoundedArraySpec(
                shape=(),
                dtype=action_space.dtype,
                minimum=0,
                maximum=action_space.n-1
            )
        else:
            raise ValueError(f"Unsupported action space type: {type(action_space)}")

    def _get_observation_spec(self):
        observation_space = self._gym_env.observation_space
        return array_spec.ArraySpec(
            shape=observation_space.shape,
            dtype=observation_space.dtype
        )

    def action_spec(self):
        return self._action_spec

    def observation_spec(self):
        return self._observation_spec

    def _reset(self):
        return ts.restart(self._gym_env.reset())

    def _step(self, action):
        obs, reward, done, info = self._gym_env.step(action)
        if done:
            return ts.termination(obs, reward)
        else:
            return ts.transition(obs, reward)

env = gym.make('forex-v0', df=DS.FOREX_EURUSD_1H_ASK, window_size=10, frame_bound=(10, len(DS.FOREX_EURUSD_1H_ASK) - 1), unit_side="right")

train_py_env = GymWrapper(env)
eval_py_env = GymWrapper(env)

train_env = TFPyEnvironment(train_py_env)
eval_env = TFPyEnvironment(eval_py_env)

Важные моменты

  1. Спецификации действия и наблюдений: Обратите внимание на корректное извлечение спецификаций для действий и наблюдений из среды Gym. Это критически важно для успешной работы TF-Agents.

  2. Параметры frame_bound: Убедитесь, что параметры frame_bound заданы корректно, чтобы они совпадали с размерами вашего набора данных anytrading. Неправильные параметры могут привести к ошибкам.

  3. Сброс среды: Важно вызывать reset() для среды в начале или конце каждого цикла обучения, чтобы обеспечить чистое состояние для каждой серии.

Заключение

Интеграция среды anytrading с TF-Agents возможна и требует всего лишь обернуть Gym-среду в адаптер, который реализует необходимые методы. Следуя приведенным рекомендациям, вы сможете успешно интегрировать ваши среды и использовать мощные инструменты TensorFlow для обучения ваших моделей.

Это решение обеспечит вам плавный переход к использованию TF-Agents с любыми Gym-средами, включая those из библиотеки anytrading. Удачи в ваших экспериментах с усиленным обучением!

Оцените материал
Добавить комментарий

Капча загружается...