bitbot-trader 0.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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +10 -0
  7. data/Gemfile.devtools +55 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +28 -0
  10. data/Rakefile +4 -0
  11. data/bitbot-trader.gemspec +22 -0
  12. data/config/devtools.yml +4 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/mutant.yml +3 -0
  16. data/config/reek.yml +103 -0
  17. data/config/yardstick.yml +2 -0
  18. data/examples/account_info.rb +16 -0
  19. data/examples/open_orders.rb +16 -0
  20. data/lib/bitbot/trader.rb +32 -0
  21. data/lib/bitbot/trader/account.rb +29 -0
  22. data/lib/bitbot/trader/amount.rb +15 -0
  23. data/lib/bitbot/trader/api_methods.rb +33 -0
  24. data/lib/bitbot/trader/open_order.rb +29 -0
  25. data/lib/bitbot/trader/price.rb +15 -0
  26. data/lib/bitbot/trader/provider.rb +19 -0
  27. data/lib/bitbot/trader/providers/bitstamp.rb +29 -0
  28. data/lib/bitbot/trader/providers/bitstamp/http_client.rb +101 -0
  29. data/lib/bitbot/trader/providers/bitstamp/open_orders_parser.rb +33 -0
  30. data/lib/bitbot/trader/providers/bitstamp/open_orders_request.rb +25 -0
  31. data/lib/bitbot/trader/providers/mt_gox.rb +29 -0
  32. data/lib/bitbot/trader/providers/mt_gox/account_info_parser.rb +45 -0
  33. data/lib/bitbot/trader/providers/mt_gox/account_info_request.rb +24 -0
  34. data/lib/bitbot/trader/providers/mt_gox/http_client.rb +98 -0
  35. data/lib/bitbot/trader/providers/mt_gox/http_client/hmac_middleware.rb +118 -0
  36. data/lib/bitbot/trader/providers/mt_gox/open_orders_parser.rb +35 -0
  37. data/lib/bitbot/trader/providers/mt_gox/open_orders_request.rb +25 -0
  38. data/lib/bitbot/trader/providers/mt_gox/value_with_currency_coercer.rb +28 -0
  39. data/lib/bitbot/trader/request.rb +41 -0
  40. data/lib/bitbot/trader/utils/nonce_generator.rb +21 -0
  41. data/lib/bitbot/trader/version.rb +5 -0
  42. data/lib/bitbot/trader/wallet.rb +25 -0
  43. data/spec/integration/bitstamp/open_orders_spec.rb +28 -0
  44. data/spec/integration/mt_gox/account_spec.rb +28 -0
  45. data/spec/integration/mt_gox/open_orders_spec.rb +29 -0
  46. data/spec/spec_helper.rb +18 -0
  47. data/spec/support/big_decimal_matcher.rb +5 -0
  48. data/spec/support/http_connection_helpers.rb +15 -0
  49. data/spec/support/http_request_mock.rb +7 -0
  50. data/spec/support/provider_mock.rb +5 -0
  51. data/spec/unit/bitbot/trader/account_spec.rb +28 -0
  52. data/spec/unit/bitbot/trader/api_methods_spec.rb +43 -0
  53. data/spec/unit/bitbot/trader/open_order_spec.rb +19 -0
  54. data/spec/unit/bitbot/trader/provider_spec.rb +18 -0
  55. data/spec/unit/bitbot/trader/providers/bitstamp/http_client_spec.rb +75 -0
  56. data/spec/unit/bitbot/trader/providers/bitstamp/open_order_parser_spec.rb +69 -0
  57. data/spec/unit/bitbot/trader/providers/bitstamp/open_orders_request_spec.rb +24 -0
  58. data/spec/unit/bitbot/trader/providers/bitstamp_spec.rb +45 -0
  59. data/spec/unit/bitbot/trader/providers/mt_gox/account_info_parser_spec.rb +58 -0
  60. data/spec/unit/bitbot/trader/providers/mt_gox/account_info_request_spec.rb +24 -0
  61. data/spec/unit/bitbot/trader/providers/mt_gox/http_client/hmac_middleware_spec.rb +55 -0
  62. data/spec/unit/bitbot/trader/providers/mt_gox/http_client_spec.rb +100 -0
  63. data/spec/unit/bitbot/trader/providers/mt_gox/open_order_parser_spec.rb +95 -0
  64. data/spec/unit/bitbot/trader/providers/mt_gox/open_orders_request_spec.rb +24 -0
  65. data/spec/unit/bitbot/trader/providers/mt_gox/value_with_currency_coercer_spec.rb +21 -0
  66. data/spec/unit/bitbot/trader/providers/mt_gox_spec.rb +26 -0
  67. data/spec/unit/bitbot/trader/request_spec.rb +39 -0
  68. data/spec/unit/bitbot/trader/utils/nonce_generator_spec.rb +19 -0
  69. metadata +166 -0
@@ -0,0 +1,100 @@
1
+ require "spec_helper"
2
+
3
+ describe Providers::MtGox::HttpClient do
4
+ describe ".build" do
5
+ subject { described_class.build(options) }
6
+
7
+ let(:options) { {key: "double", secret: "double"} }
8
+ let(:connection) { double }
9
+
10
+ before do
11
+ described_class.should_receive(:make_connection).with("double", "double").
12
+ and_return(connection)
13
+ end
14
+
15
+ it { should be_a(described_class) }
16
+ its(:connection) { should be(connection) }
17
+ end
18
+
19
+ describe ".make_connection" do
20
+ subject(:connection) { described_class.make_connection("key", "secret") }
21
+
22
+ it { should be_a(Faraday::Connection) }
23
+
24
+ it "has correct url_prefix" do
25
+ expect(subject.url_prefix.to_s + "/").to eq(described_class::HOST)
26
+ end
27
+
28
+ context "request handlers" do
29
+ subject { connection.builder.handlers }
30
+
31
+ it { should eq([
32
+ Faraday::Request::UrlEncoded,
33
+ Providers::MtGox::HttpClient::HmacMiddleware,
34
+ Faraday::Adapter::NetHttp])
35
+ }
36
+
37
+ it "has HmacMiddleware with correct params" do
38
+ connection.builder.handlers.delete(subject[0])
39
+ hmac_middleware = connection.builder.to_app(double)
40
+ expect(hmac_middleware.key).to eq("key")
41
+ expect(hmac_middleware.secret).to eq("secret")
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#initialize" do
47
+ let(:connection) { double("connection") }
48
+
49
+ context "with default nonce generator" do
50
+ subject { described_class.new(connection) }
51
+
52
+ it { should be_a(described_class) }
53
+ its(:nonce_generator) { should be(Utils::NonceGenerator) }
54
+ end
55
+
56
+ context "with custom nonce generator" do
57
+ subject { described_class.new(connection, nonce_generator) }
58
+
59
+ let(:nonce_generator) { double("nonce generator") }
60
+
61
+ it { should be_a(described_class) }
62
+ its(:nonce_generator) { should be(nonce_generator) }
63
+ end
64
+ end
65
+
66
+ describe "#post" do
67
+ let(:client) { described_class.new(connection, nonce_generator) }
68
+ let(:connection) { double("connection") }
69
+ let(:nonce_generator) { double(generate: 123) }
70
+ let(:path) { "some_action" }
71
+
72
+ context "with default options" do
73
+ subject { client.post(path) }
74
+
75
+ let(:options) { {param: "value"} }
76
+
77
+ before do
78
+ connection.should_receive(:post).
79
+ with("some_action", {nonce: 123}).
80
+ and_return(double(body: '{"result": "yey"}'))
81
+ end
82
+
83
+ it { should eq({"result" => "yey"}) }
84
+ end
85
+
86
+ context "with custom options" do
87
+ subject { client.post(path, options) }
88
+
89
+ let(:options) { {param: "value"} }
90
+
91
+ before do
92
+ connection.should_receive(:post).
93
+ with("some_action", {param: "value", nonce: 123}).
94
+ and_return(double(body: '{"result": "yey"}'))
95
+ end
96
+
97
+ it { should eq({"result" => "yey"}) }
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,95 @@
1
+ require "spec_helper"
2
+
3
+ describe Providers::MtGox::OpenOrderParser do
4
+ describe "#parse" do
5
+ subject(:order) { described_class.new(data).parse }
6
+
7
+ context "when bid" do
8
+ let(:data) {
9
+ {
10
+ "oid" => "7c6d2237-52fb-4af4-b6ec-75e42f50c331",
11
+ "currency" => "USD",
12
+ "item" => "BTC",
13
+ "type" => "bid",
14
+ "status" => "open",
15
+ "date" => 1365886868,
16
+ "priority" => "1365886868485232",
17
+ "amount" => {
18
+ "value_int" => "3500000000",
19
+ "currency" => "BTC"
20
+ },
21
+ "effective_amount" => {
22
+ "value_int" => "3500000000",
23
+ "currency" => "BTC"
24
+ },
25
+ "price" => {
26
+ "value_int" => "3010000",
27
+ "currency" => "USD"
28
+ }
29
+ }
30
+ }
31
+
32
+ it { should be_a(OpenOrder) }
33
+ it { should be_bid }
34
+ its(:id) { should eq("7c6d2237-52fb-4af4-b6ec-75e42f50c331") }
35
+
36
+ context "amount" do
37
+ subject { order.amount }
38
+ it { should be_a(Amount) }
39
+ its(:value) { should eq(35) }
40
+ its(:currency) { should eq("BTC") }
41
+ end
42
+
43
+ context "price" do
44
+ subject { order.price }
45
+ it { should be_a(Price) }
46
+ its(:value) { should eq(30.1) }
47
+ its(:currency) { should eq("USD") }
48
+ end
49
+ end
50
+
51
+ context "when ask" do
52
+ let(:data) {
53
+ {
54
+ "oid" => "69dbeefc-1911-4b0e-b60e-b3948b50a880",
55
+ "currency" => "USD",
56
+ "item" => "BTC",
57
+ "type" => "ask",
58
+ "status" => "invalid",
59
+ "date" => 1366640210,
60
+ "priority" => "1366640210930103",
61
+ "amount" => {
62
+ "value_int" => "1220000000",
63
+ "currency" => "BTC"
64
+ },
65
+ "effective_amount" => {
66
+ "value_int" => "1220000000",
67
+ "currency" => "BTC"
68
+ },
69
+ "price" => {
70
+ "value_int" => "12061185",
71
+ "currency" => "USD"
72
+ }
73
+ }
74
+ }
75
+
76
+ it { should be_a(OpenOrder) }
77
+ it { should be_ask }
78
+ its(:id) { should eq("69dbeefc-1911-4b0e-b60e-b3948b50a880") }
79
+
80
+ context "amount" do
81
+ subject { order.amount }
82
+ it { should be_a(Amount) }
83
+ its(:value) { should eq(12.2) }
84
+ its(:currency) { should eq("BTC") }
85
+ end
86
+
87
+ context "price" do
88
+ subject { order.price }
89
+ it { should be_a(Price) }
90
+ its(:value) { should eq(120.61185) }
91
+ its(:currency) { should eq("USD") }
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe Providers::MtGox::OpenOrdersRequest do
4
+ describe "#call" do
5
+ subject { request.call }
6
+
7
+ let(:request) { described_class.new(client) }
8
+ let(:client) { HttpRequestMock.new }
9
+
10
+ let(:raw_open_orders) { {"data" => [raw_open_order]} }
11
+ let(:raw_open_order) { double("raw open order") }
12
+
13
+ before do
14
+ client.stub(:post).with("money/orders").and_return(raw_open_orders)
15
+ end
16
+
17
+ it "parses open orders" do
18
+ Providers::MtGox::OpenOrderParser.should_receive(:new).
19
+ with(raw_open_order).
20
+ and_return(double(parse: "result"))
21
+ expect(subject).to eq(["result"])
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe Providers::MtGox::ValueWithCurrencyCoercer do
4
+ describe ".call" do
5
+ subject { described_class.call(data) }
6
+
7
+ context "when non-BTC currency" do
8
+ let(:data) { {"value_int" => 123456789, "currency" => "EUR"} }
9
+
10
+ its([:value]) { should be_big_decimal(1234.56789) }
11
+ its([:currency]) { should eq("EUR") }
12
+ end
13
+
14
+ context "when BTC currency" do
15
+ let(:data) { {"value_int" => 123456789, "currency" => "BTC"} }
16
+
17
+ its([:value]) { should be_big_decimal(1.23456789) }
18
+ its([:currency]) { should eq("BTC") }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe Providers::MtGox do
4
+ describe "#initialize" do
5
+ let(:options) { double("options") }
6
+
7
+ context "when with custom http client" do
8
+ subject { described_class.new(options, http_client) }
9
+
10
+ let(:http_client) { double("HttpClient") }
11
+
12
+ it { should be_a(described_class) }
13
+ its(:client) { should be(http_client) }
14
+ end
15
+
16
+ context "when with default http client class" do
17
+ subject { described_class.new(options) }
18
+
19
+ before do
20
+ described_class::HttpClient.should_receive(:build).with(options)
21
+ end
22
+
23
+ it { should be_a(described_class) }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require "spec_helper"
2
+
3
+ describe Bitbot::Trader::Request do
4
+ describe "#initialize" do
5
+ subject { described_class.new(client) }
6
+
7
+ let(:client) { double("client") }
8
+
9
+ it { should be_a(described_class) }
10
+ end
11
+
12
+ describe "#call" do
13
+ let(:client) { double("client") }
14
+
15
+ context "without arguments" do
16
+ it "should raise NotImplementedError" do
17
+ expect {
18
+ described_class.new(client).call
19
+ }.to raise_error(NotImplementedError)
20
+ end
21
+ end
22
+
23
+ context "with arguments" do
24
+ it "should raise NotImplementedError" do
25
+ expect {
26
+ described_class.new(client).call("argument")
27
+ }.to raise_error(NotImplementedError)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#client" do
33
+ subject { described_class.new(client).client }
34
+
35
+ let(:client) { double("client") }
36
+
37
+ it { should eql(client) }
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+ require "spec_helper"
2
+
3
+ describe Utils::NonceGenerator do
4
+ describe ".generate" do
5
+ context "with default time_class" do
6
+ subject { described_class.generate }
7
+
8
+ it { should be_a(Fixnum) }
9
+ end
10
+
11
+ context "with custom time_class" do
12
+ subject { described_class.generate(time_class) }
13
+
14
+ let(:time_class) { double(now: Time.utc(2013, 2, 3, 22, 12, 23)) }
15
+
16
+ it { should eql(1359929543) }
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitbot-trader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Indrek Juhkam
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: virtus
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.8'
41
+ description: ''
42
+ email:
43
+ - indrek@urgas.eu
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .ruby-gemset
50
+ - .ruby-version
51
+ - .travis.yml
52
+ - Gemfile
53
+ - Gemfile.devtools
54
+ - LICENSE.txt
55
+ - README.md
56
+ - Rakefile
57
+ - bitbot-trader.gemspec
58
+ - config/devtools.yml
59
+ - config/flay.yml
60
+ - config/flog.yml
61
+ - config/mutant.yml
62
+ - config/reek.yml
63
+ - config/yardstick.yml
64
+ - examples/account_info.rb
65
+ - examples/open_orders.rb
66
+ - lib/bitbot/trader.rb
67
+ - lib/bitbot/trader/account.rb
68
+ - lib/bitbot/trader/amount.rb
69
+ - lib/bitbot/trader/api_methods.rb
70
+ - lib/bitbot/trader/open_order.rb
71
+ - lib/bitbot/trader/price.rb
72
+ - lib/bitbot/trader/provider.rb
73
+ - lib/bitbot/trader/providers/bitstamp.rb
74
+ - lib/bitbot/trader/providers/bitstamp/http_client.rb
75
+ - lib/bitbot/trader/providers/bitstamp/open_orders_parser.rb
76
+ - lib/bitbot/trader/providers/bitstamp/open_orders_request.rb
77
+ - lib/bitbot/trader/providers/mt_gox.rb
78
+ - lib/bitbot/trader/providers/mt_gox/account_info_parser.rb
79
+ - lib/bitbot/trader/providers/mt_gox/account_info_request.rb
80
+ - lib/bitbot/trader/providers/mt_gox/http_client.rb
81
+ - lib/bitbot/trader/providers/mt_gox/http_client/hmac_middleware.rb
82
+ - lib/bitbot/trader/providers/mt_gox/open_orders_parser.rb
83
+ - lib/bitbot/trader/providers/mt_gox/open_orders_request.rb
84
+ - lib/bitbot/trader/providers/mt_gox/value_with_currency_coercer.rb
85
+ - lib/bitbot/trader/request.rb
86
+ - lib/bitbot/trader/utils/nonce_generator.rb
87
+ - lib/bitbot/trader/version.rb
88
+ - lib/bitbot/trader/wallet.rb
89
+ - spec/integration/bitstamp/open_orders_spec.rb
90
+ - spec/integration/mt_gox/account_spec.rb
91
+ - spec/integration/mt_gox/open_orders_spec.rb
92
+ - spec/spec_helper.rb
93
+ - spec/support/big_decimal_matcher.rb
94
+ - spec/support/http_connection_helpers.rb
95
+ - spec/support/http_request_mock.rb
96
+ - spec/support/provider_mock.rb
97
+ - spec/unit/bitbot/trader/account_spec.rb
98
+ - spec/unit/bitbot/trader/api_methods_spec.rb
99
+ - spec/unit/bitbot/trader/open_order_spec.rb
100
+ - spec/unit/bitbot/trader/provider_spec.rb
101
+ - spec/unit/bitbot/trader/providers/bitstamp/http_client_spec.rb
102
+ - spec/unit/bitbot/trader/providers/bitstamp/open_order_parser_spec.rb
103
+ - spec/unit/bitbot/trader/providers/bitstamp/open_orders_request_spec.rb
104
+ - spec/unit/bitbot/trader/providers/bitstamp_spec.rb
105
+ - spec/unit/bitbot/trader/providers/mt_gox/account_info_parser_spec.rb
106
+ - spec/unit/bitbot/trader/providers/mt_gox/account_info_request_spec.rb
107
+ - spec/unit/bitbot/trader/providers/mt_gox/http_client/hmac_middleware_spec.rb
108
+ - spec/unit/bitbot/trader/providers/mt_gox/http_client_spec.rb
109
+ - spec/unit/bitbot/trader/providers/mt_gox/open_order_parser_spec.rb
110
+ - spec/unit/bitbot/trader/providers/mt_gox/open_orders_request_spec.rb
111
+ - spec/unit/bitbot/trader/providers/mt_gox/value_with_currency_coercer_spec.rb
112
+ - spec/unit/bitbot/trader/providers/mt_gox_spec.rb
113
+ - spec/unit/bitbot/trader/request_spec.rb
114
+ - spec/unit/bitbot/trader/utils/nonce_generator_spec.rb
115
+ homepage: ''
116
+ licenses:
117
+ - MIT
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.0.3
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: ''
139
+ test_files:
140
+ - spec/integration/bitstamp/open_orders_spec.rb
141
+ - spec/integration/mt_gox/account_spec.rb
142
+ - spec/integration/mt_gox/open_orders_spec.rb
143
+ - spec/spec_helper.rb
144
+ - spec/support/big_decimal_matcher.rb
145
+ - spec/support/http_connection_helpers.rb
146
+ - spec/support/http_request_mock.rb
147
+ - spec/support/provider_mock.rb
148
+ - spec/unit/bitbot/trader/account_spec.rb
149
+ - spec/unit/bitbot/trader/api_methods_spec.rb
150
+ - spec/unit/bitbot/trader/open_order_spec.rb
151
+ - spec/unit/bitbot/trader/provider_spec.rb
152
+ - spec/unit/bitbot/trader/providers/bitstamp/http_client_spec.rb
153
+ - spec/unit/bitbot/trader/providers/bitstamp/open_order_parser_spec.rb
154
+ - spec/unit/bitbot/trader/providers/bitstamp/open_orders_request_spec.rb
155
+ - spec/unit/bitbot/trader/providers/bitstamp_spec.rb
156
+ - spec/unit/bitbot/trader/providers/mt_gox/account_info_parser_spec.rb
157
+ - spec/unit/bitbot/trader/providers/mt_gox/account_info_request_spec.rb
158
+ - spec/unit/bitbot/trader/providers/mt_gox/http_client/hmac_middleware_spec.rb
159
+ - spec/unit/bitbot/trader/providers/mt_gox/http_client_spec.rb
160
+ - spec/unit/bitbot/trader/providers/mt_gox/open_order_parser_spec.rb
161
+ - spec/unit/bitbot/trader/providers/mt_gox/open_orders_request_spec.rb
162
+ - spec/unit/bitbot/trader/providers/mt_gox/value_with_currency_coercer_spec.rb
163
+ - spec/unit/bitbot/trader/providers/mt_gox_spec.rb
164
+ - spec/unit/bitbot/trader/request_spec.rb
165
+ - spec/unit/bitbot/trader/utils/nonce_generator_spec.rb
166
+ has_rdoc: