PolymarketStrategies
Blueprint / example trading strategies for the
paper_ex paper-trading engine.
This package is a reference set of textbook strategies — a
starting point for building your own. Each one is a plain
PaperEx.Strategy implementation: pure decision logic over
PaperEx types (MarketSnapshot, Order, Portfolio), with
hard-validated config in init/1. There is no proprietary alpha
here; these are the classic patterns, clearly written and
documented, so you can read them, run them on paper, and use them
as a template.
The strategies
| Tag | Module | Category | Idea |
|---|---|---|---|
momentum | PolymarketStrategies.Momentum | :flow | Buy after a sustained upward move, betting it continues. |
mean_reversion | PolymarketStrategies.MeanReversion | :flow | Buy a dip below the trailing mean, betting it snaps back. |
favorite_taker | PolymarketStrategies.FavoriteTaker | :taker | Take the ask on moderate favorites when the spread is tight. |
market_maker | PolymarketStrategies.MarketMaker | :resting | Quote two-sided around the mid and re-quote as it moves. |
stink_bid | PolymarketStrategies.StinkBid | :resting | Rest one discounted limit buy below the market and wait. |
resolution_snipe | PolymarketStrategies.ResolutionSnipe | :taker | Buy a near-certain outcome and collect the last few cents at resolution. |
basket_arb | PolymarketStrategies.BasketArb | :arb | Buy every leg of a mutually-exclusive basket when the asks sum to under $1. |
Each module's @moduledoc explains the mechanics, the per-tick
behavior, and every option (with defaults and validation rules).
Installation
Add both this package and paper_ex to your deps:
def deps do
[
{:polymarket_strategies, "~> 0.1"},
{:paper_ex, "~> 0.8"}
]
end
Using the catalog
PolymarketStrategies.Catalog is a small registry so you can
enumerate strategies by tag (to drive a UI, build runners, or
wire up per-strategy settings) instead of hardcoding the list:
PolymarketStrategies.Catalog.all()
#=> [%{tag: "stink_bid", module: PolymarketStrategies.StinkBid,
# name: "Stink Bid", category: :resting}, ...]
PolymarketStrategies.Catalog.tags()
#=> ["stink_bid", "market_maker", "favorite_taker", ...]
PolymarketStrategies.Catalog.fetch("momentum")
#=> {:ok, %{tag: "momentum", module: PolymarketStrategies.Momentum, ...}}
Running a strategy
Every strategy implements the PaperEx.Strategy behaviour, so you
drive it with paper_ex exactly like any other. For example,
initialising and asking one for a decision:
{:ok, state} =
PolymarketStrategies.Momentum.init(lookback: 10, threshold: 0.05, size: 100)
{orders, state} =
PolymarketStrategies.Momentum.decide(
%{instrument_id: token_id, snapshot: snapshot, portfolio: portfolio},
state
)
See the paper_ex docs for the full runner / engine wiring and the
PaperEx.Strategy contract.
Writing your own
These modules are meant to be copied and modified. A strategy is any
module that implements PaperEx.Strategy — validate its options in
init/1, keep decide/2 pure over the snapshot and portfolio, and
make it idempotent against its own resting orders (so it doesn't
double up). To surface a custom strategy in the catalog, register it
without touching this package:
# via config
config :polymarket_strategies,
extra: [%{tag: "my_strat", module: MyApp.MyStrat, name: "My Strat", category: :custom}]
# or at runtime
PolymarketStrategies.Catalog.register(%{
tag: "my_strat",
module: MyApp.MyStrat,
name: "My Strat",
category: :custom
})
License
MIT. See the LICENSE file distributed with this package.