Class: BudaApi::AI::NaturalLanguageTrader

Inherits:
Object
  • Object
show all
Defined in:
lib/buda_api/ai/natural_language_trader.rb

Overview

Natural language interface for trading operations

Constant Summary collapse

TRADING_FUNCTIONS =
[
  {
    name: "place_order",
    description: "Place a buy or sell order on the exchange",
    parameters: {
      type: "object",
      properties: {
        market_id: { 
          type: "string", 
          description: "Trading pair (e.g., BTC-CLP)",
          enum: BudaApi::Constants::Market::ALL
        },
        side: { 
          type: "string", 
          enum: ["buy", "sell"],
          description: "Whether to buy or sell"
        },
        amount: { 
          type: "number", 
          description: "Amount to trade (in base currency)"
        },
        price: { 
          type: "number", 
          description: "Price per unit (optional for market orders)"
        },
        order_type: { 
          type: "string", 
          enum: ["market", "limit"],
          description: "Order type - market executes immediately, limit waits for price"
        }
      },
      required: ["market_id", "side", "amount"]
    }
  },
  {
    name: "check_balance",
    description: "Check account balance for a specific currency",
    parameters: {
      type: "object",
      properties: {
        currency: { 
          type: "string", 
          description: "Currency code (e.g., BTC, CLP)",
          enum: BudaApi::Constants::Currency::ALL
        }
      },
      required: ["currency"]
    }
  },
  {
    name: "get_market_data",
    description: "Get current market data including price and order book",
    parameters: {
      type: "object",
      properties: {
        market_id: { 
          type: "string", 
          description: "Trading pair (e.g., BTC-CLP)",
          enum: BudaApi::Constants::Market::ALL
        }
      },
      required: ["market_id"]
    }
  },
  {
    name: "cancel_order",
    description: "Cancel an existing order",
    parameters: {
      type: "object",
      properties: {
        order_id: {
          type: "integer",
          description: "ID of the order to cancel"
        }
      },
      required: ["order_id"]
    }
  },
  {
    name: "get_order_history",
    description: "Get recent order history for a market",
    parameters: {
      type: "object",
      properties: {
        market_id: {
          type: "string",
          description: "Trading pair (e.g., BTC-CLP)",
          enum: BudaApi::Constants::Market::ALL
        },
        limit: {
          type: "integer",
          description: "Number of orders to retrieve (max 100)",
          maximum: 100
        }
      },
      required: ["market_id"]
    }
  },
  {
    name: "get_quotation",
    description: "Get price quotation for a potential trade",
    parameters: {
      type: "object",
      properties: {
        market_id: {
          type: "string", 
          description: "Trading pair (e.g., BTC-CLP)",
          enum: BudaApi::Constants::Market::ALL
        },
        side: {
          type: "string",
          enum: ["buy", "sell"],
          description: "Whether you want to buy or sell"
        },
        amount: {
          type: "number",
          description: "Amount you want to trade"
        }
      },
      required: ["market_id", "side", "amount"]
    }
  }
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(client, llm_provider: :openai) ⇒ NaturalLanguageTrader

Returns a new instance of NaturalLanguageTrader.



131
132
133
134
135
136
137
138
139
140
# File 'lib/buda_api/ai/natural_language_trader.rb', line 131

def initialize(client, llm_provider: :openai)
  @client = client
  @llm = RubyLLM.new(
    provider: llm_provider,
    functions: TRADING_FUNCTIONS
  )
  @conversation_history = []
  
  BudaApi::Logger.info("Natural Language Trader initialized")
end

Instance Method Details

#clear_historyObject

Clear conversation history



199
200
201
202
# File 'lib/buda_api/ai/natural_language_trader.rb', line 199

def clear_history
  @conversation_history.clear
  BudaApi::Logger.info("Conversation history cleared")
end

#conversation_historyArray<Hash>

Get conversation history

Returns:

  • (Array<Hash>)

    conversation messages



206
207
208
# File 'lib/buda_api/ai/natural_language_trader.rb', line 206

def conversation_history
  @conversation_history.dup
end

#execute_batch(commands, confirm_trades: true) ⇒ Array<Hash>

Process batch commands

Parameters:

  • commands (Array<String>)

    list of natural language commands

  • confirm_trades (Boolean) (defaults to: true)

    whether to confirm trades

Returns:

  • (Array<Hash>)

    results for each command



214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/buda_api/ai/natural_language_trader.rb', line 214

def execute_batch(commands, confirm_trades: true)
  results = []
  
  commands.each_with_index do |command, index|
    BudaApi::Logger.info("Processing batch command #{index + 1}/#{commands.length}")
    result = execute_command(command, confirm_trades: confirm_trades)
    results << result
    
    # Add small delay between commands to avoid rate limiting
    sleep(0.5) unless index == commands.length - 1
  end
  
  results
end

#execute_command(input, confirm_trades: true) ⇒ Hash

Execute a natural language trading command

Examples:

trader = BudaApi.natural_language_trader(client)
result = trader.execute_command("Check my BTC balance")
result = trader.execute_command("Buy 0.001 BTC at market price")

Parameters:

  • input (String)

    natural language command

  • confirm_trades (Boolean) (defaults to: true)

    whether to confirm before placing orders

Returns:

  • (Hash)

    execution result



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/buda_api/ai/natural_language_trader.rb', line 151

def execute_command(input, confirm_trades: true)
  BudaApi::Logger.info("Processing natural language command: #{input}")
  
  # Add to conversation history
  @conversation_history << { role: "user", content: input }
  
  begin
    response = @llm.complete(
      messages: build_conversation_messages,
      system_prompt: build_system_prompt,
      max_tokens: 500
    )
    
    # Add assistant response to history
    @conversation_history << { role: "assistant", content: response.content }
    
    if response.function_call
      result = execute_function_with_confirmation(response.function_call, confirm_trades)
      
      # Add function result to conversation
      @conversation_history << {
        role: "function", 
        name: response.function_call.name,
        content: result.to_json
      }
      
      result
    else
      {
        type: :text_response,
        content: response.content,
        timestamp: Time.now
      }
    end
    
  rescue => e
    error_msg = "Failed to process command: #{e.message}"
    BudaApi::Logger.error(error_msg)
    
    {
      type: :error,
      error: error_msg,
      timestamp: Time.now
    }
  end
end