bank_of_thailand 0.1.0
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 +7 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +15 -0
- data/LICENSE.txt +21 -0
- data/README.md +293 -0
- data/Rakefile +12 -0
- data/docs/openapi_spec/average-exchange-rate-thb--foreign-currency-2_0_2.json +778 -0
- data/docs/openapi_spec/botlicensecheckapi-1_0_2.json +122 -0
- data/docs/openapi_spec/debt-securities-auction-result-current-2_0_0.json +201 -0
- data/docs/openapi_spec/debt-securities-auction-result-current_2.0.0.json +201 -0
- data/docs/openapi_spec/deposit-interest-rates-for-individuals-of-commercial-banks-percent-per-annum-2_0_0.json +354 -0
- data/docs/openapi_spec/financial-institutions-holidays-1_0_1.json +98 -0
- data/docs/openapi_spec/interbank-transaction-rates-percent-per-annum-2_0_0.json +224 -0
- data/docs/openapi_spec/loan-interest-rates-of-commercial-banks-percent-per-annum-2_0_0.json +335 -0
- data/docs/openapi_spec/search-series_1.0.0.json +177 -0
- data/docs/openapi_spec/swap-point-onshore-in-satangs-2_0_0.json +196 -0
- data/docs/openapi_spec/thai-baht-implied-interest-rates-percent-per-annum-2_0_0.json +182 -0
- data/docs/openapi_spec/weighted-average-interbank-exchange-rate-thb--usd-2_0_1.json +546 -0
- data/lib/bank_of_thailand/client.rb +188 -0
- data/lib/bank_of_thailand/configuration.rb +88 -0
- data/lib/bank_of_thailand/errors.rb +46 -0
- data/lib/bank_of_thailand/resource.rb +34 -0
- data/lib/bank_of_thailand/resources/average_exchange_rate.rb +81 -0
- data/lib/bank_of_thailand/resources/deposit_rate.rb +46 -0
- data/lib/bank_of_thailand/resources/exchange_rate.rb +103 -0
- data/lib/bank_of_thailand/resources/financial_holidays.rb +30 -0
- data/lib/bank_of_thailand/resources/implied_rate.rb +39 -0
- data/lib/bank_of_thailand/resources/interbank_rate.rb +39 -0
- data/lib/bank_of_thailand/resources/interest_rate.rb +49 -0
- data/lib/bank_of_thailand/resources/loan_rate.rb +45 -0
- data/lib/bank_of_thailand/resources/search_series.rb +37 -0
- data/lib/bank_of_thailand/resources/statistics.rb +80 -0
- data/lib/bank_of_thailand/resources/swap_point.rb +38 -0
- data/lib/bank_of_thailand/version.rb +5 -0
- data/lib/bank_of_thailand.rb +56 -0
- data/sig/bank_of_thailand.rbs +4 -0
- metadata +211 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
require "faraday/retry"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
module BankOfThailand
|
|
8
|
+
# HTTP client for making requests to the BOT API
|
|
9
|
+
class Client
|
|
10
|
+
# @return [Configuration] the configuration instance
|
|
11
|
+
attr_reader :config
|
|
12
|
+
|
|
13
|
+
# Initialize a new Client
|
|
14
|
+
# @param config [Configuration, nil] Optional configuration instance
|
|
15
|
+
# @yield [Configuration] optional configuration block
|
|
16
|
+
#
|
|
17
|
+
# @example With global configuration
|
|
18
|
+
# client = BankOfThailand::Client.new
|
|
19
|
+
#
|
|
20
|
+
# @example With instance configuration
|
|
21
|
+
# client = BankOfThailand::Client.new do |config|
|
|
22
|
+
# config.api_token = "your_token"
|
|
23
|
+
# end
|
|
24
|
+
def initialize(config = nil)
|
|
25
|
+
@config = config || BankOfThailand.configuration.dup
|
|
26
|
+
yield(@config) if block_given?
|
|
27
|
+
@config.validate!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Access exchange rate endpoints
|
|
31
|
+
# @return [Resources::ExchangeRate]
|
|
32
|
+
def exchange_rate
|
|
33
|
+
@exchange_rate ||= Resources::ExchangeRate.new(self)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Access debt securities auction endpoints
|
|
37
|
+
# @return [Resources::DebtSecurities]
|
|
38
|
+
def debt_securities
|
|
39
|
+
@debt_securities ||= Resources::DebtSecurities.new(self)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Access license check endpoints
|
|
43
|
+
# @return [Resources::LicenseCheck]
|
|
44
|
+
def license_check
|
|
45
|
+
@license_check ||= Resources::LicenseCheck.new(self)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Access average exchange rate endpoints
|
|
49
|
+
# @return [AverageExchangeRate]
|
|
50
|
+
def average_exchange_rate
|
|
51
|
+
@average_exchange_rate ||= AverageExchangeRate.new(self)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Access deposit rate endpoints
|
|
55
|
+
# @return [DepositRate]
|
|
56
|
+
def deposit_rate
|
|
57
|
+
@deposit_rate ||= DepositRate.new(self)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Access financial holidays endpoints
|
|
61
|
+
# @return [FinancialHolidays]
|
|
62
|
+
def financial_holidays
|
|
63
|
+
@financial_holidays ||= FinancialHolidays.new(self)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Access interbank rate endpoints
|
|
67
|
+
# @return [InterbankRate]
|
|
68
|
+
def interbank_rate
|
|
69
|
+
@interbank_rate ||= InterbankRate.new(self)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Access loan rate endpoints
|
|
73
|
+
# @return [LoanRate]
|
|
74
|
+
def loan_rate
|
|
75
|
+
@loan_rate ||= LoanRate.new(self)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Access swap point endpoints
|
|
79
|
+
# @return [SwapPoint]
|
|
80
|
+
def swap_point
|
|
81
|
+
@swap_point ||= SwapPoint.new(self)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Access implied rate endpoints
|
|
85
|
+
# @return [ImpliedRate]
|
|
86
|
+
def implied_rate
|
|
87
|
+
@implied_rate ||= ImpliedRate.new(self)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Access search series endpoints
|
|
91
|
+
# @return [SearchSeries]
|
|
92
|
+
def search_series
|
|
93
|
+
@search_series ||= SearchSeries.new(self)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Make a GET request
|
|
97
|
+
# @param path [String] API endpoint path
|
|
98
|
+
# @param params [Hash] Query parameters
|
|
99
|
+
# @return [Hash] Parsed JSON response
|
|
100
|
+
# @raise [RequestError] if request fails
|
|
101
|
+
def get(path, params = {})
|
|
102
|
+
request(:get, path, params: params)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Make a POST request
|
|
106
|
+
# @param path [String] API endpoint path
|
|
107
|
+
# @param body [Hash] Request body
|
|
108
|
+
# @param params [Hash] Query parameters
|
|
109
|
+
# @return [Hash] Parsed JSON response
|
|
110
|
+
# @raise [RequestError] if request fails
|
|
111
|
+
def post(path, body: {}, params: {})
|
|
112
|
+
request(:post, path, body: body, params: params)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
# Make an HTTP request
|
|
118
|
+
# @param method [Symbol] HTTP method (:get, :post, etc.)
|
|
119
|
+
# @param path [String] API endpoint path (can be full URL or relative path)
|
|
120
|
+
# @param params [Hash] Query parameters
|
|
121
|
+
# @param body [Hash] Request body
|
|
122
|
+
# @return [Hash] Parsed response
|
|
123
|
+
# @raise [RequestError] if request fails
|
|
124
|
+
def request(method, path, params: {}, body: nil)
|
|
125
|
+
# Determine if path is a full URL or relative path
|
|
126
|
+
url = if path.start_with?("http://", "https://")
|
|
127
|
+
path
|
|
128
|
+
else
|
|
129
|
+
"#{config.base_url}#{path}"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
response = Faraday.send(method, url) do |req|
|
|
133
|
+
req.headers["Authorization"] = config.api_token
|
|
134
|
+
req.headers["Content-Type"] = "application/json"
|
|
135
|
+
req.params = params if params.any?
|
|
136
|
+
req.body = body.to_json if body
|
|
137
|
+
req.options.timeout = config.timeout
|
|
138
|
+
req.options.open_timeout = config.timeout
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
handle_response(response)
|
|
142
|
+
rescue Faraday::TimeoutError => e
|
|
143
|
+
raise RequestError, "Request timeout: #{e.message}"
|
|
144
|
+
rescue Faraday::ConnectionFailed => e
|
|
145
|
+
raise RequestError, "Connection failed: #{e.message}"
|
|
146
|
+
rescue Faraday::Error => e
|
|
147
|
+
raise RequestError, "Request failed: #{e.message}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Handle HTTP response
|
|
151
|
+
# @param response [Faraday::Response] HTTP response
|
|
152
|
+
# @return [Hash] Parsed response body
|
|
153
|
+
# @raise [RequestError] if response indicates an error
|
|
154
|
+
def handle_response(response)
|
|
155
|
+
case response.status
|
|
156
|
+
when 200..299
|
|
157
|
+
parse_json(response.body)
|
|
158
|
+
when 401
|
|
159
|
+
raise AuthenticationError.new("Authentication failed. Check your API token.", response)
|
|
160
|
+
when 403
|
|
161
|
+
raise AuthenticationError.new(
|
|
162
|
+
"Access forbidden. Your token may not have permission for this resource.",
|
|
163
|
+
response
|
|
164
|
+
)
|
|
165
|
+
when 404
|
|
166
|
+
raise NotFoundError.new("Resource not found: #{response.env.url}", response)
|
|
167
|
+
when 429
|
|
168
|
+
retry_after = response.headers["retry-after"]&.to_i
|
|
169
|
+
raise RateLimitError.new("Rate limit exceeded", response, retry_after)
|
|
170
|
+
when 500..599
|
|
171
|
+
raise ServerError.new("Server error (#{response.status})", response)
|
|
172
|
+
else
|
|
173
|
+
raise RequestError.new("Unexpected response status: #{response.status}", response)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Parse JSON response
|
|
178
|
+
# @param body [String] Response body
|
|
179
|
+
# @return [Hash] Parsed JSON
|
|
180
|
+
def parse_json(body)
|
|
181
|
+
return {} if body.nil? || body.empty?
|
|
182
|
+
|
|
183
|
+
JSON.parse(body)
|
|
184
|
+
rescue JSON::ParserError => e
|
|
185
|
+
raise RequestError, "Invalid JSON response: #{e.message}"
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Configuration for the BankOfThailand API client
|
|
5
|
+
class Configuration
|
|
6
|
+
# @return [String] API token for authentication
|
|
7
|
+
attr_accessor :api_token
|
|
8
|
+
|
|
9
|
+
# @return [String] Base URL for the BOT API gateway
|
|
10
|
+
attr_accessor :base_url
|
|
11
|
+
|
|
12
|
+
# @return [Integer] Request timeout in seconds
|
|
13
|
+
attr_accessor :timeout
|
|
14
|
+
|
|
15
|
+
# @return [Integer] Number of retry attempts for failed requests
|
|
16
|
+
attr_accessor :max_retries
|
|
17
|
+
|
|
18
|
+
# @return [Logger, nil] Logger instance for debugging
|
|
19
|
+
attr_accessor :logger
|
|
20
|
+
|
|
21
|
+
# Default base URL for the BOT API
|
|
22
|
+
DEFAULT_BASE_URL = "https://gateway.api.bot.or.th"
|
|
23
|
+
|
|
24
|
+
# Default timeout in seconds
|
|
25
|
+
DEFAULT_TIMEOUT = 30
|
|
26
|
+
|
|
27
|
+
# Default number of retries
|
|
28
|
+
DEFAULT_MAX_RETRIES = 3
|
|
29
|
+
|
|
30
|
+
# Initialize a new Configuration instance
|
|
31
|
+
def initialize
|
|
32
|
+
@api_token = nil
|
|
33
|
+
@base_url = DEFAULT_BASE_URL
|
|
34
|
+
@timeout = DEFAULT_TIMEOUT
|
|
35
|
+
@max_retries = DEFAULT_MAX_RETRIES
|
|
36
|
+
@logger = nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Validate the configuration
|
|
40
|
+
# @raise [ConfigurationError] if configuration is invalid
|
|
41
|
+
# @return [Boolean] true if valid
|
|
42
|
+
def validate!
|
|
43
|
+
raise ConfigurationError, "API token is required" if api_token.nil? || api_token.empty?
|
|
44
|
+
raise ConfigurationError, "Base URL cannot be empty" if base_url.nil? || base_url.empty?
|
|
45
|
+
|
|
46
|
+
true
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Check if configuration is valid
|
|
50
|
+
# @return [Boolean] true if valid, false otherwise
|
|
51
|
+
def valid?
|
|
52
|
+
validate!
|
|
53
|
+
true
|
|
54
|
+
rescue ConfigurationError
|
|
55
|
+
false
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class << self
|
|
60
|
+
# @return [Configuration] the global configuration instance
|
|
61
|
+
attr_writer :configuration
|
|
62
|
+
|
|
63
|
+
# Get the global configuration
|
|
64
|
+
# @return [Configuration] the configuration instance
|
|
65
|
+
def configuration
|
|
66
|
+
@configuration ||= Configuration.new
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Configure the gem
|
|
70
|
+
# @yield [Configuration] the configuration instance
|
|
71
|
+
# @return [void]
|
|
72
|
+
#
|
|
73
|
+
# @example
|
|
74
|
+
# BankOfThailand.configure do |config|
|
|
75
|
+
# config.api_token = "your_token_here"
|
|
76
|
+
# config.timeout = 60
|
|
77
|
+
# end
|
|
78
|
+
def configure
|
|
79
|
+
yield(configuration)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Reset configuration to defaults
|
|
83
|
+
# @return [Configuration] new configuration instance
|
|
84
|
+
def reset_configuration!
|
|
85
|
+
@configuration = Configuration.new
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Base error class for all BankOfThailand errors
|
|
5
|
+
class Error < StandardError; end
|
|
6
|
+
|
|
7
|
+
# Raised when API request fails
|
|
8
|
+
class RequestError < Error
|
|
9
|
+
attr_reader :response
|
|
10
|
+
|
|
11
|
+
# @param message [String] Error message
|
|
12
|
+
# @param response [Faraday::Response, nil] HTTP response object
|
|
13
|
+
def initialize(message, response = nil)
|
|
14
|
+
@response = response
|
|
15
|
+
super(message)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Raised when authentication fails
|
|
20
|
+
class AuthenticationError < RequestError; end
|
|
21
|
+
|
|
22
|
+
# Raised when the API token is missing or invalid
|
|
23
|
+
class InvalidTokenError < AuthenticationError; end
|
|
24
|
+
|
|
25
|
+
# Raised when the requested resource is not found
|
|
26
|
+
class NotFoundError < RequestError; end
|
|
27
|
+
|
|
28
|
+
# Raised when rate limit is exceeded
|
|
29
|
+
class RateLimitError < RequestError
|
|
30
|
+
attr_reader :retry_after
|
|
31
|
+
|
|
32
|
+
# @param message [String] Error message
|
|
33
|
+
# @param response [Faraday::Response, nil] HTTP response object
|
|
34
|
+
# @param retry_after [Integer, nil] Seconds to wait before retrying
|
|
35
|
+
def initialize(message, response = nil, retry_after = nil)
|
|
36
|
+
@retry_after = retry_after
|
|
37
|
+
super(message, response)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Raised when server returns 5xx error
|
|
42
|
+
class ServerError < RequestError; end
|
|
43
|
+
|
|
44
|
+
# Raised when configuration is invalid
|
|
45
|
+
class ConfigurationError < Error; end
|
|
46
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Base class for API resources
|
|
5
|
+
class Resource
|
|
6
|
+
# @return [Client] the API client instance
|
|
7
|
+
attr_reader :client
|
|
8
|
+
|
|
9
|
+
# Initialize a new Resource
|
|
10
|
+
# @param client [Client] API client instance
|
|
11
|
+
def initialize(client)
|
|
12
|
+
@client = client
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# Make a GET request
|
|
18
|
+
# @param path [String] API endpoint path
|
|
19
|
+
# @param params [Hash] Query parameters
|
|
20
|
+
# @return [Hash] Response data
|
|
21
|
+
def get(path, params = {})
|
|
22
|
+
client.get(path, params)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Make a POST request
|
|
26
|
+
# @param path [String] API endpoint path
|
|
27
|
+
# @param body [Hash] Request body
|
|
28
|
+
# @param params [Hash] Query parameters
|
|
29
|
+
# @return [Hash] Response data
|
|
30
|
+
def post(path, body: {}, params: {})
|
|
31
|
+
client.post(path, body: body, params: params)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Average Exchange Rate - THB / Foreign Currency resource
|
|
5
|
+
#
|
|
6
|
+
# This resource provides access to daily average exchange rates between Thai Baht
|
|
7
|
+
# and 19 foreign currencies from commercial banks in Thailand.
|
|
8
|
+
#
|
|
9
|
+
# @example Get daily average exchange rates
|
|
10
|
+
# client = BankOfThailand.client
|
|
11
|
+
# rates = client.average_exchange_rate.daily(
|
|
12
|
+
# start_period: "2024-01-01",
|
|
13
|
+
# end_period: "2024-01-31",
|
|
14
|
+
# currency: "USD"
|
|
15
|
+
# )
|
|
16
|
+
class AverageExchangeRate < Resource
|
|
17
|
+
BASE_URL = "https://gateway.api.bot.or.th/Stat-ExchangeRate/v2"
|
|
18
|
+
|
|
19
|
+
# Get daily average exchange rates
|
|
20
|
+
#
|
|
21
|
+
# @param start_period [String] Start period date (YYYY-MM-DD)
|
|
22
|
+
# @param end_period [String] End period date (YYYY-MM-DD)
|
|
23
|
+
# @param currency [String, nil] Foreign currency code (optional)
|
|
24
|
+
# @return [Hash] Response containing daily average exchange rate data
|
|
25
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
26
|
+
def daily(start_period:, end_period:, currency: nil)
|
|
27
|
+
params = { start_period: start_period, end_period: end_period }
|
|
28
|
+
params[:currency] = currency if currency
|
|
29
|
+
|
|
30
|
+
get_with_base_url("/DAILY_AVG_EXG_RATE/", params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Get monthly average exchange rates
|
|
34
|
+
#
|
|
35
|
+
# @param start_period [String] Start period (YYYY-MM)
|
|
36
|
+
# @param end_period [String] End period (YYYY-MM)
|
|
37
|
+
# @param currency [String, nil] Foreign currency code (optional)
|
|
38
|
+
# @return [Hash] Response containing monthly average exchange rate data
|
|
39
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
40
|
+
def monthly(start_period:, end_period:, currency: nil)
|
|
41
|
+
params = { start_period: start_period, end_period: end_period }
|
|
42
|
+
params[:currency] = currency if currency
|
|
43
|
+
|
|
44
|
+
get_with_base_url("/MONTHLY_AVG_EXG_RATE/", params)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Get quarterly average exchange rates
|
|
48
|
+
#
|
|
49
|
+
# @param start_period [String] Start period (YYYY-QN, e.g., 2024-Q1)
|
|
50
|
+
# @param end_period [String] End period (YYYY-QN)
|
|
51
|
+
# @param currency [String, nil] Foreign currency code (optional)
|
|
52
|
+
# @return [Hash] Response containing quarterly average exchange rate data
|
|
53
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
54
|
+
def quarterly(start_period:, end_period:, currency: nil)
|
|
55
|
+
params = { start_period: start_period, end_period: end_period }
|
|
56
|
+
params[:currency] = currency if currency
|
|
57
|
+
|
|
58
|
+
get_with_base_url("/QUARTERLY_AVG_EXG_RATE/", params)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get annual average exchange rates
|
|
62
|
+
#
|
|
63
|
+
# @param start_period [String] Start period (YYYY)
|
|
64
|
+
# @param end_period [String] End period (YYYY)
|
|
65
|
+
# @param currency [String, nil] Foreign currency code (optional)
|
|
66
|
+
# @return [Hash] Response containing annual average exchange rate data
|
|
67
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
68
|
+
def annual(start_period:, end_period:, currency: nil)
|
|
69
|
+
params = { start_period: start_period, end_period: end_period }
|
|
70
|
+
params[:currency] = currency if currency
|
|
71
|
+
|
|
72
|
+
get_with_base_url("/ANNUAL_AVG_EXG_RATE/", params)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def get_with_base_url(path, params = {})
|
|
78
|
+
@client.get("#{BASE_URL}#{path}", params)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Deposit Interest Rates resource
|
|
5
|
+
#
|
|
6
|
+
# This resource provides access to deposit interest rates for individuals
|
|
7
|
+
# from commercial banks in Thailand.
|
|
8
|
+
#
|
|
9
|
+
# @example Get deposit rates
|
|
10
|
+
# client = BankOfThailand.client
|
|
11
|
+
# rates = client.deposit_rate.rates(
|
|
12
|
+
# start_period: "2024-01-01",
|
|
13
|
+
# end_period: "2024-01-31"
|
|
14
|
+
# )
|
|
15
|
+
class DepositRate < Resource
|
|
16
|
+
BASE_URL = "https://gateway.api.bot.or.th/DepositRate/v2"
|
|
17
|
+
|
|
18
|
+
# Get deposit interest rates for individuals of commercial banks
|
|
19
|
+
#
|
|
20
|
+
# @param start_period [String] Start period date (YYYY-MM-DD)
|
|
21
|
+
# @param end_period [String] End period date (YYYY-MM-DD)
|
|
22
|
+
# @return [Hash] Response containing deposit interest rate data
|
|
23
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
24
|
+
def rates(start_period:, end_period:)
|
|
25
|
+
params = { start_period: start_period, end_period: end_period }
|
|
26
|
+
get_with_base_url("/deposit_rate/", params)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Get min-max deposit interest rates for individuals of commercial banks
|
|
30
|
+
#
|
|
31
|
+
# @param start_period [String] Start period date (YYYY-MM-DD)
|
|
32
|
+
# @param end_period [String] End period date (YYYY-MM-DD)
|
|
33
|
+
# @return [Hash] Response containing min-max deposit interest rate data
|
|
34
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
35
|
+
def average_rates(start_period:, end_period:)
|
|
36
|
+
params = { start_period: start_period, end_period: end_period }
|
|
37
|
+
get_with_base_url("/avg_deposit_rate/", params)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def get_with_base_url(path, params = {})
|
|
43
|
+
@client.get("#{BASE_URL}#{path}", params)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
module Resources
|
|
5
|
+
# Weighted-average Interbank Exchange Rate - THB / USD
|
|
6
|
+
#
|
|
7
|
+
# This API provides weighted-average interbank exchange rates calculated from
|
|
8
|
+
# daily interbank purchases and sales of US Dollar (against THB) for transactions
|
|
9
|
+
# worth more than or equal to 1 million USD.
|
|
10
|
+
#
|
|
11
|
+
# @see https://gateway.api.bot.or.th/Stat-ReferenceRate/v2
|
|
12
|
+
class ExchangeRate < Resource
|
|
13
|
+
# Base URL for this API (overrides the global base URL)
|
|
14
|
+
BASE_URL = "https://gateway.api.bot.or.th/Stat-ReferenceRate/v2"
|
|
15
|
+
|
|
16
|
+
# Get daily weighted-average interbank exchange rate
|
|
17
|
+
#
|
|
18
|
+
# @param start_period [String] Start date in YYYY-MM-DD format (e.g., "2017-06-30")
|
|
19
|
+
# @param end_period [String] End date in YYYY-MM-DD format (e.g., "2017-06-30")
|
|
20
|
+
# @return [Hash] Response containing daily exchange rate data
|
|
21
|
+
#
|
|
22
|
+
# @example Get daily rates for a date range
|
|
23
|
+
# client.exchange_rate.daily(
|
|
24
|
+
# start_period: "2025-01-01",
|
|
25
|
+
# end_period: "2025-01-31"
|
|
26
|
+
# )
|
|
27
|
+
def daily(start_period:, end_period:)
|
|
28
|
+
get_with_base_url(
|
|
29
|
+
"#{BASE_URL}/DAILY_REF_RATE/",
|
|
30
|
+
start_period: start_period,
|
|
31
|
+
end_period: end_period
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Get monthly weighted-average interbank exchange rate
|
|
36
|
+
#
|
|
37
|
+
# @param start_period [String] Start period in YYYY-MM format (e.g., "2017-06")
|
|
38
|
+
# @param end_period [String] End period in YYYY-MM format (e.g., "2017-06")
|
|
39
|
+
# @return [Hash] Response containing monthly exchange rate data
|
|
40
|
+
#
|
|
41
|
+
# @example Get monthly rates
|
|
42
|
+
# client.exchange_rate.monthly(
|
|
43
|
+
# start_period: "2025-01",
|
|
44
|
+
# end_period: "2025-03"
|
|
45
|
+
# )
|
|
46
|
+
def monthly(start_period:, end_period:)
|
|
47
|
+
get_with_base_url(
|
|
48
|
+
"#{BASE_URL}/MONTHLY_REF_RATE/",
|
|
49
|
+
start_period: start_period,
|
|
50
|
+
end_period: end_period
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Get quarterly weighted-average interbank exchange rate
|
|
55
|
+
#
|
|
56
|
+
# @param start_period [String] Start period in YYYY-QN format (e.g., "2017-Q1")
|
|
57
|
+
# @param end_period [String] End period in YYYY-QN format (e.g., "2017-Q1")
|
|
58
|
+
# @return [Hash] Response containing quarterly exchange rate data
|
|
59
|
+
#
|
|
60
|
+
# @example Get quarterly rates
|
|
61
|
+
# client.exchange_rate.quarterly(
|
|
62
|
+
# start_period: "2025-Q1",
|
|
63
|
+
# end_period: "2025-Q2"
|
|
64
|
+
# )
|
|
65
|
+
def quarterly(start_period:, end_period:)
|
|
66
|
+
get_with_base_url(
|
|
67
|
+
"#{BASE_URL}/QUARTERLY_REF_RATE/",
|
|
68
|
+
start_period: start_period,
|
|
69
|
+
end_period: end_period
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Get annual weighted-average interbank exchange rate
|
|
74
|
+
#
|
|
75
|
+
# @param start_period [String] Start year in YYYY format (e.g., "2017")
|
|
76
|
+
# @param end_period [String] End year in YYYY format (e.g., "2017")
|
|
77
|
+
# @return [Hash] Response containing annual exchange rate data
|
|
78
|
+
#
|
|
79
|
+
# @example Get annual rates
|
|
80
|
+
# client.exchange_rate.annual(
|
|
81
|
+
# start_period: "2020",
|
|
82
|
+
# end_period: "2024"
|
|
83
|
+
# )
|
|
84
|
+
def annual(start_period:, end_period:)
|
|
85
|
+
get_with_base_url(
|
|
86
|
+
"#{BASE_URL}/ANNUAL_REF_RATE/",
|
|
87
|
+
start_period: start_period,
|
|
88
|
+
end_period: end_period
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
# Make a GET request with a custom base URL
|
|
95
|
+
# @param url [String] Full URL path
|
|
96
|
+
# @param params [Hash] Query parameters
|
|
97
|
+
# @return [Hash] Response data
|
|
98
|
+
def get_with_base_url(url, params = {})
|
|
99
|
+
client.get(url, params)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Financial Institutions' Holidays resource
|
|
5
|
+
#
|
|
6
|
+
# This resource provides access to the list of holidays for financial institutions in Thailand.
|
|
7
|
+
#
|
|
8
|
+
# @example Get holidays for a year
|
|
9
|
+
# client = BankOfThailand.client
|
|
10
|
+
# holidays = client.financial_holidays.list(year: "2024")
|
|
11
|
+
class FinancialHolidays < Resource
|
|
12
|
+
BASE_URL = "https://gateway.api.bot.or.th/financial-institutions-holidays"
|
|
13
|
+
|
|
14
|
+
# Get financial institutions' holidays for a specific year
|
|
15
|
+
#
|
|
16
|
+
# @param year [String] Year in format YYYY (e.g., "2024")
|
|
17
|
+
# @return [Array<Hash>] Array of holiday data
|
|
18
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
19
|
+
def list(year:)
|
|
20
|
+
params = { year: year }
|
|
21
|
+
get_with_base_url("/", params)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def get_with_base_url(path, params = {})
|
|
27
|
+
@client.get("#{BASE_URL}#{path}", params)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Thai Baht Implied Interest Rates resource
|
|
5
|
+
#
|
|
6
|
+
# This resource provides access to Thai Baht implied interest rates derived from
|
|
7
|
+
# the swap market.
|
|
8
|
+
#
|
|
9
|
+
# @example Get implied interest rates
|
|
10
|
+
# client = BankOfThailand.client
|
|
11
|
+
# rates = client.implied_rate.rates(
|
|
12
|
+
# start_period: "2024-01-01",
|
|
13
|
+
# end_period: "2024-01-31",
|
|
14
|
+
# rate_type: "ONSHORE : T/N"
|
|
15
|
+
# )
|
|
16
|
+
class ImpliedRate < Resource
|
|
17
|
+
BASE_URL = "https://gateway.api.bot.or.th/Stat-ThaiBahtImpliedInterestRate/v2/THB_IMPL_INT_RATE"
|
|
18
|
+
|
|
19
|
+
# Get Thai Baht implied interest rates
|
|
20
|
+
#
|
|
21
|
+
# @param start_period [String] Start period date (YYYY-MM-DD)
|
|
22
|
+
# @param end_period [String] End period date (YYYY-MM-DD)
|
|
23
|
+
# @param rate_type [String, nil] Rate type (e.g., "ONSHORE : T/N") (optional)
|
|
24
|
+
# @return [Hash] Response containing Thai Baht implied interest rate data
|
|
25
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
26
|
+
def rates(start_period:, end_period:, rate_type: nil)
|
|
27
|
+
params = { start_period: start_period, end_period: end_period }
|
|
28
|
+
params[:rate_type] = rate_type if rate_type
|
|
29
|
+
|
|
30
|
+
get_with_base_url("/", params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def get_with_base_url(path, params = {})
|
|
36
|
+
@client.get("#{BASE_URL}#{path}", params)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BankOfThailand
|
|
4
|
+
# Interbank Transaction Rates resource
|
|
5
|
+
#
|
|
6
|
+
# This resource provides access to interbank transaction rates from commercial banks
|
|
7
|
+
# and financial institutions in Thailand.
|
|
8
|
+
#
|
|
9
|
+
# @example Get interbank rates
|
|
10
|
+
# client = BankOfThailand.client
|
|
11
|
+
# rates = client.interbank_rate.rates(
|
|
12
|
+
# start_period: "2024-01-01",
|
|
13
|
+
# end_period: "2024-01-31",
|
|
14
|
+
# term_type: "O/N"
|
|
15
|
+
# )
|
|
16
|
+
class InterbankRate < Resource
|
|
17
|
+
BASE_URL = "https://gateway.api.bot.or.th/Stat-InterbankTransactionRate/v2/INTRBNK_TXN_RATE"
|
|
18
|
+
|
|
19
|
+
# Get interbank transaction rates
|
|
20
|
+
#
|
|
21
|
+
# @param start_period [String] Start period date (YYYY-MM-DD)
|
|
22
|
+
# @param end_period [String] End period date (YYYY-MM-DD)
|
|
23
|
+
# @param term_type [String, nil] Term type (e.g., "O/N", "T/N") (optional)
|
|
24
|
+
# @return [Hash] Response containing interbank transaction rate data
|
|
25
|
+
# @raise [BankOfThailand::Error] if the request fails
|
|
26
|
+
def rates(start_period:, end_period:, term_type: nil)
|
|
27
|
+
params = { start_period: start_period, end_period: end_period }
|
|
28
|
+
params[:term_type] = term_type if term_type
|
|
29
|
+
|
|
30
|
+
get_with_base_url("/", params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def get_with_base_url(path, params = {})
|
|
36
|
+
@client.get("#{BASE_URL}#{path}", params)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|