Fetch a signal from YOUR backend
fetch signal from YOUR backend
Mirrors runner/src/plugins/02-exampleSignal
What this teaches
- decide() is plain async TypeScript — you can fetch, call APIs, do whatever you need
- This is the typical "I have a model running somewhere else, the operator just executes its output" pattern
New vs exampleReadState
- Decision input comes from an external HTTP endpoint, not on-chain data
import type { StrategyPlugin } from "@automark/runtime-core";
interface Signal {
action: "hold" | "buy" | "sell";
asset: string;
confidence: number;
}
export default function createExampleSignal(): StrategyPlugin {
const vaultId = process.env.VAULT_ID;
if (!vaultId) throw new Error("exampleSignal: VAULT_ID not set");
const signalUrl = process.env.SIGNAL_URL ?? "https://your-backend.com/signal";
return {
name: "exampleSignal",
vaultId,
triggers: [{ kind: "cron", everySeconds: 5 }],
async decide(ctx) {
const res = await fetch(signalUrl);
const signal = (await res.json()) as Signal;
if (signal.action == 'hold') return [{ kind:'noop', reason: 'hold'}]
ctx.logger.info("got signal", { signal });
return [{ kind: "noop", reason: `observing signal=${signal.action}` }];
},
};
}
// insights we can take from this example:
// You can connect an external backend to handle more granular decisions in other languages and keep only execution here. Separation between intelligence/quant code and execution.
//
Environment variables
- VAULT_ID
- SIGNAL_URL (defaults to a placeholder)