Skip to main content
Glama

menese_strategy

Create and manage automated trading strategies including DCA, Take Profit, and Stop Loss across 19 blockchain networks to optimize cryptocurrency investments.

Instructions

Manage automated trading strategies: DCA (dollar-cost averaging), Take Profit (sell above target), Stop Loss (sell below threshold).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform
strategyTypeNoStrategy type (required for create)
chainNoTarget chain (required for create)
amountNoAmount per execution (decimal, for create)
intervalSecondsNoInterval between DCA executions in seconds (min 60)
maxExecutionsNoMax number of executions
targetPriceNoTarget price in USD (for take_profit/stop_loss)
ruleIdNoRule ID (for cancel)

Implementation Reference

  • The handler logic for 'menese_strategy' tool, managing create, list, and cancel actions for trading strategies.
    async ({ action, strategyType, chain, amount, intervalSeconds, maxExecutions, targetPrice, ruleId }) => {
      const identity = store.get();
      if (!identity) {
        return { content: [{ type: "text" as const, text: "No wallet configured. Use menese_setup first." }], isError: true };
      }
    
      if (action === "list") {
        const result = await listStrategies(config, resolveActorIdentity(store));
        return {
          content: [{
            type: "text" as const,
            text: JSON.stringify(result, bigIntReplacer, 2),
          }],
        };
      }
    
      if (action === "cancel") {
        if (ruleId == null) {
          return { content: [{ type: "text" as const, text: "ruleId is required for cancel." }], isError: true };
        }
        const result = await deleteStrategy(config, resolveActorIdentity(store), ruleId);
        return {
          content: [{
            type: "text" as const,
            text: JSON.stringify(result, bigIntReplacer, 2),
          }],
        };
      }
    
      // action === "create"
      if (!strategyType || !chain || !amount) {
        return {
          content: [{ type: "text" as const, text: "strategyType, chain, and amount are required for create." }],
          isError: true,
        };
      }
    
      const chainType = CHAIN_TYPE_MAP[chain];
      const ruleType = RULE_TYPE_MAP[strategyType];
      if (!chainType || !ruleType) {
        return { content: [{ type: "text" as const, text: "Invalid chain or strategy type." }], isError: true };
      }
    
      const decimals = CHAIN_DECIMALS[chain] ?? 18;
      const triggerPrice = targetPrice ? BigInt(Math.round(parseFloat(targetPrice) * 1_000_000)) : 0n;
    
      // Build the Candid Rule record
      const rule: Record<string, unknown> = {
        chainType,
        ruleType,
        triggerPrice,
        sizePct: 100n,
        positionId: 0n,
        id: 0n,
        status: { Draft: null },
        createdAt: BigInt(Date.now()) * 1_000_000n,
        apyMigrationConfig: [],
        lpConfig: [],
        scheduledConfig: [],
        volatilityConfig: [],
        swapAmountDrops: [],
        swapAmountLamports: [],
        swapAmountWei: [],
        dcaConfig: [],
      };
    
      // Set chain-specific amount field
      if (chain === "solana") {
        rule.swapAmountLamports = [parseAmount(amount, 9)];
      } else if (chain === "xrp") {
        rule.swapAmountDrops = [parseAmount(amount, 6)];
      } else {
        rule.swapAmountWei = [parseAmount(amount, decimals)];
      }
    
      // DCA config
      if (strategyType === "dca" && intervalSeconds) {
        rule.dcaConfig = [{ intervalSeconds: BigInt(intervalSeconds), maxExecutions: maxExecutions ? [BigInt(maxExecutions)] : [] }];
      }
    
      const result = await addStrategy(config, resolveActorIdentity(store), rule);
      return {
        content: [{
          type: "text" as const,
          text: JSON.stringify(result, bigIntReplacer, 2),
        }],
      };
    },
  • The input schema for 'menese_strategy', defining parameters for different actions.
    description:
      "Manage automated trading strategies: DCA (dollar-cost averaging), " +
      "Take Profit (sell above target), Stop Loss (sell below threshold).",
    inputSchema: {
      action: z.enum(["create", "list", "cancel"]).describe("Action to perform"),
      strategyType: z.enum(["dca", "take_profit", "stop_loss"]).optional()
        .describe("Strategy type (required for create)"),
      chain: z.enum(SUPPORTED_CHAINS as unknown as [string, ...string[]]).optional()
        .describe("Target chain (required for create)"),
      amount: z.string().optional().describe("Amount per execution (decimal, for create)"),
      intervalSeconds: z.number().min(60).optional()
        .describe("Interval between DCA executions in seconds (min 60)"),
      maxExecutions: z.number().min(1).optional()
        .describe("Max number of executions"),
      targetPrice: z.string().optional()
        .describe("Target price in USD (for take_profit/stop_loss)"),
      ruleId: z.number().optional().describe("Rule ID (for cancel)"),
    },
  • Registration function for the 'menese_strategy' tool.
    export function registerStrategyTool(
      server: McpServer,
      store: IdentityStore,
      config: MeneseConfig,
    ): void {
      server.registerTool(
        "menese_strategy",
        {
          description:
            "Manage automated trading strategies: DCA (dollar-cost averaging), " +
            "Take Profit (sell above target), Stop Loss (sell below threshold).",
          inputSchema: {
            action: z.enum(["create", "list", "cancel"]).describe("Action to perform"),
            strategyType: z.enum(["dca", "take_profit", "stop_loss"]).optional()
              .describe("Strategy type (required for create)"),
            chain: z.enum(SUPPORTED_CHAINS as unknown as [string, ...string[]]).optional()
              .describe("Target chain (required for create)"),
            amount: z.string().optional().describe("Amount per execution (decimal, for create)"),
            intervalSeconds: z.number().min(60).optional()
              .describe("Interval between DCA executions in seconds (min 60)"),
            maxExecutions: z.number().min(1).optional()
              .describe("Max number of executions"),
            targetPrice: z.string().optional()
              .describe("Target price in USD (for take_profit/stop_loss)"),
            ruleId: z.number().optional().describe("Rule ID (for cancel)"),
          },
        },
        async ({ action, strategyType, chain, amount, intervalSeconds, maxExecutions, targetPrice, ruleId }) => {
          const identity = store.get();
          if (!identity) {
            return { content: [{ type: "text" as const, text: "No wallet configured. Use menese_setup first." }], isError: true };
          }
    
          if (action === "list") {
            const result = await listStrategies(config, resolveActorIdentity(store));
            return {
              content: [{
                type: "text" as const,
                text: JSON.stringify(result, bigIntReplacer, 2),
              }],
            };
          }
    
          if (action === "cancel") {
            if (ruleId == null) {
              return { content: [{ type: "text" as const, text: "ruleId is required for cancel." }], isError: true };
            }
            const result = await deleteStrategy(config, resolveActorIdentity(store), ruleId);
            return {
              content: [{
                type: "text" as const,
                text: JSON.stringify(result, bigIntReplacer, 2),
              }],
            };
          }
    
          // action === "create"
          if (!strategyType || !chain || !amount) {
            return {
              content: [{ type: "text" as const, text: "strategyType, chain, and amount are required for create." }],
              isError: true,
            };
          }
    
          const chainType = CHAIN_TYPE_MAP[chain];
          const ruleType = RULE_TYPE_MAP[strategyType];
          if (!chainType || !ruleType) {
            return { content: [{ type: "text" as const, text: "Invalid chain or strategy type." }], isError: true };
          }
    
          const decimals = CHAIN_DECIMALS[chain] ?? 18;
          const triggerPrice = targetPrice ? BigInt(Math.round(parseFloat(targetPrice) * 1_000_000)) : 0n;
    
          // Build the Candid Rule record
          const rule: Record<string, unknown> = {
            chainType,
            ruleType,
            triggerPrice,
            sizePct: 100n,
            positionId: 0n,
            id: 0n,
            status: { Draft: null },
            createdAt: BigInt(Date.now()) * 1_000_000n,
            apyMigrationConfig: [],
            lpConfig: [],
            scheduledConfig: [],
            volatilityConfig: [],
            swapAmountDrops: [],
            swapAmountLamports: [],
            swapAmountWei: [],
            dcaConfig: [],
          };
    
          // Set chain-specific amount field
          if (chain === "solana") {
            rule.swapAmountLamports = [parseAmount(amount, 9)];
          } else if (chain === "xrp") {
            rule.swapAmountDrops = [parseAmount(amount, 6)];
          } else {
            rule.swapAmountWei = [parseAmount(amount, decimals)];
          }
    
          // DCA config
          if (strategyType === "dca" && intervalSeconds) {
            rule.dcaConfig = [{ intervalSeconds: BigInt(intervalSeconds), maxExecutions: maxExecutions ? [BigInt(maxExecutions)] : [] }];
          }
    
          const result = await addStrategy(config, resolveActorIdentity(store), rule);
          return {
            content: [{
              type: "text" as const,
              text: JSON.stringify(result, bigIntReplacer, 2),
            }],
          };
        },
      );
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Aboodtt404/mcp-menesesdk'

If you have feedback or need assistance with the MCP directory API, please join our Discord server