class_docstr: A stock trading environment for OpenAI gym
  This environment penalizes the model if excedeed the stop-loss threshold, selling assets with under expectation %profit, and also
  for not maintaining a reserve of cash.
  This enables the model to do trading with high confidence and manage cash reserves in addition to performing trading procedures.
  
  Reward at any step is given as follows
      r_i = (sum(cash, asset_value) + additional_reward - total_penalty - initial_cash) / initial_cash / days_elapsed
      , where total_penalty = cash_penalty + stop_loss_penalty + low_profit_penalty
              cash_penalty = max(0, sum(cash, asset_value)*cash_penalty_proportion-cash)
              stop_loss_penalty = -1 * dot(holdings,negative_closing_diff_avg_buy)
              low_profit_penalty = -1 * dot(holdings,negative_profit_sell_diff_avg_buy)
              additional_reward = dot(holdings,positive_profit_sell_diff_avg_buy)
  
      This reward function takes into account a profit/loss ratio constraint, liquidity requirement, as well as long-term accrued rewards.
      This reward function also forces the model to trade only when it's really confident to do so.
  
  Parameters:
  state space: {start_cash, <owned_shares>, for s in stocks{<stock.values>}, }
      df (pandas.DataFrame): Dataframe containing data
      buy_cost_pct (float): cost for buying shares
      sell_cost_pct (float): cost for selling shares
      hmax (int): max number of share purchases allowed per asset
      discrete_actions (bool): option to choose whether perform dicretization on actions space or not
      shares_increment (int): multiples number of shares can be bought in each trade.
      stoploss_penalty (float): Maximum loss we can tolerate. Valid value range is between 0 and 1. If x is specified, then agent will force sell all holdings for a particular asset if current price < x * avg_buy_price
      profit_loss_ratio (int, float): Expected profit/loss ratio. Only applicable when stoploss_penalty < 1.
      turbulence_threshold (float): Maximum turbulence allowed in market for purchases to occur. If exceeded, positions are liquidated
      print_verbosity(int): When iterating (step), how often to print stats about state of env
      initial_amount: (int, float): Amount of cash initially available
      daily_information_columns (list(str)): Columns to use when building state space from the dataframe. It could be OHLC columns or any other variables such as technical indicators and turbulence index
      cash_penalty_proportion (int, float): Penalty to apply if the algorithm runs out of cash
      patient (bool): option to choose whether end the cycle when we're running out of cash or just don't buy anything until we got additional cash
  action space: <share_dollar_purchases>
  TODO:
      add holdings to memory
      move transactions to after the clip step.
  tests:
      after reset, static strategy should result in same metrics
      given no change in prices, no change in asset values
class_docstr_tok: ["A","stock","trading","environment","for","OpenAI","gym","This","environment","penalizes","the","model","if","excedeed","the","stop-loss","threshold",",","selling","assets","with","under","expectation","%","profit",",","and","also","for","not","maintaining","a","reserve","of","cash",".","This","enables","the","model","to","do","trading","with","high","confidence","and","manage","cash","reserves","in","addition","to","performing","trading","procedures",".","Reward","at","any","step","is","given","as","follows","r_i","=","(","sum","(","cash",",","asset_value",")","+","additional_reward","-","total_penalty","-","initial_cash",")","\/","initial_cash","\/","days_elapsed",",","where","total_penalty","=","cash_penalty","+","stop_loss_penalty","+","low_profit_penalty","cash_penalty","=","max","(","0",",","sum","(","cash",",","asset_value",")","*","cash_penalty_proportion-cash",")","stop_loss_penalty","=","-1","*","dot","(","holdings",",","negative_closing_diff_avg_buy",")","low_profit_penalty","=","-1","*","dot","(","holdings",",","negative_profit_sell_diff_avg_buy",")","additional_reward","=","dot","(","holdings",",","positive_profit_sell_diff_avg_buy",")","This","reward","function","takes","into","account","a","profit\/loss","ratio","constraint",",","liquidity","requirement",",","as","well","as","long-term","accrued","rewards",".","This","reward","function","also","forces","the","model","to","trade","only","when","it","'s","really","confident","to","do","so",".","Parameters",":","state","space",":","{","start_cash",",","<","owned_shares",">",",","for","s","in","stocks","{","<","stock.values",">","}",",","}","df","(","pandas.DataFrame",")",":","Dataframe","containing","data","buy_cost_pct","(","float",")",":","cost","for","buying","shares","sell_cost_pct","(","float",")",":","cost","for","selling","shares","hmax","(","int",")",":","max","number","of","share","purchases","allowed","per","asset","discrete_actions","(","bool",")",":","option","to","choose","whether","perform","dicretization","on","actions","space","or","not","shares_increment","(","int",")",":","multiples","number","of","shares","can","be","bought","in","each","trade",".","stoploss_penalty","(","float",")",":","Maximum","loss","we","can","tolerate",".","Valid","value","range","is","between","0","and","1",".","If","x","is","specified",",","then","agent","will","force","sell","all","holdings","for","a","particular","asset","if","current","price","<","x","*","avg_buy_price","profit_loss_ratio","(","int",",","float",")",":","Expected","profit\/loss","ratio",".","Only","applicable","when","stoploss_penalty","<","1.","turbulence_threshold","(","float",")",":","Maximum","turbulence","allowed","in","market","for","purchases","to","occur",".","If","exceeded",",","positions","are","liquidated","print_verbosity","(","int",")",":","When","iterating","(","step",")",",","how","often","to","print","stats","about","state","of","env","initial_amount",":","(","int",",","float",")",":","Amount","of","cash","initially","available","daily_information_columns","(","list","(","str",")",")",":","Columns","to","use","when","building","state","space","from","the","dataframe",".","It","could","be","OHLC","columns","or","any","other","variables","such","as","technical","indicators","and","turbulence","index","cash_penalty_proportion","(","int",",","float",")",":","Penalty","to","apply","if","the","algorithm","runs","out","of","cash","patient","(","bool",")",":","option","to","choose","whether","end","the","cycle","when","we","'re","running","out","of","cash","or","just","do","n't","buy","anything","until","we","got","additional","cash","action","space",":","<","share_dollar_purchases",">","TODO",":","add","holdings","to","memory","move","transactions","to","after","the","clip","step",".","tests",":","after","reset",",","static","strategy","should","result","in","same","metrics","given","no","change","in","prices",",","no","change","in","asset","values"]
code: def current_step(self):
      return self.date_index - self.starting_point
  
imports: from __future__ import annotations
  import random
  import time
  from copy import deepcopy
  import gym
  import matplotlib
  import numpy
  import pandas
  from gym import spaces
  from stable_baselines3.common import logger
  from stable_baselines3.common.vec_env import DummyVecEnv
  from stable_baselines3.common.vec_env import SubprocVecEnv
label_desc: Use image node_id 3 for calling the StockTradingEnvStopLoss obj's underlying member method code with example usage: obj.current_step() and returns: unknown