pythonlistalgorithmalgorithmic-trading

Filtering paused stocks: TypeError: string indices must be integers


# Import JoinQuant Library
import jqdata
import pandas as pd
from jqdata import finance

# Initialize functions, and setting benchmarks etc.
def initialize(context):
    # Setting HS300(00300.XSHG) as benchmark
    set_benchmark('000300.XSHG')
    # Start active back-adjustment mode, i.e. real price.
    set_option('use_real_price', True)
    # Setting commissions for stock trading:0.03% when buying,0.03% plus 0.1% stamp duty when    selling, with 5 RMB minimum per transaction cost.
    set_order_cost(OrderCost(close_tax = 0.001, open_commission = 0.0003, close_commission = 0.0003, min_commission = 5), type = 'stock')
    # Setting commissions for index futures trading: 0.0023% when buying & selling, 0.23% when closing today's positions.
    set_order_cost(OrderCost(open_commission = 0.000023, close_commission = 0.000023,   close_today_commission = 0.0023, min_commission = 0), type = 'index_futures')

# Filtering ST stocks
# Return the list of stocks after filtering (i.e. those non-ST stocks in a list)
def filter_st(stocks, day):
   dataframe = get_extras('is_st', stocks, start_date = day, end_date = day, df = True)
   non_st_list = []
   for i in list(dataframe.columns):
        if not dataframe[i].bool():
           non_st_list.append(i)

   return str(non_st_list)

# Filtering paused stocks, including those which hit high_limit or low_limit when opening
# Return the list of stocks after filtering (i.e. those non-paused stocks in a list)

def filter_paused(stocks):
    curr_data = stocks
    stock_list = [stock for stock in stocks if not (
        curr_data[stock].paused or
        (curr_data[stock].day_open == curr_data[stock].high_limit) or
        (curr_data[stock].day_open == curr_data[stock].low_limit)
        )]
    return stock_list

# Call handle_data function once every unit time (if backtest per day, then call it once per day; if backtest by minute, then call it once per minute)
def handle_data(context, data):
    # Get the current date in the form 20XX-XX-XX
    current_date = context.current_dt.date()
    # Get all stocks
    all_stocks = list(get_all_securities(types = ['stock'], date = None).index)
    # Filter ST stocks with the base of all_stocks in the previous step
    non_st_stocks = filter_st(all_stocks, current_date)
    # Filter paused stocks on top of non_st_stocks in the previous step
    filter_paused(non_st_stocks)
    # Print the remaining stock list after filtering ST stocks and paused stocks
    print(filter_paused(non_st_stocks))`

With the function of filter_paused(stocks), I try to filter out the paused stocks, and get the remaining list of stocks after filtering. Yet I get something like this:

Traceback (most recent call last):
  File "/tmp/jqcore/jqboson/jqboson/core/entry.py", line 379, in _run
    engine.start()
  File "/tmp/jqcore/jqboson/jqboson/core/engine.py", line 231, in start
    self._dispatcher.start()
  File "/tmp/jqcore/jqboson/jqboson/core/dispatcher.py", line 280, in start
    self._run_loop()
  File "/tmp/jqcore/jqboson/jqboson/core/dispatcher.py", line 240, in _run_loop
    self._loop.run()
  File "/tmp/jqcore/jqboson/jqboson/core/loop/loop.py", line 107, in run
    self._handle_queue()
  File "/tmp/jqcore/jqboson/jqboson/core/loop/loop.py", line 153, in _handle_queue
    message.callback(**message.callback_data)
  File "/tmp/jqcore/jqboson/jqboson/core/mds/market_data_subscriber.py", line 228, in broadcast
    consumer.send(market_data)
  File "/tmp/jqcore/jqboson/jqboson/core/mds/market_data_consumer_manager.py", line 59, in    consumer_gen
    msg_callback()
  File "/tmp/jqcore/jqboson/jqboson/core/mds/market_data_consumer_manager.py", line 52, in msg_callback
    callback(market_data)
  File "/tmp/jqcore/jqboson/jqboson/core/mds/market_data_consumer_manager.py", line 122, in wrapper
    result = callback(*args, **kwargs)
  File "/tmp/jqcore/jqboson/jqboson/core/strategy.py", line 474, in _wrapper
    self._context.current_dt
  File "/tmp/strategy/user_code.py", line 60, in handle_data
    filter_paused(non_st_stocks)
  File "/tmp/strategy/user_code.py", line 43, in filter_paused
    stock_list = [stock for stock in stocks if not (
  File "/tmp/strategy/user_code.py", line 44, in <listcomp>
    curr_data[stock].paused or
TypeError: string indices must be integers

Apparently the function "filter_paused(stocks)" is the problem. Does anyone know how to fix it? Everything was done on JoinQuant platform.


Solution

  • You don't need to index a list within a list comprehension

    def filter_paused(stocks):
        return [stock for stock in stocks if not (
            stock.paused or
            stock.day_open == stock.high_limit or
            stock.day_open == stock.low_limit
            )]