Class: Alpaca::Trade::Api::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/alpaca/trade/api/client.rb

Constant Summary collapse

TIMEFRAMES =
['minute', '1Min', '5Min', '15Min', 'day', '1D']

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(endpoint: Alpaca::Trade::Api.configuration.endpoint, key_id: Alpaca::Trade::Api.configuration.key_id, key_secret: Alpaca::Trade::Api.configuration.key_secret) ⇒ Client

Returns a new instance of Client.



14
15
16
17
18
19
20
21
# File 'lib/alpaca/trade/api/client.rb', line 14

def initialize(endpoint: Alpaca::Trade::Api.configuration.endpoint,
               key_id: Alpaca::Trade::Api.configuration.key_id,
               key_secret: Alpaca::Trade::Api.configuration.key_secret)
  @data_endpoint = Alpaca::Trade::Api.configuration.data_endpoint
  @endpoint = endpoint
  @key_id = key_id
  @key_secret = key_secret
end

Instance Attribute Details

#data_endpointObject (readonly)

Returns the value of attribute data_endpoint.



10
11
12
# File 'lib/alpaca/trade/api/client.rb', line 10

def data_endpoint
  @data_endpoint
end

#endpointObject (readonly)

Returns the value of attribute endpoint.



10
11
12
# File 'lib/alpaca/trade/api/client.rb', line 10

def endpoint
  @endpoint
end

#key_idObject (readonly)

Returns the value of attribute key_id.



10
11
12
# File 'lib/alpaca/trade/api/client.rb', line 10

def key_id
  @key_id
end

#key_secretObject (readonly)

Returns the value of attribute key_secret.



10
11
12
# File 'lib/alpaca/trade/api/client.rb', line 10

def key_secret
  @key_secret
end

Instance Method Details

#accountObject



23
24
25
26
# File 'lib/alpaca/trade/api/client.rb', line 23

def 
  response = get_request(endpoint, 'v2/account')
  Account.new(JSON.parse(response.body))
end

#account_activities(activity_type:) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/alpaca/trade/api/client.rb', line 28

def (activity_type:)
  response = get_request(endpoint, "/v2/account/activities/#{activity_type}")
  raise InvalidActivityType, JSON.parse(response.body)['message'] if response.status == 422
  json = JSON.parse(response.body)
  activity_class = (TradeActivity::ATTRIBUTES - json.first.to_h.keys).none? ? TradeActivity : NonTradeActivity
  json.map { |item| activity_class.new(item) }
end

#asset(symbol:) ⇒ Object



36
37
38
39
# File 'lib/alpaca/trade/api/client.rb', line 36

def asset(symbol:)
  response = get_request(endpoint, "v2/assets/#{symbol}")
  Asset.new(JSON.parse(response.body))
end

#assets(status: nil, asset_class: nil) ⇒ Object



41
42
43
44
45
# File 'lib/alpaca/trade/api/client.rb', line 41

def assets(status: nil, asset_class: nil)
  response = get_request(endpoint, "v2/assets", { status: status, asset_class: asset_class }.compact)
  json = JSON.parse(response.body)
  json.map { |item| Asset.new(item) }
end

#bars(timeframe, symbols, limit: 100) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/alpaca/trade/api/client.rb', line 47

def bars(timeframe, symbols, limit: 100)
  validate_timeframe(timeframe)
  response = get_request(data_endpoint, "v1/bars/#{timeframe}", symbols: symbols.join(','), limit: limit)
  json = JSON.parse(response.body)
  json.keys.each_with_object({}) do |symbol, hash|
    hash[symbol] = json[symbol].map { |bar| Bar.new(bar) }
  end
end

#calendar(start_date: Date.today, end_date: (Date.today + 30)) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/alpaca/trade/api/client.rb', line 56

def calendar(start_date: Date.today, end_date: (Date.today + 30))
  # FIX, use start_date.strftime('%F')
  params = { "start" => start_date.iso8601, "end" => end_date.iso8601 }
  response = get_request(endpoint, "v2/calendar", params)
  json = JSON.parse(response.body)
  json.map { |item| Calendar.new(item) }
end

#cancel_order(id:) ⇒ Object

Raises:



64
65
66
67
68
# File 'lib/alpaca/trade/api/client.rb', line 64

def cancel_order(id:)
  response = delete_request(endpoint, "v2/orders/#{id}")
  raise InvalidOrderId, JSON.parse(response.body)['message'] if response.status == 404
  raise OrderNotCancelable if response.status == 422
end

#cancel_ordersObject



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/alpaca/trade/api/client.rb', line 70

def cancel_orders
  response = delete_request(endpoint, 'v2/orders')

  json = JSON.parse(response.body)
  json.map do |item|
    {
      'id' => item['id'],
      'status' => item['status'],
      'body' => Order.new(item['body']),
    }
  end
end

#clockObject



83
84
85
86
# File 'lib/alpaca/trade/api/client.rb', line 83

def clock
  response = get_request(endpoint, 'v2/clock')
  Clock.new(JSON.parse(response.body))
end

#close_position(symbol:) ⇒ Object



88
89
90
91
92
93
# File 'lib/alpaca/trade/api/client.rb', line 88

def close_position(symbol:)
  response = delete_request(endpoint, "v2/positions/#{symbol}")
  raise NoPositionForSymbol, JSON.parse(response.body)['message'] if response.status == 404

  Position.new(JSON.parse(response.body))
end

#close_positionsObject



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/alpaca/trade/api/client.rb', line 95

def close_positions
  response = delete_request(endpoint, 'v2/positions')

  json = JSON.parse(response.body)
  json.map do |item|
    {
      'symbol' => item['symbol'],
      'status' => item['status'],
      'body' => Position.new(item['body']),
    }
  end
end

#last_trade(symbol:) ⇒ Object

Raises:



108
109
110
111
112
113
# File 'lib/alpaca/trade/api/client.rb', line 108

def last_trade(symbol:)
  response = get_request(data_endpoint, "v1/last/stocks/#{symbol}")
  raise InvalidRequest, JSON.parse(response.body)['message'] if response.status == 404

  LastTrade.new(JSON.parse(response.body))
end

#new_order(symbol:, side:, type:, time_in_force:, qty: nil, notional: nil, limit_price: nil, stop_price: nil, extended_hours: false, client_order_id: nil, order_class: nil, take_profit: nil, stop_loss: nil) ⇒ Object

Raises:



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/alpaca/trade/api/client.rb', line 115

def new_order(symbol:, side:, type:, time_in_force:, qty: nil, notional: nil,
  limit_price: nil, stop_price: nil, extended_hours: false, client_order_id: nil,
  order_class: nil, take_profit: nil, stop_loss: nil)

  params = {
    symbol: symbol,
    side: side,
    type: type,
    time_in_force: time_in_force,
    qty: qty,
    notional: notional,
    limit_price: limit_price,
    order_class: order_class,
    stop_price: stop_price,
    take_profit: take_profit,
    stop_loss: stop_loss,
    extended_hours: extended_hours,
    client_order_id: client_order_id
  }
  response = post_request(endpoint, 'v2/orders', params.compact)
  raise InsufficientFunds, JSON.parse(response.body)['message'] if response.status == 403
  raise MissingParameters, JSON.parse(response.body)['message'] if response.status == 422

  Order.new(JSON.parse(response.body))
end

#order(id:) ⇒ Object

Raises:



141
142
143
144
145
146
# File 'lib/alpaca/trade/api/client.rb', line 141

def order(id:)
  response = get_request(endpoint, "v2/orders/#{id}")
  raise InvalidOrderId, JSON.parse(response.body)['message'] if response.status == 404

  Order.new(JSON.parse(response.body))
end

#orders(status: nil, after: nil, until_time: nil, direction: nil, limit: 50) ⇒ Object



148
149
150
151
152
153
# File 'lib/alpaca/trade/api/client.rb', line 148

def orders(status: nil, after: nil, until_time: nil, direction: nil, limit: 50)
  params = { status: status, after: after, until: until_time, direction: direction, limit: limit }
  response = get_request(endpoint, "v2/orders", params.compact)
  json = JSON.parse(response.body)
  json.map { |item| Order.new(item) }
end

#position(symbol: nil) ⇒ Object



155
156
157
158
159
160
# File 'lib/alpaca/trade/api/client.rb', line 155

def position(symbol: nil)
  response = get_request(endpoint, ["v2/positions", symbol].compact.join('/'))
  raise NoPositionForSymbol, JSON.parse(response.body)['message'] if response.status == 404

  Position.new(JSON.parse(response.body))
end

#positions(symbol: nil) ⇒ Object



162
163
164
165
166
# File 'lib/alpaca/trade/api/client.rb', line 162

def positions(symbol: nil)
  response = get_request(endpoint, ["v2/positions", symbol].compact.join('/'))
  json = JSON.parse(response.body)
  json.map { |item| Position.new(item) }
end

#replace_order(id:, qty: nil, time_in_force: nil, limit_price: nil, stop_price: nil, client_order_id: nil) ⇒ Object

Raises:



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/alpaca/trade/api/client.rb', line 168

def replace_order(id:, qty: nil, time_in_force: nil, limit_price: nil,
                  stop_price: nil, client_order_id: nil)

  params = {
    qty: qty,
    time_in_force: time_in_force,
    limit_price: limit_price,
    stop_price: stop_price,
    client_order_id: client_order_id
  }
  response = patch_request(endpoint, "v2/orders/#{id}", params.compact)
  raise InsufficientFunds, JSON.parse(response.body)['message'] if response.status == 403
  raise InvalidOrderId, JSON.parse(response.body)['message'] if response.status == 404
  raise InvalidRequest, JSON.parse(response.body)['message'] if response.status == 422

  Order.new(JSON.parse(response.body))
end