buda_api 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +101 -4
- data/buda_api.gemspec +4 -1
- data/examples/ai/README.md +314 -0
- data/examples/ai/anomaly_detection_example.rb +412 -0
- data/examples/ai/natural_language_trading.rb +369 -0
- data/examples/ai/report_generation_example.rb +605 -0
- data/examples/ai/risk_management_example.rb +300 -0
- data/examples/ai/trading_assistant_example.rb +295 -0
- data/lib/buda_api/ai/anomaly_detector.rb +787 -0
- data/lib/buda_api/ai/natural_language_trader.rb +541 -0
- data/lib/buda_api/ai/report_generator.rb +1054 -0
- data/lib/buda_api/ai/risk_manager.rb +789 -0
- data/lib/buda_api/ai/trading_assistant.rb +404 -0
- data/lib/buda_api/version.rb +1 -1
- data/lib/buda_api.rb +37 -0
- metadata +32 -1
@@ -0,0 +1,300 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Example: Advanced Risk Management with AI
|
5
|
+
# This example demonstrates comprehensive risk management using AI-powered analysis
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
require_relative '../../lib/buda_api'
|
9
|
+
|
10
|
+
# Configuration
|
11
|
+
API_KEY = ENV['BUDA_API_KEY'] || 'your_api_key_here'
|
12
|
+
API_SECRET = ENV['BUDA_API_SECRET'] || 'your_api_secret_here'
|
13
|
+
|
14
|
+
def main
|
15
|
+
puts "⚠️ Advanced AI Risk Management Example"
|
16
|
+
puts "=" * 50
|
17
|
+
|
18
|
+
unless BudaApi.ai_available?
|
19
|
+
puts "❌ AI features not available. Install ruby_llm gem first."
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
# Initialize client and risk manager
|
24
|
+
client = BudaApi::AuthenticatedClient.new(
|
25
|
+
api_key: API_KEY,
|
26
|
+
api_secret: API_SECRET,
|
27
|
+
sandbox: true
|
28
|
+
)
|
29
|
+
|
30
|
+
risk_manager = BudaApi::AI::RiskManager.new(client, llm_provider: :openai)
|
31
|
+
|
32
|
+
# Example 1: Comprehensive Portfolio Risk Analysis
|
33
|
+
puts "\n📊 Portfolio Risk Analysis"
|
34
|
+
puts "-" * 30
|
35
|
+
|
36
|
+
portfolio_risk = risk_manager.analyze_portfolio_risk(
|
37
|
+
include_ai_insights: true,
|
38
|
+
focus_factors: ["concentration_risk", "volatility_risk"]
|
39
|
+
)
|
40
|
+
|
41
|
+
if portfolio_risk[:type] == :portfolio_risk_analysis
|
42
|
+
puts "Portfolio Overview:"
|
43
|
+
puts " Total Value: #{portfolio_risk[:portfolio_value].round(2)} CLP"
|
44
|
+
puts " Risk Level: #{portfolio_risk[:overall_risk][:color]} #{portfolio_risk[:overall_risk][:level]}"
|
45
|
+
puts " Risk Score: #{portfolio_risk[:overall_risk][:score].round(1)}/5.0"
|
46
|
+
puts " Holdings: #{portfolio_risk[:currency_count]} different currencies"
|
47
|
+
|
48
|
+
puts "\nRisk Breakdown:"
|
49
|
+
risk_components = portfolio_risk[:overall_risk][:components]
|
50
|
+
puts " Concentration Risk: #{risk_components[:concentration].round(1)}/5.0"
|
51
|
+
puts " Volatility Risk: #{risk_components[:volatility].round(1)}/5.0"
|
52
|
+
puts " Diversification Risk: #{risk_components[:diversification].round(1)}/5.0"
|
53
|
+
puts " Correlation Risk: #{risk_components[:correlation].round(1)}/5.0"
|
54
|
+
|
55
|
+
puts "\nTop Holdings:"
|
56
|
+
portfolio_risk[:holdings].first(3).each do |holding|
|
57
|
+
percentage = (holding[:amount] / portfolio_risk[:portfolio_value]) * 100
|
58
|
+
puts " #{holding[:currency]}: #{holding[:amount].round(4)} (#{percentage.round(1)}%)"
|
59
|
+
end
|
60
|
+
|
61
|
+
if portfolio_risk[:recommendations].any?
|
62
|
+
puts "\nRecommendations:"
|
63
|
+
portfolio_risk[:recommendations].each do |rec|
|
64
|
+
puts " #{rec[:type].upcase}: #{rec[:message]}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if portfolio_risk[:ai_insights]
|
69
|
+
puts "\nAI Risk Insights:"
|
70
|
+
puts portfolio_risk[:ai_insights][:analysis]
|
71
|
+
end
|
72
|
+
else
|
73
|
+
puts "Portfolio Risk: #{portfolio_risk[:message]}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Example 2: Pre-Trade Risk Evaluation
|
77
|
+
puts "\n🎯 Pre-Trade Risk Evaluation"
|
78
|
+
puts "-" * 30
|
79
|
+
|
80
|
+
# Evaluate risk for a potential BTC purchase
|
81
|
+
trade_risk = risk_manager.evaluate_trade_risk(
|
82
|
+
"BTC-CLP",
|
83
|
+
"buy",
|
84
|
+
0.001, # 0.001 BTC
|
85
|
+
nil # Market price
|
86
|
+
)
|
87
|
+
|
88
|
+
if trade_risk[:type] == :trade_risk_evaluation
|
89
|
+
puts "Trade Risk Assessment:"
|
90
|
+
puts " Market: #{trade_risk[:market_id]}"
|
91
|
+
puts " Side: #{trade_risk[:side]} #{trade_risk[:amount]} BTC"
|
92
|
+
puts " Risk Level: #{RISK_LEVELS[trade_risk[:risk_level]][:color]} #{RISK_LEVELS[trade_risk[:risk_level]][:description]}"
|
93
|
+
puts " Risk Score: #{trade_risk[:risk_score].round(1)}/5.0"
|
94
|
+
puts " Should Proceed: #{trade_risk[:should_proceed] ? '✅ Yes' : '❌ No'}"
|
95
|
+
|
96
|
+
puts "\nRisk Factors:"
|
97
|
+
puts " Position Impact: #{trade_risk[:position_risk][:portfolio_percentage].round(1)}% of portfolio"
|
98
|
+
puts " Market Impact: #{trade_risk[:market_impact_risk][:impact_score].round(1)}/5.0"
|
99
|
+
puts " Trade Value: #{trade_risk[:trade_impact][:estimated_cost].round(2)} CLP"
|
100
|
+
|
101
|
+
puts "\nRecommendations:"
|
102
|
+
trade_risk[:recommendations].each do |recommendation|
|
103
|
+
puts " • #{recommendation}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Example 3: Risk Monitoring with Alerts
|
108
|
+
puts "\n🚨 Risk Threshold Monitoring"
|
109
|
+
puts "-" * 30
|
110
|
+
|
111
|
+
# Set custom risk thresholds
|
112
|
+
thresholds = {
|
113
|
+
max_position_percentage: 25.0, # Max 25% in single asset
|
114
|
+
max_daily_loss: 3.0, # Max 3% daily loss
|
115
|
+
min_diversification_score: 0.7, # Min diversification
|
116
|
+
max_volatility_score: 3.5 # Max volatility tolerance
|
117
|
+
}
|
118
|
+
|
119
|
+
monitoring_result = risk_manager.monitor_risk_thresholds(thresholds)
|
120
|
+
|
121
|
+
puts "Risk Monitoring Results:"
|
122
|
+
puts " Alerts Detected: #{monitoring_result[:alerts_count]}"
|
123
|
+
puts " Portfolio Safe: #{monitoring_result[:safe] ? '✅ Yes' : '❌ No'}"
|
124
|
+
|
125
|
+
if monitoring_result[:alerts].any?
|
126
|
+
puts "\nActive Alerts:"
|
127
|
+
monitoring_result[:alerts].each do |alert|
|
128
|
+
level_emoji = case alert[:level]
|
129
|
+
when :high then "🚨"
|
130
|
+
when :medium then "⚠️"
|
131
|
+
else "ℹ️"
|
132
|
+
end
|
133
|
+
puts " #{level_emoji} #{alert[:message]}"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
puts "\nCurrent Thresholds:"
|
138
|
+
monitoring_result[:thresholds].each do |name, value|
|
139
|
+
puts " #{name}: #{value}"
|
140
|
+
end
|
141
|
+
|
142
|
+
# Example 4: Stop-Loss Recommendations
|
143
|
+
puts "\n🛡️ Stop-Loss Recommendations"
|
144
|
+
puts "-" * 30
|
145
|
+
|
146
|
+
# Assume we have a BTC position to protect
|
147
|
+
position_size = 0.005 # 0.005 BTC
|
148
|
+
|
149
|
+
stop_loss_rec = risk_manager.recommend_stop_loss("BTC-CLP", position_size)
|
150
|
+
|
151
|
+
if stop_loss_rec[:type] == :stop_loss_recommendations
|
152
|
+
puts "Stop-Loss Analysis for #{stop_loss_rec[:position_size]} BTC:"
|
153
|
+
puts "Current Price: #{stop_loss_rec[:current_price]} CLP"
|
154
|
+
puts "Position Value: #{stop_loss_rec[:position_value].round(2)} CLP"
|
155
|
+
|
156
|
+
puts "\nStop-Loss Options:"
|
157
|
+
stop_loss_rec[:recommendations].each do |name, option|
|
158
|
+
puts " #{name.capitalize}:"
|
159
|
+
puts " Price: #{option[:price].round(2)} CLP"
|
160
|
+
puts " Max Loss: #{option[:max_loss].round(2)} CLP (#{option[:percentage]}%)"
|
161
|
+
puts " Description: #{option[:description]}"
|
162
|
+
puts
|
163
|
+
end
|
164
|
+
|
165
|
+
recommended = stop_loss_rec[:recommendation]
|
166
|
+
puts "💡 Recommended: #{recommended} stop-loss based on current market conditions"
|
167
|
+
end
|
168
|
+
|
169
|
+
# Example 5: Risk-Adjusted Position Sizing
|
170
|
+
puts "\n📏 Risk-Adjusted Position Sizing"
|
171
|
+
puts "-" * 30
|
172
|
+
|
173
|
+
# Calculate optimal position size based on risk tolerance
|
174
|
+
def calculate_optimal_position_size(portfolio_value, risk_per_trade_percent, stop_loss_percent)
|
175
|
+
risk_amount = portfolio_value * (risk_per_trade_percent / 100.0)
|
176
|
+
position_size_clp = risk_amount / (stop_loss_percent / 100.0)
|
177
|
+
position_size_clp
|
178
|
+
end
|
179
|
+
|
180
|
+
portfolio_value = portfolio_risk[:portfolio_value] || 1000000 # 1M CLP default
|
181
|
+
risk_per_trade = 2.0 # Risk 2% per trade
|
182
|
+
stop_loss_distance = 5.0 # 5% stop loss
|
183
|
+
|
184
|
+
optimal_position_clp = calculate_optimal_position_size(
|
185
|
+
portfolio_value,
|
186
|
+
risk_per_trade,
|
187
|
+
stop_loss_distance
|
188
|
+
)
|
189
|
+
|
190
|
+
puts "Position Sizing Calculation:"
|
191
|
+
puts " Portfolio Value: #{portfolio_value.round(2)} CLP"
|
192
|
+
puts " Risk Per Trade: #{risk_per_trade}%"
|
193
|
+
puts " Stop Loss Distance: #{stop_loss_distance}%"
|
194
|
+
puts " Optimal Position Size: #{optimal_position_clp.round(2)} CLP"
|
195
|
+
puts " Max Risk Amount: #{(portfolio_value * risk_per_trade / 100.0).round(2)} CLP"
|
196
|
+
|
197
|
+
# Example 6: Correlation Analysis
|
198
|
+
puts "\n🔗 Asset Correlation Analysis"
|
199
|
+
puts "-" * 30
|
200
|
+
|
201
|
+
# Simplified correlation analysis using current price changes
|
202
|
+
def analyze_correlations(client, markets)
|
203
|
+
correlations = {}
|
204
|
+
|
205
|
+
markets.each do |market1|
|
206
|
+
markets.each do |market2|
|
207
|
+
next if market1 == market2
|
208
|
+
|
209
|
+
begin
|
210
|
+
ticker1 = client.ticker(market1)
|
211
|
+
ticker2 = client.ticker(market2)
|
212
|
+
|
213
|
+
# Simple correlation based on 24h changes (in real implementation, use historical data)
|
214
|
+
change1 = ticker1.price_variation_24h
|
215
|
+
change2 = ticker2.price_variation_24h
|
216
|
+
|
217
|
+
# Simplified correlation indicator
|
218
|
+
correlation = case
|
219
|
+
when (change1 > 0 && change2 > 0) || (change1 < 0 && change2 < 0)
|
220
|
+
(change1 * change2).abs / ([change1.abs, change2.abs].max + 0.01)
|
221
|
+
else
|
222
|
+
-(change1 * change2).abs / ([change1.abs, change2.abs].max + 0.01)
|
223
|
+
end
|
224
|
+
|
225
|
+
correlations["#{market1}-#{market2}"] = correlation.round(2)
|
226
|
+
rescue
|
227
|
+
# Skip if unable to get data
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
correlations
|
233
|
+
end
|
234
|
+
|
235
|
+
major_markets = ["BTC-CLP", "ETH-CLP"]
|
236
|
+
correlations = analyze_correlations(client, major_markets)
|
237
|
+
|
238
|
+
puts "Asset Correlation Analysis:"
|
239
|
+
correlations.each do |pair, correlation|
|
240
|
+
correlation_level = case correlation.abs
|
241
|
+
when 0.8..1.0 then "Very High"
|
242
|
+
when 0.6..0.8 then "High"
|
243
|
+
when 0.4..0.6 then "Medium"
|
244
|
+
when 0.2..0.4 then "Low"
|
245
|
+
else "Very Low"
|
246
|
+
end
|
247
|
+
|
248
|
+
direction = correlation > 0 ? "Positive" : "Negative"
|
249
|
+
puts " #{pair}: #{correlation} (#{direction} #{correlation_level})"
|
250
|
+
end
|
251
|
+
|
252
|
+
# Example 7: Risk Dashboard Summary
|
253
|
+
puts "\n📋 Risk Dashboard Summary"
|
254
|
+
puts "=" * 50
|
255
|
+
|
256
|
+
dashboard = {
|
257
|
+
portfolio_health: portfolio_risk[:overall_risk][:level],
|
258
|
+
active_alerts: monitoring_result[:alerts_count],
|
259
|
+
risk_score: portfolio_risk[:overall_risk][:score].round(1),
|
260
|
+
recommendations_count: portfolio_risk[:recommendations]&.length || 0,
|
261
|
+
last_updated: Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
262
|
+
}
|
263
|
+
|
264
|
+
puts "Risk Dashboard:"
|
265
|
+
puts " Portfolio Health: #{RISK_LEVELS[dashboard[:portfolio_health].to_sym][:color]} #{dashboard[:portfolio_health]}"
|
266
|
+
puts " Risk Score: #{dashboard[:risk_score]}/5.0"
|
267
|
+
puts " Active Alerts: #{dashboard[:active_alerts]}"
|
268
|
+
puts " Pending Recommendations: #{dashboard[:recommendations_count]}"
|
269
|
+
puts " Last Updated: #{dashboard[:last_updated]}"
|
270
|
+
|
271
|
+
# Health status
|
272
|
+
overall_status = if dashboard[:risk_score] < 2.5 && dashboard[:active_alerts] == 0
|
273
|
+
"🟢 HEALTHY"
|
274
|
+
elsif dashboard[:risk_score] < 4.0 && dashboard[:active_alerts] < 3
|
275
|
+
"🟡 CAUTION"
|
276
|
+
else
|
277
|
+
"🔴 HIGH RISK"
|
278
|
+
end
|
279
|
+
|
280
|
+
puts " Overall Status: #{overall_status}"
|
281
|
+
|
282
|
+
rescue BudaApi::ApiError => e
|
283
|
+
puts "❌ API Error: #{e.message}"
|
284
|
+
rescue => e
|
285
|
+
puts "❌ Error: #{e.message}"
|
286
|
+
puts e.backtrace.first(3).join("\n") if ENV['DEBUG']
|
287
|
+
end
|
288
|
+
|
289
|
+
# Define risk levels constant for display
|
290
|
+
RISK_LEVELS = {
|
291
|
+
very_low: { color: "🟢", description: "Very Low Risk" },
|
292
|
+
low: { color: "🟡", description: "Low Risk" },
|
293
|
+
medium: { color: "🟠", description: "Medium Risk" },
|
294
|
+
high: { color: "🔴", description: "High Risk" },
|
295
|
+
very_high: { color: "🚫", description: "Very High Risk" }
|
296
|
+
}
|
297
|
+
|
298
|
+
if __FILE__ == $0
|
299
|
+
main
|
300
|
+
end
|
@@ -0,0 +1,295 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Example: AI-Enhanced Trading Assistant
|
5
|
+
# This example demonstrates how to use BudaApi with AI features for comprehensive trading analysis
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
require_relative '../lib/buda_api'
|
9
|
+
|
10
|
+
# Configuration
|
11
|
+
API_KEY = ENV['BUDA_API_KEY'] || 'your_api_key_here'
|
12
|
+
API_SECRET = ENV['BUDA_API_SECRET'] || 'your_api_secret_here'
|
13
|
+
LLM_PROVIDER = :openai # or :anthropic, :ollama
|
14
|
+
|
15
|
+
def main
|
16
|
+
puts "🤖 BudaApi AI Trading Assistant Example"
|
17
|
+
puts "=" * 50
|
18
|
+
|
19
|
+
# Check if AI features are available
|
20
|
+
unless BudaApi.ai_available?
|
21
|
+
puts "❌ AI features are not available. Please install ruby_llm gem:"
|
22
|
+
puts " gem install ruby_llm"
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "✅ AI features available"
|
27
|
+
|
28
|
+
# Initialize authenticated client
|
29
|
+
client = BudaApi::AuthenticatedClient.new(
|
30
|
+
api_key: API_KEY,
|
31
|
+
api_secret: API_SECRET,
|
32
|
+
sandbox: true # Use sandbox for testing
|
33
|
+
)
|
34
|
+
|
35
|
+
# Initialize AI trading assistant
|
36
|
+
assistant = BudaApi.trading_assistant(client, llm_provider: LLM_PROVIDER)
|
37
|
+
|
38
|
+
# Example 1: Market Analysis with AI
|
39
|
+
puts "\n📊 Market Analysis"
|
40
|
+
puts "-" * 30
|
41
|
+
|
42
|
+
market_analysis = assistant.analyze_market("BTC-CLP")
|
43
|
+
puts "Market: #{market_analysis[:market_id]}"
|
44
|
+
puts "Current Price: #{market_analysis[:current_price]} CLP"
|
45
|
+
puts "Trend: #{market_analysis[:trend]}"
|
46
|
+
puts "AI Recommendation: #{market_analysis[:ai_recommendation][:action]}"
|
47
|
+
puts "Confidence: #{market_analysis[:ai_recommendation][:confidence]}%"
|
48
|
+
|
49
|
+
# Example 2: Trading Strategy Suggestions
|
50
|
+
puts "\n🎯 Trading Strategy"
|
51
|
+
puts "-" * 30
|
52
|
+
|
53
|
+
strategy = assistant.suggest_trading_strategy(
|
54
|
+
market_id: "BTC-CLP",
|
55
|
+
risk_tolerance: "medium",
|
56
|
+
investment_horizon: "short_term"
|
57
|
+
)
|
58
|
+
|
59
|
+
puts "Strategy: #{strategy[:strategy_name]}"
|
60
|
+
puts "Entry Range: #{strategy[:entry_signals][:price_range][:min]} - #{strategy[:entry_signals][:price_range][:max]} CLP"
|
61
|
+
puts "Target: #{strategy[:profit_targets].first[:price]} CLP (#{strategy[:profit_targets].first[:percentage]}%)"
|
62
|
+
puts "Stop Loss: #{strategy[:risk_management][:stop_loss][:price]} CLP"
|
63
|
+
|
64
|
+
# Example 3: Entry/Exit Signals
|
65
|
+
puts "\n🚦 Entry/Exit Signals"
|
66
|
+
puts "-" * 30
|
67
|
+
|
68
|
+
signals = assistant.get_entry_exit_signals(["BTC-CLP", "ETH-CLP"])
|
69
|
+
|
70
|
+
signals[:signals].each do |signal|
|
71
|
+
puts "#{signal[:market_id]}:"
|
72
|
+
puts " Signal: #{signal[:signal]} (#{signal[:strength]})"
|
73
|
+
puts " Price: #{signal[:current_price]} CLP"
|
74
|
+
puts " Recommendation: #{signal[:recommendation]}"
|
75
|
+
puts
|
76
|
+
end
|
77
|
+
|
78
|
+
# Example 4: Natural Language Trading
|
79
|
+
puts "\n💬 Natural Language Trading"
|
80
|
+
puts "-" * 30
|
81
|
+
|
82
|
+
nl_trader = BudaApi.natural_language_trader(client, llm_provider: LLM_PROVIDER)
|
83
|
+
|
84
|
+
# Execute natural language commands
|
85
|
+
commands = [
|
86
|
+
"Check my BTC balance",
|
87
|
+
"What's the current price of Ethereum?",
|
88
|
+
"Show me the order book for BTC-CLP"
|
89
|
+
]
|
90
|
+
|
91
|
+
commands.each do |command|
|
92
|
+
puts "Query: #{command}"
|
93
|
+
result = nl_trader.execute_command(command, confirm_trades: false)
|
94
|
+
puts "Response: #{result[:content] || result[:message]}"
|
95
|
+
puts
|
96
|
+
end
|
97
|
+
|
98
|
+
# Example 5: Risk Management
|
99
|
+
puts "\n⚠️ Risk Management"
|
100
|
+
puts "-" * 30
|
101
|
+
|
102
|
+
risk_manager = BudaApi::AI::RiskManager.new(client, llm_provider: LLM_PROVIDER)
|
103
|
+
|
104
|
+
portfolio_risk = risk_manager.analyze_portfolio_risk(include_ai_insights: true)
|
105
|
+
|
106
|
+
if portfolio_risk[:type] == :portfolio_risk_analysis
|
107
|
+
puts "Portfolio Value: #{portfolio_risk[:portfolio_value].round(2)} CLP"
|
108
|
+
puts "Risk Level: #{portfolio_risk[:overall_risk][:color]} #{portfolio_risk[:overall_risk][:level]}"
|
109
|
+
puts "Risk Score: #{portfolio_risk[:overall_risk][:score].round(1)}/5.0"
|
110
|
+
|
111
|
+
if portfolio_risk[:ai_insights]
|
112
|
+
puts "\nAI Risk Insights:"
|
113
|
+
puts portfolio_risk[:ai_insights][:analysis]
|
114
|
+
end
|
115
|
+
else
|
116
|
+
puts "Portfolio analysis: #{portfolio_risk[:message]}"
|
117
|
+
end
|
118
|
+
|
119
|
+
# Example 6: Anomaly Detection
|
120
|
+
puts "\n🔍 Anomaly Detection"
|
121
|
+
puts "-" * 30
|
122
|
+
|
123
|
+
detector = BudaApi::AI::AnomalyDetector.new(client, llm_provider: LLM_PROVIDER)
|
124
|
+
|
125
|
+
anomalies = detector.detect_market_anomalies(
|
126
|
+
markets: ["BTC-CLP", "ETH-CLP"],
|
127
|
+
include_ai_analysis: true
|
128
|
+
)
|
129
|
+
|
130
|
+
puts "Markets Analyzed: #{anomalies[:markets_analyzed]}"
|
131
|
+
puts "Anomalies Detected: #{anomalies[:anomalies_detected]}"
|
132
|
+
|
133
|
+
if anomalies[:anomalies_detected] > 0
|
134
|
+
puts "\nTop Anomalies:"
|
135
|
+
anomalies[:anomalies].first(3).each do |anomaly|
|
136
|
+
puts " #{anomaly[:type]}: #{anomaly[:description]} (#{anomaly[:severity]})"
|
137
|
+
end
|
138
|
+
|
139
|
+
if anomalies[:ai_analysis]
|
140
|
+
puts "\nAI Analysis:"
|
141
|
+
puts anomalies[:ai_analysis][:analysis]
|
142
|
+
end
|
143
|
+
else
|
144
|
+
puts "✅ No significant anomalies detected"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Example 7: Report Generation
|
148
|
+
puts "\n📋 Report Generation"
|
149
|
+
puts "-" * 30
|
150
|
+
|
151
|
+
reporter = BudaApi::AI::ReportGenerator.new(client, llm_provider: LLM_PROVIDER)
|
152
|
+
|
153
|
+
portfolio_report = reporter.generate_portfolio_summary(
|
154
|
+
format: "markdown",
|
155
|
+
include_ai: true
|
156
|
+
)
|
157
|
+
|
158
|
+
if portfolio_report[:type] == :portfolio_summary_report
|
159
|
+
puts "Report generated successfully!"
|
160
|
+
puts "Format: #{portfolio_report[:format]}"
|
161
|
+
|
162
|
+
# Save report to file
|
163
|
+
filename = "portfolio_report_#{Time.now.strftime('%Y%m%d_%H%M%S')}.md"
|
164
|
+
File.write(filename, portfolio_report[:formatted_content])
|
165
|
+
puts "Report saved to: #{filename}"
|
166
|
+
else
|
167
|
+
puts "Report generation: #{portfolio_report[:message] || portfolio_report[:error]}"
|
168
|
+
end
|
169
|
+
|
170
|
+
# Example 8: Custom AI Analysis
|
171
|
+
puts "\n🧠 Custom AI Analysis"
|
172
|
+
puts "-" * 30
|
173
|
+
|
174
|
+
custom_prompt = "Analyze the Chilean cryptocurrency market trends and provide investment recommendations for the next week"
|
175
|
+
|
176
|
+
custom_report = reporter.generate_custom_report(
|
177
|
+
custom_prompt,
|
178
|
+
[:portfolio, :market],
|
179
|
+
format: "text"
|
180
|
+
)
|
181
|
+
|
182
|
+
if custom_report[:ai_analysis]
|
183
|
+
puts "Custom Analysis:"
|
184
|
+
puts custom_report[:ai_analysis][:content]
|
185
|
+
else
|
186
|
+
puts "Custom analysis not available"
|
187
|
+
end
|
188
|
+
|
189
|
+
rescue BudaApi::AuthenticationError
|
190
|
+
puts "❌ Authentication failed. Please check your API credentials."
|
191
|
+
rescue BudaApi::ApiError => e
|
192
|
+
puts "❌ API Error: #{e.message}"
|
193
|
+
rescue => e
|
194
|
+
puts "❌ Unexpected error: #{e.message}"
|
195
|
+
puts e.backtrace.first(5).join("\n") if ENV['DEBUG']
|
196
|
+
end
|
197
|
+
|
198
|
+
# Interactive mode
|
199
|
+
def interactive_mode
|
200
|
+
puts "\n🎮 Interactive AI Trading Mode"
|
201
|
+
puts "Type 'help' for commands, 'exit' to quit"
|
202
|
+
puts "-" * 40
|
203
|
+
|
204
|
+
client = BudaApi::AuthenticatedClient.new(
|
205
|
+
api_key: API_KEY,
|
206
|
+
api_secret: API_SECRET,
|
207
|
+
sandbox: true
|
208
|
+
)
|
209
|
+
|
210
|
+
nl_trader = BudaApi.natural_language_trader(client, llm_provider: LLM_PROVIDER)
|
211
|
+
|
212
|
+
loop do
|
213
|
+
print "\n💬 Ask me anything about trading: "
|
214
|
+
input = gets.chomp
|
215
|
+
|
216
|
+
case input.downcase
|
217
|
+
when 'exit', 'quit'
|
218
|
+
puts "👋 Goodbye!"
|
219
|
+
break
|
220
|
+
when 'help'
|
221
|
+
show_help
|
222
|
+
when 'clear'
|
223
|
+
nl_trader.clear_history
|
224
|
+
puts "🧹 Conversation history cleared"
|
225
|
+
else
|
226
|
+
if input.strip.empty?
|
227
|
+
puts "Please enter a command or question"
|
228
|
+
next
|
229
|
+
end
|
230
|
+
|
231
|
+
puts "🤔 Processing..."
|
232
|
+
result = nl_trader.execute_command(input, confirm_trades: true)
|
233
|
+
|
234
|
+
case result[:type]
|
235
|
+
when :text_response
|
236
|
+
puts "🤖 #{result[:content]}"
|
237
|
+
when :confirmation_required
|
238
|
+
puts "⚠️ #{result[:message]}"
|
239
|
+
print "Confirm? (y/n): "
|
240
|
+
confirm = gets.chomp.downcase
|
241
|
+
if confirm == 'y' || confirm == 'yes'
|
242
|
+
# Would execute the confirmed action
|
243
|
+
puts "✅ Action confirmed (demo mode - not actually executed)"
|
244
|
+
else
|
245
|
+
puts "❌ Action cancelled"
|
246
|
+
end
|
247
|
+
when :order_placed
|
248
|
+
puts "✅ #{result[:message]}"
|
249
|
+
when :balance_info
|
250
|
+
puts "💰 #{result[:message]}"
|
251
|
+
when :market_data
|
252
|
+
puts "📊 #{result[:message]}"
|
253
|
+
when :error
|
254
|
+
puts "❌ #{result[:error]}"
|
255
|
+
else
|
256
|
+
puts "📋 #{result[:message] || 'Action completed'}"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def show_help
|
263
|
+
puts """
|
264
|
+
Available commands:
|
265
|
+
- Check my [currency] balance
|
266
|
+
- What's the price of [crypto]?
|
267
|
+
- Buy/sell [amount] [crypto]
|
268
|
+
- Show order book for [market]
|
269
|
+
- Get market analysis for [market]
|
270
|
+
- What are the best trading opportunities?
|
271
|
+
- Analyze my portfolio risk
|
272
|
+
- Generate a trading report
|
273
|
+
|
274
|
+
Special commands:
|
275
|
+
- help: Show this help
|
276
|
+
- clear: Clear conversation history
|
277
|
+
- exit: Quit interactive mode
|
278
|
+
"""
|
279
|
+
end
|
280
|
+
|
281
|
+
if __FILE__ == $0
|
282
|
+
puts "Choose mode:"
|
283
|
+
puts "1. Run examples (default)"
|
284
|
+
puts "2. Interactive mode"
|
285
|
+
print "Selection (1-2): "
|
286
|
+
|
287
|
+
choice = gets.chomp
|
288
|
+
|
289
|
+
case choice
|
290
|
+
when '2'
|
291
|
+
interactive_mode if BudaApi.ai_available?
|
292
|
+
else
|
293
|
+
main
|
294
|
+
end
|
295
|
+
end
|