# Options Signals Mini (`publicmoney/options-signals-mini`) Actor

Find unusual options activity and see why: the quantitative flags that fired on each contract, volume against open interest, implied volatility, and the news around the underlying. Export data, run via API, schedule and monitor runs, or integrate with other tools.

- **URL**: https://apify.com/publicmoney/options-signals-mini.md
- **Developed by:** [Public Money](https://apify.com/publicmoney) (Apify)
- **Categories:** Business
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

A screener tells you a contract is moving. It does not tell you why, so you end up with a list and a browser full of tabs. This Actor returns both halves: the quantitative flags that fired on a contract, in `signalCodes`, and the count of news stories around the underlying inside your window, so an unusual move arrives with its likely cause attached.

### What it does

- Returns **the flags that fired** in `signalCodes`, so a contract arrives labelled rather than just ranked.
- Counts the **news around the underlying** in `newsCount`, inside a window you set, which is the fastest way to separate a story from a stray print.
- Two routes: read Yahoo's **trend screeners** to find candidates, or pass **tickers** you already care about.
- Carries `underlyingPrice` next to the contract, so the strike is in context without a second lookup.
- Reports **implied volatility as a percent** and the change on the day, the pair that says whether premium is being bid up.
- Runs the Yahoo Finance Options and news Actors as child runs, so the flags and the stories come from one call.

### Use cases

| You need to | How this Actor does it |
| --- | --- |
| Find unusual activity with a reason | Run the most-active trend and read `signalCodes` next to `newsCount` |
| Separate news moves from noise | Filter on `newsCount` above zero |
| Watch your own names | Switch the route to `ticker` and pass your list |
| Tune the news window | Set **News window hours** to match how fast your market reacts |
| Screen for premium being bid up | Sort on `impliedVolatilityPercent` and read the flags |
| Feed a trading agent | Call the Actor over MCP and let the model ask for what it needs |

### Quick start

1. Click **Try for free**.
2. Leave **Route** on `trend` to screen the market, or switch it to `ticker` to pass your own names.
3. Pick the **Trend**: `most-active`, `gainers`, `losers`, `highest-implied-volatility` or `highest-open-interest`.
4. Set **News window hours**, which is how far back the story count reaches. The default is 48.
5. Click **Start**. Rows appear within seconds.
6. Export as JSON, CSV, Excel or XML, or read the dataset over the API.

### Input

| Field | Type | Default | What it controls |
| --- | --- | --- | --- |
| `route` | string | `trend` | `trend` screens the market, `ticker` reads the names you pass |
| `trend` | string | `most-active` | Which Yahoo screener to read on the trend route |
| `tickers` | array | `AAPL` | Underlyings to read on the ticker route |
| `contractsPerTicker` | integer | `10` | How many contracts to keep per underlying |
| `newsWindowHours` | integer | `48` | How far back the news count reaches |
| `maxItems` | integer | `0` | Caps how many contracts are returned |

```json
{
    "route": "trend",
    "trend": "most-active",
    "newsWindowHours": 48,
    "maxItems": 0
}
```

### Output

One dataset item per contract, with the flags and the news count attached. A contract with no flags is still returned, with `signalCodes` empty, so you can see what was considered.

| Field group | Fields |
| --- | --- |
| Contract | `status`, `contractSymbol`, `tickerSymbol`, `contractType`, `strike`, `expirationDate` |
| Premium | `value`, `changePercent`, `underlyingPrice` |
| Signals | `signalCodes`, `impliedVolatilityPercent` |
| Context | `newsCount` |

```json
{
    "status": "ok",
    "contractSymbol": "AAPL261218C00320000",
    "tickerSymbol": "AAPL",
    "contractType": "call",
    "strike": 320.0,
    "expirationDate": "2026-12-18",
    "value": 14.85,
    "changePercent": -6.31,
    "underlyingPrice": 319.97,
    "impliedVolatilityPercent": 28.4,
    "signalCodes": [
        "volume-above-open-interest",
        "iv-elevated"
    ],
    "newsCount": 4
}
```

### Integrations

Run it over the API and get the rows back in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/publicmoney~options-signals-mini/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"route": "trend", "trend": "most-active", "newsWindowHours": 48, "maxItems": 0}'
```

From Python:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("publicmoney/options-signals-mini").call(run_input={"route": "trend", "trend": "most-active", "newsWindowHours": 48, "maxItems": 0})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["tickerSymbol"], item["value"])
```

Give an AI agent the Actor over MCP:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com/?actors=publicmoney/options-signals-mini"
        }
    }
}
```

Schedules run it on any cron, webhooks fire when a run finishes, and platform integrations push the
dataset to Google Sheets, Slack, Airtable, Zapier or your own endpoint.

### Cost

Pay per event, so you pay for records rather than compute time.

| Event | Free tier | Top volume tier |
| --- | --- | --- |
| Contract record | $0.01 | $0.004 |
| Actor start | $0.00005 per GB | Same |

Two things are charged. The **contract record** above is this Actor's own event. On top of that it runs the Yahoo Finance Options and news Actors as **child runs on your account**, and each charges its own per-record price, which will not appear in this Actor's usage total. A narrower trend and a smaller **Contracts per ticker** is the lever. A record that returned no data is never charged.

### Troubleshooting

| Issue | Solution |
| --- | --- |
| `signalCodes` is empty on every contract | Nothing crossed a threshold in that screener today. That is a real answer, not a failure. |
| `newsCount` is always zero | Widen **News window hours**. A 48 hour window on a quiet name legitimately finds nothing. |
| The run costs more than the record price suggests | The child Actors charge their own per-record price on your account, and those charges are not in this Actor's usage total. |
| The run is slower than the options Actor alone | It starts child runs and waits for them. Narrow the trend or cut **Contracts per ticker**. |
| A flag fired that I disagree with | The flags are thresholds, not advice. `signalCodes` names each one so you can filter to the ones you trust. |

### FAQ

#### What counts as unusual options activity?

Here it is explicit rather than a black box: each flag in `signalCodes` is a named threshold, such as volume above open interest or implied volatility elevated against its own recent range. You can filter to the flags you believe and ignore the rest.

#### Why does it include news?

Because a screener alone cannot tell you whether a move has a cause. `newsCount` inside your window is the cheapest signal for that, and it is the difference between a list to research and a list to act on.

#### Why is it priced above the single-source Actors?

One record fans out into child runs against the options and news Actors, and those charge their own per-record price on your account. The cost section spells it out.

#### Can I use my own flag thresholds?

Not in the input. What you can do is read the underlying numbers, which are all in the record, and apply your own rule downstream.

#### Does it return historical signals?

No. Each record is current. Schedule it and let the dataset accumulate to get a history of what fired when.

#### Do I need a Yahoo Finance API key?

No. You need an Apify token to call the Actor over the API. No Yahoo Finance credential is involved anywhere.

#### Can I get this data in Python?

Yes, with the `apify-client` package as shown above. It returns parsed JSON, so there is no HTML or response handling on your side.

#### Can I get the data into Excel or Google Sheets?

Yes. Export the dataset as XLSX or CSV, or connect the Google Sheets integration so each run appends to a sheet.

#### Can an AI agent call this Actor?

Yes. Add it to an MCP client with the config above and the model can request what it needs on its own. Every record is flat JSON with named fields, so no post-processing is needed.

#### Is it legal to scrape Yahoo Finance?

This Actor reads public Yahoo Finance data that needs no login and collects no personal data. Scraping public data is generally lawful, and how you store, redistribute or act on market data is governed by your own agreements and local rules. Take your own legal advice for your use case.

### Changelog

- **0.0.1** First release. Trend and ticker routes with flags and news context.

### Feedback

Found a field Yahoo Finance publishes that this Actor misses, or an input it rejects? Open an issue on the Issues tab with the input and what you expected. A daily test runs every Actor in the fleet against live sources, so parser fixes ship fast.

# Actor input Schema

## `route` (type: `string`):

Trend analyses the contracts Yahoo ranks in one category. Ticker analyses the chain for the underlyings you name.

## `trend` (type: `string`):

Which screener to analyse on the Trend route.

## `tickers` (type: `array`):

Underlying symbols, one per line. Only used on the Ticker route.

## `contractsPerTicker` (type: `integer`):

How many contracts to analyse per trend or per ticker.

## `newsWindowHours` (type: `integer`):

How far back a story can be published and still be attached to a contract.

## `maxItems` (type: `integer`):

Stop after this many charged records. 0 means no cap.

## Actor input object example

```json
{
  "route": "trend",
  "trend": "most-active",
  "tickers": [
    "AAPL"
  ],
  "contractsPerTicker": 10,
  "newsWindowHours": 48,
  "maxItems": 0
}
```

# Actor output Schema

## `results` (type: `string`):

One item per requested input, in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "route": "trend",
    "trend": "most-active",
    "tickers": [
        "AAPL"
    ],
    "contractsPerTicker": 10,
    "newsWindowHours": 48,
    "maxItems": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("publicmoney/options-signals-mini").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "route": "trend",
    "trend": "most-active",
    "tickers": ["AAPL"],
    "contractsPerTicker": 10,
    "newsWindowHours": 48,
    "maxItems": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("publicmoney/options-signals-mini").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "route": "trend",
  "trend": "most-active",
  "tickers": [
    "AAPL"
  ],
  "contractsPerTicker": 10,
  "newsWindowHours": 48,
  "maxItems": 0
}' |
apify call publicmoney/options-signals-mini --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,publicmoney/options-signals-mini"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/XwmdN4kwFFTtY4h5j/builds/Jy7M7y3ebgxeCx7o1/openapi.json
