rbtc_arbitrage_simple 1.2.3 → 1.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 40fce7b383de7c133941d19f55ff55adaf3fa01d
4
- data.tar.gz: d625c40f8afee77529f458183cf32fba33fef0d8
3
+ metadata.gz: ef0a86fb8de589d7b45bc44e07ce93222bad2e17
4
+ data.tar.gz: b78c0c931af1ff282bba897320eb59c0b5279615
5
5
  SHA512:
6
- metadata.gz: 8c08ee2166aafcd8dbd14dfa1a02ae5e0c14881b1b778b906fa6662e13ccc04770d2e7aae4e66c9da16a01b6a42188719030d758ea1f59282cd2b6392910f7ee
7
- data.tar.gz: a8ef905fc4e189aa20ff6839440960f1e00c744119142d8e0b69af44af1eb226b98c80fc7bd6b7766ab7d79696d04b78a88049efbd732e245faf02f5d97096e9
6
+ metadata.gz: ff3874ce7ee3bdecf7b30e8338d2472fe33371f1a62ecb135e1dfcbcb04e1342828415907990aba602262450a59096e0fc4f34447ac65930269d116f7e73e826
7
+ data.tar.gz: 77c3cdb383df68cd78e3facc9122f7001e55fd0179b1aca441abd5a286e2b771c2a731ed66a5e6c7c7708c7c406cbba1608bd80640462f212bc7a3d21478f167
@@ -6,6 +6,11 @@ rvm:
6
6
  - ruby-head
7
7
  - jruby-19mode
8
8
  - jruby-head
9
+
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: 2.1.0
13
+ - rvm: ruby-head
9
14
  env:
10
15
  global:
11
16
  - secure: FdoR9cSL5JzSiGRgmrEGCx55VdP7QU6jt2vzeJyc+2Ho67UXxJuXWgFdwojs6X85O3in8YfSOInBLGXXsD8a3mBuvhsAaMmDLbhFKfEExsc9bnpTj3k95UMGRO3pGNkk1tfj/ohsLFs+yL4r/mFZ5pOoxWW0uhYuRPA+Jk39hZg=
@@ -21,3 +26,6 @@ env:
21
26
  - secure: IFyJX6lAmBpef0I50UPCy6L5IRxqRKoPhv74s5y0FPB4chrir7iMZ7Sd1IczxV7ly4Dt7hdALHP1qMTmkcGmTV6YOzwR46G4JAwWtX2xlf4OYk4jey7qjNsS6iijD6dvdYjqSKUuGaX3Til3kUOLcA3hhINvHxj5unv2pHB2W70=
22
27
  - secure: YiYtCBJNfgWuzQ059RMmZxM00bs4c/GuqaEaKufLPPByJHHt3z4jCNT5lurox/RIqSYTv+1Nvgor1xJZF4VPDIhtoCpVRe3g5Pvubrp4gWQry11ta0f1JhPSrm5ORlF1hpHPfzHHSh+/YVmKcO8agQAaIgfKcXDzsE6j5QqiGWQ=
23
28
  - secure: TCrSkWTG2A7ZHxU/J82R1oRn3+ISYHOZmukvBT/OkOh35yjhtig3KhroYki67guCClVxov+ZPvCRUKgmsEoVng1ljk/ZXyyNf4QNVccEJxHCwIRiqs36jlC2ebd8g+JJUPrnnWGO/U5vBm+WlrOb4lFlIsBuCYI+FBAFYTPmKEs=
29
+ - secure: cePvBAt6j7UwybsP6Cs5a7mwaXMHDteXC1ENsNMy69qV5mae7oRKqsfavZ8ar33apNXqALXDWiDnHH7wPccMl3GXIquHE7I73lAOcEu4V+f7nHqqFuJezA12IL0swOQhDNK23C5ibkFftlpG2jTxHpaRLaDNCuv404cREalwwgA=
30
+ - secure: PLTV2N3BYlqXmDDuOuZGk83YApX3oEIpskkWHUGj8f3wBpjOSPxuLBdpSGMXRqT2kIMJqle65gqlYpwh4NcTgqL93iNAT9fh7WDyNx/SUL+Mz04kphAC6N0VPyg7nvTi33bDbkmAAFNc+1yoWKAlB2gjKKXFtdxTwMp4SjvNsfs=
31
+ - secure: nyFUNdswDOM0UgW3T/jeEvIyZPSGq+ZEpyYw6KGpwb7a5F1DbAfoSy6zJGWK6S3vKf6814e43HmawhJlhcD9KYOV783O7KYu54FTmhZ/SP9QhNV+w1hiKKRQcTlJdjbPIuO5piuMDMCPacCJa+C9YO0lhhxfZ+/6F4SNR1fteN0=
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbtc_arbitrage_simple (1.2.3)
4
+ rbtc_arbitrage_simple (1.4.4)
5
5
  activemodel (>= 3.1)
6
6
  activesupport (>= 3.1)
7
7
  btce (= 0.2.4)
8
- coinbase (= 1.2.4)
8
+ coinbase (= 1.2.6)
9
9
  mtgox
10
+ pony
10
11
  thor
11
12
 
12
13
  GEM
@@ -31,10 +32,10 @@ GEM
31
32
  codeclimate-test-reporter (0.2.0)
32
33
  simplecov (>= 0.7.1, < 1.0.0)
33
34
  coderay (1.1.0)
34
- coinbase (1.2.4)
35
+ coinbase (1.2.6)
35
36
  hashie (>= 1.2.0)
36
37
  httparty (>= 0.8.3)
37
- money (>= 4.0.1)
38
+ money (= 5.1.1)
38
39
  multi_json (>= 1.3.4)
39
40
  coveralls (0.7.0)
40
41
  multi_json (~> 1.3)
@@ -70,11 +71,15 @@ GEM
70
71
  rb-fsevent (>= 0.9.3)
71
72
  rb-inotify (>= 0.9)
72
73
  lumberjack (1.0.4)
74
+ mail (2.2.7)
75
+ activesupport (>= 2.3.6)
76
+ mime-types
77
+ treetop (>= 1.4.5)
73
78
  method_source (0.8.2)
74
79
  mime-types (2.0)
75
80
  minitest (4.7.5)
76
- money (6.0.0)
77
- i18n (~> 0.6.4)
81
+ money (5.1.1)
82
+ i18n (~> 0.6.0)
78
83
  monkey-patch (0.0.14)
79
84
  activesupport
80
85
  mtgox (1.1.0)
@@ -83,6 +88,9 @@ GEM
83
88
  multi_json (1.8.2)
84
89
  multi_xml (0.5.5)
85
90
  multipart-post (1.2.0)
91
+ polyglot (0.3.3)
92
+ pony (1.6.2)
93
+ mail (>= 2.0)
86
94
  pry (0.9.12.4)
87
95
  coderay (~> 1.0)
88
96
  method_source (~> 0.8)
@@ -128,6 +136,9 @@ GEM
128
136
  tilt (1.4.1)
129
137
  timers (1.1.0)
130
138
  tins (0.13.1)
139
+ treetop (1.4.15)
140
+ polyglot
141
+ polyglot (>= 0.3.1)
131
142
  tzinfo (0.3.38)
132
143
  vcr (2.8.0)
133
144
  webmock (1.16.1)
data/README.md CHANGED
@@ -8,11 +8,11 @@ A Ruby gem for executing arbitrage between the MtGox and Bitstamp bitcoin exchan
8
8
 
9
9
  [Why I open sourced a bitcoin arbitrate bot](http://hankstoever.com/posts/2-Why-I-open-sourced-a-bitcoin-arbitrage-bot)
10
10
 
11
- I'm also creating a course on [creating your own bitcoin arbitrage bot](https://www.uludum.org/funds/2)
11
+ I'm also creating a course on [creating your own bitcoin arbitrage bot](https://www.uludum.org/funds/2)
12
12
 
13
13
  Donations accepted: **16BMcqf93eEpb2aWgMkJCSQQH85WzrpbdZ**
14
14
 
15
- [![Build Status](https://travis-ci.org/hstove/rbtc_arbitrage.png?branch=master)](https://travis-ci.org/hstove/rbtc_arbitrage)
15
+ [![Build Status](https://travis-ci.org/hstove/rbtc_arbitrage.png?branch=no-native)](https://travis-ci.org/hstove/rbtc_arbitrage)
16
16
  [![Coverage Status](https://coveralls.io/repos/hstove/rbtc_arbitrage/badge.png)](https://coveralls.io/r/hstove/rbtc_arbitrage)
17
17
  [![Code Climate](https://codeclimate.com/github/hstove/rbtc_arbitrage.png)](https://codeclimate.com/github/hstove/rbtc_arbitrage)
18
18
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
4
  require 'rbtc_arbitrage'
4
5
  RbtcArbitrage::CLI.start ARGV
@@ -3,6 +3,7 @@ require 'mtgox'
3
3
  require_relative 'rbtc_arbitrage/campbx.rb'
4
4
  require 'btce'
5
5
  require 'coinbase'
6
+ require 'pony'
6
7
  require_relative 'rbtc_arbitrage/client.rb'
7
8
  Dir["#{File.dirname(__FILE__)}/rbtc_arbitrage/**/*.rb"].each { |f| require(f) }
8
9
 
@@ -9,6 +9,7 @@ module RbtcArbitrage
9
9
  option :buyer, type: :string, default: "campbx"
10
10
  option :seller, type: :string, default: "mtgox"
11
11
  option :repeat, type: :numeric, default: nil
12
+ option :notify, type: :boolean, default: false
12
13
  def trade
13
14
  RbtcArbitrage::Trader.new(options).trade
14
15
  end
@@ -13,11 +13,14 @@ module RbtcArbitrage
13
13
  @options = {}
14
14
  set_key opts, :volume, 0.01
15
15
  set_key opts, :cutoff, 2
16
- set_key opts, :logger, Logger.new(STDOUT)
16
+ default_logger = Logger.new($stdout)
17
+ default_logger.datetime_format = "%^b %e %Y %l:%M:%S %p %z"
18
+ set_key opts, :logger, default_logger
17
19
  set_key opts, :verbose, true
18
20
  set_key opts, :live, false
19
21
  set_key opts, :repeat, nil
20
22
  exchange = opts[:buyer] || :campbx
23
+ set_key opts, :notify, false
21
24
  @buy_client = client_for_exchange(exchange)
22
25
  exchange = opts[:seller] || :mtgox
23
26
  @sell_client = client_for_exchange(exchange)
@@ -38,15 +41,18 @@ module RbtcArbitrage
38
41
 
39
42
  execute_trade if options[:live]
40
43
 
44
+ notify
45
+
41
46
  if @options[:repeat]
42
47
  trade_again
43
48
  end
49
+
44
50
  self
45
51
  end
46
52
 
47
53
  def trade_again
48
54
  sleep @options[:repeat]
49
- @logger.info " - " if @options[:verbose]
55
+ logger.info " - " if @options[:verbose]
50
56
  @buy_client = @buy_client.class.new(@options)
51
57
  @sell_client = @sell_client.class.new(@options)
52
58
  trade
@@ -104,6 +110,15 @@ module RbtcArbitrage
104
110
  [@sell_client, @buy_client].each do |client|
105
111
  client.validate_env
106
112
  end
113
+ if options[:notify]
114
+ ["PASSWORD","USERNAME","EMAIL"].each do |key|
115
+ key = "SENDGRID_#{key}"
116
+ unless ENV[key]
117
+ raise ArgumentError, "Exiting because missing required ENV variable $#{key}."
118
+ end
119
+ end
120
+ setup_pony
121
+ end
107
122
  end
108
123
 
109
124
  def client_for_exchange market
@@ -119,5 +134,60 @@ module RbtcArbitrage
119
134
  raise ArgumentError, "Invalid exchange - '#{market}'"
120
135
  end
121
136
  end
137
+
138
+ def notify
139
+ return false unless options[:notify]
140
+ return false unless @percent > options[:cutoff]
141
+ setup_pony
142
+
143
+ options[:logger].info "Sending email to #{ENV['SENDGRID_EMAIL']}"
144
+ Pony.mail({
145
+ body: notification,
146
+ to: ENV['SENDGRID_EMAIL'],
147
+ })
148
+ end
149
+
150
+ def setup_pony
151
+ Pony.options = {
152
+ from: ENV['FROM_EMAIL'] || "info@example.org",
153
+ subject: "rbtc_arbitrage notification",
154
+ via: :smtp,
155
+ via_options: {
156
+ address: 'smtp.sendgrid.net',
157
+ port: '587',
158
+ domain: 'heroku.com',
159
+ user_name: ENV['SENDGRID_USERNAME'],
160
+ password: ENV['SENDGRID_PASSWORD'],
161
+ authentication: :plain,
162
+ enable_starttls_auto: true
163
+ }
164
+ }
165
+ end
166
+
167
+ def notification
168
+ lower_ex = @buy_client.exchange.to_s.capitalize
169
+ higher_ex = @sell_client.exchange.to_s.capitalize
170
+ <<-eos
171
+ Update from your friendly rbtc_arbitrage trader:
172
+
173
+ -------------------
174
+
175
+ #{lower_ex}: $#{buyer[:price].round(2)}
176
+ #{higher_ex}: $#{seller[:price].round(2)}
177
+ buying #{@options[:volume]} btc from #{lower_ex} for $#{@paid.round(2)}
178
+ selling #{@options[:volume]} btc on #{higher_ex} for $#{@received.round(2)}
179
+ profit: $#{(@received - @paid).round(2)} (#{@percent.round(2)}%)
180
+
181
+ -------------------
182
+
183
+ options:
184
+
185
+ #{options.reject{|k,v| v.is_a?(Logger)}.collect{|k,v| "#{k}: #{v.to_s}"}.join(" | ")}
186
+
187
+ -------------------
188
+
189
+ https://github.com/hstove/rbtc_arbitrage
190
+ eos
191
+ end
122
192
  end
123
193
  end
@@ -1,3 +1,3 @@
1
1
  module RbtcArbitrage
2
- VERSION = "1.2.3"
2
+ VERSION = "1.4.4"
3
3
  end
@@ -26,5 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency "activesupport", ">= 3.1"
27
27
  spec.add_dependency "thor"
28
28
  spec.add_dependency "btce", '0.2.4'
29
- spec.add_dependency "coinbase", '1.2.4'
29
+ spec.add_dependency "coinbase", '1.2.6'
30
+ spec.add_dependency "pony"
30
31
  end
@@ -37,6 +37,20 @@ describe RbtcArbitrage::Trader do
37
37
  end
38
38
  end
39
39
  end
40
+
41
+ ["PASSWORD","USERNAME","EMAIL"].each do |key|
42
+ key = "SENDGRID_#{key}"
43
+ it "should raise if --notify and not ENV[#{key}]" do
44
+ trader.sell_client.stub(:validate_env)
45
+ trader.buy_client.stub(:validate_env)
46
+ old_val = ENV[key]
47
+ ENV[key] = nil
48
+ trader.options[:notify] = true
49
+ expect { trader.validate_env }.to raise_error(ArgumentError)
50
+ trader.options[:notify] = false
51
+ expect { trader.validate_env }.not_to raise_error
52
+ end
53
+ end
40
54
  end
41
55
 
42
56
  describe "#fetch_prices" do
@@ -71,6 +85,7 @@ describe RbtcArbitrage::Trader do
71
85
  live: true,
72
86
  seller: :btce,
73
87
  buyer: :mtgox,
88
+ notify: true,
74
89
  }
75
90
  }
76
91
 
@@ -142,6 +157,7 @@ describe RbtcArbitrage::Trader do
142
157
  describe "#trade" do
143
158
  it "calls the right methods" do
144
159
  trader.should_receive(:fetch_prices)
160
+ trader.should_receive(:notify)
145
161
  trader.should_not_receive(:log_info)
146
162
  trader.should_not_receive(:execute_trade)
147
163
 
@@ -183,15 +199,29 @@ describe RbtcArbitrage::Trader do
183
199
  end
184
200
 
185
201
  describe "#log_info" do
186
- it "calls logger.info" do
202
+ before :each do
187
203
  trader.buyer[:price] = 1
188
204
  trader.seller[:price] = 1
189
205
  trader.instance_variable_set :@percent, 1
190
206
  trader.instance_variable_set :@paid, 1
191
207
  trader.instance_variable_set :@received, 1
208
+ end
209
+ it "calls logger.info" do
192
210
  trader.logger.should_receive(:info).exactly(5).times
193
211
  trader.log_info
194
212
  end
213
+
214
+ it "formats the log correctly" do
215
+ FileUtils.mkdir_p('tmp')
216
+ date = DateTime.now.strftime "%^b %e %Y %l"
217
+ logger = Logger.new('tmp/log.info')
218
+ logger.datetime_format = trader.logger.datetime_format
219
+ trader.options[:logger] = logger
220
+ trader.log_info
221
+ contents = File.read("tmp/log.info")
222
+ contents.should include(date)
223
+ contents.should include(" INFO -- ")
224
+ end
195
225
  end
196
226
 
197
227
  describe "#logger" do
@@ -225,4 +255,82 @@ describe RbtcArbitrage::Trader do
225
255
  end
226
256
  end
227
257
 
258
+ describe "#notify" do
259
+ it "returns false when notify == false" do
260
+ trader.notify.should == false
261
+ end
262
+
263
+ it "returns false unless cutoff < percent" do
264
+ trader.options[:notify] = true
265
+ trader.instance_variable_set :@percent, 1
266
+ trader.notify.should == false
267
+ end
268
+
269
+ it "calls Sendgrid when notify == true" do
270
+ trader.options[:notify] = true
271
+ trader.instance_variable_set :@percent, 3
272
+ trader.instance_variable_set :@paid, 5
273
+ trader.instance_variable_set :@received, 6
274
+ trader.buyer[:price] = 1
275
+ trader.seller[:price] = 1
276
+
277
+ trader.options[:logger].should_receive(:info)
278
+ Pony.should_receive(:mail).with({
279
+ to: ENV['SENDGRID_EMAIL'],
280
+ body: trader.notification,
281
+ })
282
+
283
+ trader.notify
284
+ end
285
+ end
286
+
287
+ describe "#setup_pony" do
288
+ it "gets called on validation when --notify" do
289
+ ["PASSWORD","USERNAME","EMAIL"].each do |key|
290
+ key = "SENDGRID_#{key}"
291
+ ENV[key] ||= "something"
292
+ end
293
+ trader.options[:notify] = true
294
+ trader.should_receive(:setup_pony).once
295
+ trader.validate_env
296
+ end
297
+ it "sets up pony correctly" do
298
+ opts = {
299
+ from: "info@example.org",
300
+ subject: "rbtc_arbitrage notification",
301
+ :via => :smtp,
302
+ :via_options => {
303
+ :address => 'smtp.sendgrid.net',
304
+ :port => '587',
305
+ :domain => 'heroku.com',
306
+ :user_name => ENV['SENDGRID_USERNAME'],
307
+ :password => ENV['SENDGRID_PASSWORD'],
308
+ :authentication => :plain,
309
+ :enable_starttls_auto => true
310
+ }
311
+ }
312
+ Pony.should_receive(:options=).with(opts)
313
+ trader.setup_pony
314
+ end
315
+ end
316
+
317
+ describe "#notification" do
318
+ it "includes the right values" do
319
+ trader.instance_variable_set :@percent, 3
320
+ trader.instance_variable_set :@paid, 5
321
+ trader.instance_variable_set :@received, 8
322
+ trader.buyer[:price] = 1.00453
323
+ trader.seller[:price] = 3.50453
324
+
325
+ value = trader.notification
326
+ value.should include("$1.0")
327
+ value.should include("$3.5")
328
+ value.should include("$3.0")
329
+ value.should include("3.0%")
330
+ end
331
+ context "--live" do
332
+ it "should say that it made a trade"
333
+ end
334
+ end
335
+
228
336
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbtc_arbitrage_simple
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hank Stoever
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-23 00:00:00.000000000 Z
11
+ date: 2014-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,14 +114,28 @@ dependencies:
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 1.2.4
117
+ version: 1.2.6
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 1.2.4
124
+ version: 1.2.6
125
+ - !ruby/object:Gem::Dependency
126
+ name: pony
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: A gem for conducting arbitrage with Bitcoin.
126
140
  email:
127
141
  - hstove@gmail.com