class_docstr: Maintain states of the environment. SAOEStateAdapter accepts execution results and update its internal state
  according to the execution results with additional information acquired from executors & exchange. For example,
  it gets the dealt order amount from execution results, and get the corresponding market price / volume from
  exchange.
  
  Example usage::
  
      adapter = SAOEStateAdapter(...)
      adapter.update(...)
      state = adapter.saoe_state
class_docstr_tok: ["Maintain","states","of","the","environment",".","SAOEStateAdapter","accepts","execution","results","and","update","its","internal","state","according","to","the","execution","results","with","additional","information","acquired","from","executors","&","exchange",".","For","example",",","it","gets","the","dealt","order","amount","from","execution","results",",","and","get","the","corresponding","market","price","\/","volume","from","exchange",".","Example","usage",":",":","adapter","=","SAOEStateAdapter","(","...",")","adapter.update","(","...",")","state","=","adapter.saoe_state"]
code: def update(
      self,
      execute_result: list,
      last_step_range: Tuple[int, int],
  ) -> None:
      last_step_size = last_step_range[1] - last_step_range[0] + 1
      start_time = self.backtest_data.ticks_index[last_step_range[0]]
      end_time = self.backtest_data.ticks_index[last_step_range[1]]
  
      exec_vol = np.zeros(last_step_size)
      for order, _, __, ___ in execute_result:
          idx, _ = get_day_min_idx_range(
              order.start_time,
              order.end_time,
              f"{self.data_granularity}min",
              REG_CN,
          )
          exec_vol[idx - last_step_range[0]] = order.deal_amount
  
      if exec_vol.sum() > self.position and exec_vol.sum() > 0.0:
          if exec_vol.sum() > self.position + 1.0:
              warnings.warn(
                  f"Sum of execution volume is {exec_vol.sum()} which is larger than "
                  f"position + 1.0 = {self.position} + 1.0 = {self.position + 1.0}. "
                  f"All execution volume is scaled down linearly to ensure that their sum does not position."
              )
          exec_vol *= self.position / (exec_vol.sum())
  
      market_volume = cast(
          IndexData,
          self.exchange.get_volume(
              self.order.stock_id,
              pd.Timestamp(start_time),
              pd.Timestamp(end_time),
              method=None,
          ),
      )
      market_price = cast(
          IndexData,
          self.exchange.get_deal_price(
              self.order.stock_id,
              pd.Timestamp(start_time),
              pd.Timestamp(end_time),
              method=None,
              direction=self.order.direction,
          ),
      )
      market_price = fill_missing_data(
          np.array(market_price, dtype=float).reshape(-1)
      )
      market_volume = fill_missing_data(
          np.array(market_volume, dtype=float).reshape(-1)
      )
  
      assert market_price.shape == market_volume.shape == exec_vol.shape
  
      # Get data from the current level executor's indicator
      current_trade_account = self.executor.trade_account
      current_df = (
          current_trade_account.get_trade_indicator().generate_trade_indicators_dataframe()
      )
      self.history_exec = dataframe_append(
          self.history_exec,
          self._collect_multi_order_metric(
              order=self.order,
              datetime=_get_all_timestamps(
                  start_time,
                  end_time,
                  include_end=True,
                  granularity=ONE_MIN * self.data_granularity,
              ),
              market_vol=market_volume,
              market_price=market_price,
              exec_vol=exec_vol,
              pa=current_df.iloc[-1]["pa"],
          ),
      )
  
      self.history_steps = dataframe_append(
          self.history_steps,
          [
              self._collect_single_order_metric(
                  self.order,
                  self.cur_time,
                  market_volume,
                  market_price,
                  exec_vol.sum(),
                  exec_vol,
              ),
          ],
      )
  
      # Do this at the end
      self.position -= exec_vol.sum()
  
      self.cur_time = self._next_time()
  
imports: from __future__ import annotations
  import collections
  from types import GeneratorType
  from typing import Any, Callable, cast, Dict, Generator, List, Optional, Tuple, Union
  import warnings
  import numpy
  import pandas
  import torch
  from tianshou.data import Batch
  from tianshou.policy import BasePolicy
  from qlib.backtest import CommonInfrastructure, Order
  from qlib.backtest.decision import BaseTradeDecision, TradeDecisionWithDetails, TradeDecisionWO, TradeRange
  from qlib.backtest.exchange import Exchange
  from qlib.backtest.executor import BaseExecutor
  from qlib.backtest.utils import LevelInfrastructure, get_start_end_idx
  from qlib.constant import EPS, ONE_MIN, REG_CN
  from qlib.rl.data.native import IntradayBacktestData, load_backtest_data
  from qlib.rl.interpreter import ActionInterpreter, StateInterpreter
  from qlib.rl.order_execution.state import SAOEMetrics, SAOEState
  from qlib.rl.order_execution.utils import dataframe_append, price_advantage
  from qlib.strategy.base import RLStrategy
  from qlib.utils import init_instance_by_config
  from qlib.utils.index_data import IndexData
  from qlib.utils.time import get_day_min_idx_range
label_desc: Use image node_id 3 for calling the SAOEStateAdapter obj's underlying member method code with example usage: obj.update(execute_result, last_step_range) without return types