Screening Equities by Amplitude, Float Size, and Recent Market Attention
Summary
This Chinese-language post describes a short-term equity selection screen based on three conditions: prior-session price amplitude above a threshold, tradable share count at or below a stated limit, and appearance on the previous day’s exchange activity list. It frames the filters as a way to find volatile, relatively small-float stocks that have attracted market attention. The post also provides formula and Python examples, with the Python version ranking qualifying names by turnover rate and retaining a fraction of the candidate list.
The article gives no backtest, return series, or evidence that the screen has predictive value. It warns that attention data is backward-looking and delayed, that short-term filters can be noisy, and that relying on publicity may neglect company fundamentals and sector context. It suggests adding fundamental variables, other technical criteria, market-attention measures, or machine-learning analysis, but does not test those proposed extensions. The thresholds and ranking are therefore presented as a screening recipe, not a demonstrated source of durable returns.
Key ideas
- The screen combines recent price amplitude, a maximum float-size condition, and prior-day exchange attention data.
- The sample implementation ranks qualifying stocks by turnover rate and limits the final selection count.
- The post characterizes the approach as short-term and acknowledges that noisy moves can dominate its signals.
- Exchange attention data is lagged and does not establish that a stock will continue moving in the same direction.
- Fundamental and sector information are suggested as additions, but their effects are not evaluated.
Tags
Full text
# gen_training_orders.py
```py
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
import os
import numpy as np
import pandas as pd
from pathlib import Path
DATA_PATH = Path(os.path.join("data", "pickle", "backtest"))
OUTPUT_PATH = Path(os.path.join("data", "orders"))
def generate_order(stock: str, start_idx: int, end_idx: int) -> bool:
dataset = pd.read_pickle(DATA_PATH / f"{stock}.pkl")
df = dataset.handler.fetch(level=None).reset_index()
if len(df) == 0 or df.isnull().values.any() or min(df["$volume0"]) < 1e-5:
return False
df["date"] = df["datetime"].dt.date.astype("datetime64")
df = df.set_index(["instrument", "datetime", "date"])
df = df.groupby("date", group_keys=False).take(range(start_idx, end_idx)).droplevel(level=0)
order_all = pd.DataFrame(df.groupby(level=(2, 0), group_keys=False).mean().dropna())
order_all["amount"] = np.random.lognormal(-3.28, 1.14) * order_all["$volume0"]
order_all = order_all[order_all["amount"] > 0.0]
order_all["order_type"] = 0
order_all = order_all.drop(columns=["$volume0"])
order_train = order_all[order_all.index.get_level_values(0) <= pd.Timestamp("2021-06-30")]
order_test = order_all[order_all.index.get_level_values(0) > pd.Timestamp("2021-06-30")]
order_valid = order_test[order_test.index.get_level_values(0) <= pd.Timestamp("2021-09-30")]
order_test = order_test[order_test.index.get_level_values(0) > pd.Timestamp("2021-09-30")]
for order, tag in zip((order_train, order_valid, order_test, order_all), ("train", "valid", "test", "all")):
path = OUTPUT_PATH / tag
os.makedirs(path, exist_ok=True)
if len(order) > 0:
order.to_pickle(path / f"{stock}.pkl.target")
return True
np.random.seed(1234)
file_list = sorted(os.listdir(DATA_PATH))
stocks = [f.replace(".pkl", "") for f in file_list]
np.random.shuffle(stocks)
cnt = 0
for stock in stocks:
if generate_order(stock, 0, 240 // 5 - 1):
cnt += 1
if cnt == 100:
break
```Shown in full with attribution under the source's licence. Licence: MIT
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.