Your First Plugin¶
Use the meridian CLI to scaffold a plugin project, add data, write strategy logic, and run it.
Install the CLI¶
Verify the installation:
Scaffold a Signal Plugin¶
This creates a complete, runnable project:
my-momentum/
├── Makefile # test, run, lint, fmt targets
├── requirements.txt # open-meridian + test deps
├── data/
│ └── sample.csv # starter price data (AAPL, 60 days)
├── src/
│ └── strategy.py # your strategy — edit this
└── tests/
└── test_strategy.py # unit test skeleton
Add Data¶
Drop a CSV into data/. The minimum columns are date and close:
date,open,high,low,close,volume
2024-01-02,150.00,152.50,149.50,151.00,1000000
2024-01-03,151.00,153.00,150.00,152.50,1100000
2024-01-04,152.50,154.00,151.50,153.75,950000
Column names are flexible — the SDK recognizes common variants:
| Standard | Also accepted |
|---|---|
date |
timestamp, time, dt |
open |
o, Open |
high |
h, High |
low |
l, Low |
close |
c, Close, adj_close |
volume |
vol, v, Volume |
You can also use Parquet files, DataFrames, or lists of dicts. See Local Development for details.
Edit Your Strategy¶
Open src/strategy.py. The scaffold generates this starting point:
from meridian import LocalClient, SignalEngine
from decimal import Decimal
client = LocalClient(starting_cash=100_000)
client.load_bars("AAPL", "data/sample.csv")
class MomentumStrategy(SignalEngine):
def on_data(self, window):
"""Called once per bar date with a rolling window of history."""
bars = window.bars("AAPL", lookback=20)
if len(bars) < 20:
return
# 20-day return
ret = (bars[-1].close - bars[0].close) / bars[0].close
pos = self.client.positions("AAPL")
holding = pos.get("AAPL", {}).get("quantity", Decimal(0))
if ret > 0.03 and holding == 0:
self.submit_order("AAPL", "BUY", 100)
elif ret < -0.02 and holding > 0:
self.submit_order("AAPL", "SELL", int(holding))
MomentumStrategy(client).run(warmup=20)
print("Positions:", client.positions())
print("Cash:", client.cash())
print("Fills:", len(client.fills()))
The on_data pattern is the core of every signal plugin:
- Pull historical bars from the
window - Compute your indicator or signal
- Call
self.submit_order()when conditions are met
The window object gives you access to all loaded symbols. Use window.bars(symbol, lookback=N) for a slice of history and window.latest(symbol) for the current bar.
Run and Test¶
make run executes src/strategy.py and prints positions, cash, and trade history to stdout. make test runs pytest against tests/test_strategy.py.
Scaffold a Data Adapter (DGM) Plugin¶
Signal plugins consume data. DGM (Data Gateway Module) plugins produce it. To scaffold a data adapter:
This generates a different project structure tailored for data ingestion:
my-csv-loader/
├── Makefile
├── requirements.txt
├── config/
│ └── sources.yaml # data source configuration
├── src/
│ └── adapter.py # your data adapter — edit this
└── tests/
└── test_adapter.py
The adapter template shows the pattern for reading from an external source and publishing bars:
from meridian import LocalClient
client = LocalClient()
# Load from your source
client.load_bars("AAPL", "data/aapl_daily.csv")
client.load_bars("MSFT", "data/msft_daily.csv")
# In connected mode, this publishes to platform.data.eod.*
# In local mode, it makes the data available to signal plugins
List Available Templates¶
See all scaffolds the CLI can generate:
Available templates:
signal Signal / alpha generation plugin
dgm Data Gateway Module (data adapter)
ccm Connectivity Module (broker adapter)
portfolio Portfolio construction plugin
oms Order management plugin
ems Execution management plugin
Each template includes a Makefile, test skeleton, and example configuration appropriate to the plugin type.
Next Steps¶
- Strategy Gallery -- five complete strategies to study and modify
- Local Development -- deep dive on LocalClient, data loading, and order simulation
- SDK Core Concepts -- sidecar protocol, plugin lifecycle, and kernel API surfaces
You built a plugin
Ready to share it?
- Submit to the marketplace — get your plugin listed for other deployments to use
- Certification process — get the "Meridian Certified" badge
- Show it off in Discord #show-and-tell