code: def handle_data(context, data):
      # This handle_data function is where the real work is done.  Our data is
      # minute-level tick data, and each minute is called a frame.  This function
      # runs on each frame of the data.
  
      # We flag the first period of each day.
      # Since cryptocurrencies trade 24/7 the `before_trading_starts` handle
      # would only execute once. This method works with minute and daily
      # frequencies.
      today = data.current_dt.floor("1D")
      if today != context.current_day:
          context.traded_today = dict()
          context.current_day = today
  
      # Preparing dictionaries for asset-level data points
      volumes = dict()
      rsis = dict()
      price_values = dict()
      cash = context.portfolio.cash
  
      for asset in context.assets:
          # We're computing the volume-weighted-average-price of the security
          # defined above, in the context.assets variable.  For this example,
          #  we're using three bars on the 15 min bars.
  
          # The frequency attribute determine the bar size. We use this
          # convention for the frequency alias:
          # http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
          prices = data.history(
              asset,
              fields="close",
              bar_count=50,
              frequency=context.CANDLE_SIZE,
          )
  
          # Ta-lib calculates various technical indicator based on price and
          # volume arrays.
  
          # In this example, we are comp
          rsi = talib.RSI(prices.values, timeperiod=14)
  
          # We need a variable for the current price of the security to compare
          #  to the average. Since we are requesting two fields, data.current()
          # returns a DataFrame with
          current = data.current(asset, fields=["close", "volume"])
          price = current["close"]
  
          # If base_price is not set, we use the current value. This is the
          # price at the first bar which we reference to calculate price_change.
          # if asset not in context.base_price:
          #     context.base_price[asset] = price
          #
          # base_price = context.base_price[asset]
          # price_change = (price - base_price) / base_price
  
          # Tracking the relevant data
          volumes[asset] = current["volume"]
          rsis[asset] = rsi[-1]
          price_values[asset] = price
          # price_changes[asset] = price_change
  
          # We are trying to avoid over-trading by limiting our trades to
          # one per day.
          if asset in context.traded_today:
              continue
  
          # Exit if we cannot trade
          if not data.can_trade(asset):
              continue
  
          # Another powerful built-in feature of the Catalyst backtester is the
          # portfolio object.  The portfolio object tracks your positions, cash,
          # cost basis of specific holdings, and more.  In this line, we
          # calculate how long or short our position is at this minute.
          pos_amount = context.portfolio.positions[asset].amount
  
          if rsi[-1] <= context.RSI_OVERSOLD and pos_amount == 0:
              log.info(
                  "{}: buying - price: {}, rsi: {}".format(
                      data.current_dt, price, rsi[-1]
                  )
              )
              # Set a style for limit orders,
              limit_price = price * 1.005
              target = 1.0 / len(context.assets)
              order_target_percent(
                  asset, target, limit_price=limit_price
              )
              context.traded_today[asset] = True
  
          elif rsi[-1] >= context.RSI_OVERBOUGHT and pos_amount > 0:
              log.info(
                  "{}: selling - price: {}, rsi: {}".format(
                      data.current_dt, price, rsi[-1]
                  )
              )
              limit_price = price * 0.995
              order_target_percent(asset, 0, limit_price=limit_price)
              context.traded_today[asset] = True
  
      # Now that we've collected all current data for this frame, we use
      # the record() method to save it. This data will be available as
      # a parameter of the analyze() function for further analysis.
      record(
          current_price=price_values,
          volume=volumes,
          rsi=rsis,
          cash=cash,
      )
  
file_path: catalyst/catalyst/examples/marketplace/mean_reversion_by_marketcap.py
imports: import os
  import tempfile
  import time
  import pandas
  import talib
  from logbook import Logger
  from catalyst import run_algorithm
  from catalyst.api import symbol, record, order_target_percent, get_dataset
  from catalyst.exchange.utils.stats_utils import set_print_settings, get_pretty_stats
  from catalyst.utils.paths import ensure_directory
label_desc: Use image node_id 2 for calling a global function with example usage: handle_data(context, data) without return types