tensortrade-org / tensortrade

An open source reinforcement learning framework for training, evaluating, and deploying robust trading agents.
https://discord.gg/ZZ7BGWh
Apache License 2.0
4.52k stars 1.02k forks source link

A typo in the date_format of the ScreenLogger class needs to be fixed. #384

Closed Elfet closed 2 years ago

Elfet commented 2 years ago

This is my first time writing an Issue, so there may be some poor parts.

System information

Describe the current behavior The problem occurred when I was working on the Renderers and Plotly Chart in Example. When I ran agent.train, I got an Invalid format string error at the ScreenLogger Class, as shown below. This error was caused by incorrect formatting, so I fixed it and the error went away.


File \tensortrade\env\default\renderers.py:218, in ScreenLogger.render_env(self, episode, max_episodes, step, max_steps, price_history, net_worth, performance, trades)
    209 def render_env(self,
    210                episode: int = None,
    211                max_episodes: int = None,
   (...)
    216                performance: pd.DataFrame = None,
    217                trades: 'OrderedDict' = None):
--> 218     print(self._create_log_entry(episode, max_episodes, step, max_steps, date_format=self._date_format))

File \tensortrade\env\default\renderers.py:109, in BaseRenderer._create_log_entry(episode, max_episodes, step, max_steps, date_format)
     82 @staticmethod
     83 def _create_log_entry(episode: int = None,
     84                       max_episodes: int = None,
     85                       step: int = None,
     86                       max_steps: int = None,
     87                       date_format: str = "%Y-%m-%d %H:%M:%S %p") -> str:
     88     """
     89     Creates a log entry to be used by a renderer.
     90 
   (...)
    107         a log entry
    108     """
--> 109     log_entry = f"[{datetime.now().strftime(date_format)}]"
    111     if episode is not None:
    112         log_entry += f" Episode: {episode + 1}/{max_episodes if max_episodes else ''}"

ValueError: Invalid format string

Describe the expected behavior Changed the date_format of the Init method of the ScreenLogger Class as follows.

// before change
def __init__(self, date_format: str = "%Y-%m-%d %-I:%M:%S %p"):
        super().__init__()
        self._date_format = date_format

// after change
def __init__(self, date_format: str = "%Y-%m-%d %I:%M:%S %p"):
        super().__init__()
        self._date_format = date_format

Code to reproduce the issue
I used the data generated by the following for df.

# ccxtを使って、取引所からデータを取得
import pandas as pd
import ccxt
import datetime
import os
import pickle

def data_to_df(data):
    # CCXTから取得したデータをDataFrameに変換
    df = pd.DataFrame(
        data, columns=["date", "open", "high", "low", "close", "volume"]
    )
    df["date"] = pd.to_datetime(df["date"] / 1000, unit="s")
    df.set_index("date", inplace=True)
    return df

def get_data(ticker, start_date, timeframe="5m"):
    # 取引所のリミットレート(アクセス制限)を超えないように設定
    exchange = ccxt.bybit({"enableRateLimit": True})
    df = data_to_df(
        exchange.fetch_ohlcv(
            ticker, 
            timeframe=timeframe, 
            since=start_date,
            params={"reverse": False})
    )
    return df

def save_ohlcv(exchange, symbol, start_date, timeframe="5m"):
    # ファイルがない場合に作成する
    if not os.path.exists(f'./{exchange}_{symbol}_{timeframe}.pkl'):
        df = get_data(symbol, start_date, timeframe)
        df.to_pickle(f'./{exchange}_{symbol}_{timeframe}.pkl')

    # ファイルの最後が最近だったら取得しない。
    with open(f'./{exchange}_{symbol}_{timeframe}.pkl', 'rb') as f:
        df = pd.read_pickle(f'./{exchange}_{symbol}_{timeframe}.pkl')
        last_raw_date = pickle.load(f)[-1:].index[0]
        if last_raw_date > datetime.datetime.now() - datetime.timedelta(days=5):
            return 

    # 最近までを取得して、保存する。
    while True:
        last_raw_date = df[-1:].index[0]
        if last_raw_date > datetime.datetime.now() - datetime.timedelta(days=5):
            break
        df = pd.concat([df, get_data(symbol, last_raw_date.timestamp() * 1000, timeframe)]).drop_duplicates()
    with open(f'./{exchange}_{symbol}_{timeframe}.pkl', 'wb') as f:
        pickle.dump(df, f)

start_date = int(datetime.datetime(2022, 1, 1, 10, 20).timestamp() * 1000)
save_ohlcv("bybit", "BTCUSDT", start_date)

df = pd.read_pickle(f'./bybit_BTCUSDT_5m.pkl')
df.reset_index(inplace=True)
df.sort_values(by='date', ascending=True, inplace=True)
df['date'] = df['date'].dt.strftime('%Y-%m-%d %I:%M %p')
df

Other info / logs
Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached.

carlogrisetti commented 2 years ago

Should be ok with those two changes, which also switch the format to 24-hour