Mix.install(
[
{:lux, "~> 0.4.0"}
{:kino, "~> 0.14.2"}
],
start_applications: false,
config: [
lux: [
api_keys: [
openai: System.fetch_env!("LB_OPENAI_API_KEY")
],
open_ai_models: [
default: "gpt-4o-mini"
],
accounts: [
hyperliquid_private_key: System.fetch_env!("LB_HYPERLIQUID_PRIVATE_KEY"),
hyperliquid_address: System.fetch_env!("LB_HYPERLIQUID_ADDRESS"),
hyperliquid_api_url: System.fetch_env!("LB_HYPERLIQUID_API_URL")
]
]
]
)
Mix.Task.run("setup", install_deps: false)
Application.put_env(:venomous, :snake_manager, %{
python_opts: [
module_paths: [
Lux.Python.module_path(),
Lux.Python.module_path(:deps)
],
python_executable: "python3"
]
})
Application.ensure_all_started([:lux, :kino])
Before running this notebook, you'll need to set up the following secrets in your Livebook settings:
LB_OPENAI_API_KEY="" # Your OpenAI API key
LB_HYPERLIQUID_PRIVATE_KEY="" # Your Hyperliquid private key
LB_HYPERLIQUID_ADDRESS="" # Your Hyperliquid wallet address
LB_HYPERLIQUID_API_URL="https://api.hyperliquid.xyz"
When you run this notebook for the first time, you can get an error and see Add secret
button. After you add the secret and evaludate the setup cell again, you'll get another button to add other secrets.
This example demonstrates a simple trading system built with Lux agents. The system consists of:
- A Market Researcher agent that analyzes market conditions and proposes trades
- A Risk Manager agent that evaluates trade proposals
- An Agent Hub that coordinates communication between agents
- A Local Signal Router for message passing
Here's the complete trading system implementation:
defmodule ExampleApp.TradingSystem do
@moduledoc """
Simple interface for running the trading system.
"""
alias Lux.Agents.MarketResearcher
alias Lux.AgentHub
alias Lux.Signal.Router.Local
alias Lux.Signals.TradeProposal
require Logger
@doc """
Runs one iteration of market analysis and trading.
"""
def run(researcher_id, risk_manager_id) do
hub = AgentHub.get_default()
router = Process.whereis(:trading_router)
{:ok, %{agent: researcher, pid: researcher_pid}} = AgentHub.get_agent_info(hub, researcher_id)
{:ok, %{agent: risk_manager}} = AgentHub.get_agent_info(hub, risk_manager_id)
# Example market conditions (replace with real data)
market_conditions = %{
"ETH" => %{
"price" => 2800.0,
"24h_volume" => 1_000_000,
"volatility" => 0.15
}
}
# Get trade proposal from researcher and send to risk manager
with {:ok, signal} <- MarketResearcher.propose_trade(researcher_pid, market_conditions) do
# Create a signal to send to the risk manager
{:ok, trade_signal} = TradeProposal.new(%{
payload: signal,
sender: researcher.id,
recipient: risk_manager.id
})
signal_id = trade_signal.id
# Subscribe to signal delivery events
:ok = Local.subscribe(signal_id, name: router)
# Update researcher status to busy while processing
:ok = AgentHub.update_status(hub, researcher.id, :busy)
# Route the signal through the local router
:ok = Local.route(trade_signal, name: router, hub: hub)
# Wait for signal delivery confirmation
receive do
{:signal_delivered, ^signal_id} ->
Logger.info("Trade signal delivered successfully")
:ok = AgentHub.update_status(hub, researcher.id, :available)
{:signal_failed, ^signal_id, reason} ->
Logger.error("Failed to deliver trade signal: #{inspect(reason)}")
:ok = AgentHub.update_status(hub, researcher.id, :available)
after
5000 ->
Logger.error("Timeout waiting for signal delivery")
:ok = AgentHub.update_status(hub, researcher.id, :available)
{:error, :timeout}
end
end
end
end
Before start the system, let's start some agents and register them to Lux.AgentHub
.
alias Lux.Agents.MarketResearcher
alias Lux.Agents.RiskManager
alias Lux.AgentHub
alias Lux.Signal.Router.Local
# Get default agent hub
hub = AgentHub.get_default()
# Start the signal router
{:ok, router} = Kino.start_child({Local, [name: :trading_router]})
# Start both agents
{:ok, researcher_pid} = Kino.start_child({MarketResearcher, []})
{:ok, risk_manager_pid} = Kino.start_child({RiskManager, []})
# Get agent states
researcher = :sys.get_state(researcher_pid)
risk_manager = :sys.get_state(risk_manager_pid)
# Register agents with their capabilities
:ok = AgentHub.register(hub, researcher, researcher_pid, [:market_research, :analysis])
:ok = AgentHub.register(hub, risk_manager, risk_manager_pid, [:risk_management])
Let's try running the trading system:
ExampleApp.TradingSystem.run(
researcher.id,
risk_manager.id
)
-
System Setup
- The system starts by initializing an AgentHub and Local Router
- Two agents are created: MarketResearcher and RiskManager
- Agents are registered with their capabilities in the hub
-
Market Analysis
- The MarketResearcher analyzes market conditions
- If a trading opportunity is found, it creates a trade proposal
-
Signal Routing
- Trade proposals are wrapped in a TradeProposal signal
- The Local Router handles delivery between agents
- The system monitors signal delivery status
-
Risk Management
- The RiskManager receives and evaluates trade proposals
- It applies risk management rules before approving trades
This example demonstrates core Lux concepts including:
- Agent-based architecture
- Signal-based communication
- Capability registration
- Status management
- Error handling
To extend this example, you could:
- Add more sophisticated market analysis
- Implement additional risk management rules
- Add trade execution functionality
- Include position tracking
- Add portfolio management
- Implement backtesting capabilities