rapflag 0.0.2 → 0.0.3
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/.gitignore +4 -1
- data/Gemfile +2 -0
- data/History.md +5 -0
- data/bin/rapflag +17 -5
- data/fixtures/vcr_cassettes/rapflag.yml +44 -0
- data/lib/rapflag/bitfinex.rb +93 -0
- data/lib/rapflag/config.rb +0 -6
- data/lib/rapflag/history.rb +125 -0
- data/lib/rapflag/poloniex.rb +325 -0
- data/lib/rapflag/version.rb +1 -1
- data/rapflag.gemspec +1 -0
- data/spec/bitfinex_spec.rb +128 -0
- data/spec/poloniex_spec.rb +115 -0
- data/spec/spec_helper.rb +6 -0
- metadata +24 -5
- data/lib/rapflag/fetch.rb +0 -176
- data/spec/rapflag_spec.rb +0 -115
@@ -0,0 +1,325 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'faraday'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'rapflag/history'
|
6
|
+
require 'poloniex'
|
7
|
+
require 'json'
|
8
|
+
require 'pp'
|
9
|
+
|
10
|
+
module RAPFLAG
|
11
|
+
|
12
|
+
class Poloniex < History
|
13
|
+
attr_reader :complete_balances, :active_loans, :lending_history, :deposits, :withdrawals, :deposit_addresses,
|
14
|
+
:trade_history, :available_account_balances, :open_orders, :tradable_balances
|
15
|
+
|
16
|
+
@@btc_to_usd = {}
|
17
|
+
@@bfx_to_usd = {}
|
18
|
+
|
19
|
+
def get_usd_exchange(date_time = Time.now, from='BTC')
|
20
|
+
return 1.0 if from == 'USD'
|
21
|
+
daily = ::Poloniex.get_all_daily_exchange_rates('BTC_GNT')
|
22
|
+
|
23
|
+
key = date_time.strftime(DATE_FORMAT)
|
24
|
+
return @@btc_to_usd[key] if from.eql?('BTC') && @@btc_to_usd.size > 0
|
25
|
+
return @@bfx_to_usd[key] if from.eql?('BFX') && @@bfx_to_usd.size > 0
|
26
|
+
ms = (date_time.is_a?(Date) ? date_time.to_time : date_time).to_i*1000
|
27
|
+
ms_next_date = ms + (3*24*3600)*1000
|
28
|
+
# this does not work
|
29
|
+
# url = "https://api.bitfinex.com/v2/candles/trade:1D:t#{from}USD/hist?start:#{ms}?end:#{ms_next_date}"
|
30
|
+
url = "https://api.bitfinex.com/v2/candles/trade:1D:t#{from}USD/hist?start:#{ms}?end:#{ms_next_date}"
|
31
|
+
# therefore we just return the most uptodate
|
32
|
+
url = "https://api.bitfinex.com/v2/candles/trade:1D:t#{from}USD/hist?start:#{ms}"
|
33
|
+
puts "Fetching #{date_time}: #{url} #{@@btc_to_usd.size} BTC #{@@bfx_to_usd.size} BFX" if $VERBOSE
|
34
|
+
response = Faraday.get(url)
|
35
|
+
items = eval(response.body)
|
36
|
+
rates = {}
|
37
|
+
items.each do |item|
|
38
|
+
if item.first.eql?(:error)
|
39
|
+
puts "Fetching returned #{item}. Aborting"
|
40
|
+
exit(1)
|
41
|
+
end
|
42
|
+
timestamp = Time.at(item.first/1000).strftime(DATE_FORMAT)
|
43
|
+
rates[timestamp] = item[2]
|
44
|
+
end;
|
45
|
+
from.eql?('BTC') ? @@btc_to_usd = rates.clone : @@bfx_to_usd = rates.clone
|
46
|
+
rates[key] ? rates[key] : nil
|
47
|
+
rescue => err
|
48
|
+
puts "Err #{err}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def dump_history
|
52
|
+
load_history_info
|
53
|
+
FileUtils.makedirs('output') unless File.directory?('output')
|
54
|
+
CSV.open('output/trade_history.csv','w+',
|
55
|
+
:col_sep => ';',
|
56
|
+
:write_headers=> true,
|
57
|
+
:headers => [ 'currency_pair'] + @trade_history.values.first.first.to_h.keys
|
58
|
+
) do |csv|
|
59
|
+
@trade_history.each do |currency_pair, trades|
|
60
|
+
trades.each do |trace|
|
61
|
+
csv << [ currency_pair] + trace.to_h.values
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
CSV.open('output/lending_history.csv','w+',
|
66
|
+
:col_sep => ';',
|
67
|
+
:write_headers=> true,
|
68
|
+
:headers => @lending_history.first.to_h.keys
|
69
|
+
) do |csv|
|
70
|
+
@lending_history.each do |info|
|
71
|
+
csv << info.to_h.values
|
72
|
+
end
|
73
|
+
end
|
74
|
+
CSV.open('output/tradable_balances.csv','w+',
|
75
|
+
:col_sep => ';',
|
76
|
+
:write_headers=> true,
|
77
|
+
:headers => [ 'from_currency', 'to_from_currency', ]
|
78
|
+
) do |csv|
|
79
|
+
@tradable_balances.each do |currency_pair, balance|
|
80
|
+
balance.each do |info|
|
81
|
+
csv << [ currency_pair] + info
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
CSV.open('output/complete_balances.csv', 'w+',
|
86
|
+
:col_sep => ';',
|
87
|
+
:write_headers=> true,
|
88
|
+
:headers => [ 'currency', 'available', 'onOrders', 'btcValue' ]
|
89
|
+
) do |csv|
|
90
|
+
@complete_balances.each do |balance|
|
91
|
+
csv << [balance[0]] + balance[1].values
|
92
|
+
end
|
93
|
+
end
|
94
|
+
CSV.open('output/active_loans.csv', 'w+',
|
95
|
+
:col_sep => ';',
|
96
|
+
:write_headers=> true,
|
97
|
+
:headers => [ 'key', 'id', 'currency', 'rate', 'amount', 'duration', 'autoRenew', 'date', 'fees', ]
|
98
|
+
) do |csv|
|
99
|
+
@active_loans.each do |key, loans|
|
100
|
+
loans.each do | loan |
|
101
|
+
csv << [key] + loan.values
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
CSV.open('output/available_account_balances.csv', 'w+',
|
107
|
+
:col_sep => ';',
|
108
|
+
:write_headers=> true,
|
109
|
+
:headers => [ 'key', 'currency', 'balance']
|
110
|
+
) do |csv|
|
111
|
+
@available_account_balances.each do |key, balances|
|
112
|
+
balances.each do |currency, balance|
|
113
|
+
csv << [key, currency, balance]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
CSV.open('output/deposit_addresses.csv', 'w+',
|
118
|
+
:col_sep => ';',
|
119
|
+
:write_headers=> true,
|
120
|
+
:headers => [ 'currency', 'id']
|
121
|
+
) do |csv|
|
122
|
+
@deposit_addresses.each do |currency, id|
|
123
|
+
csv << [currency, id]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
CSV.open('output/withdrawals.csv','w+',
|
127
|
+
:col_sep => ';',
|
128
|
+
:write_headers=> true,
|
129
|
+
:headers => @deposits.first.to_h.keys
|
130
|
+
) do |csv|
|
131
|
+
@deposits.each do |info|
|
132
|
+
csv << info.to_h.values
|
133
|
+
end
|
134
|
+
end
|
135
|
+
CSV.open('output/deposits.csv','w+',
|
136
|
+
:col_sep => ';',
|
137
|
+
:write_headers=> true,
|
138
|
+
:headers => @withdrawals.first.to_h.keys
|
139
|
+
) do |csv|
|
140
|
+
@withdrawals.each do |info|
|
141
|
+
csv << info.to_h.values
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def find_per_currency_and_day(items, currency, date)
|
147
|
+
puts "Searching for #{currency} in day #{date}" if $VERBOSE
|
148
|
+
start_time = date.to_time.to_i
|
149
|
+
end_time = (date + 1).to_time.to_i
|
150
|
+
found = items.find_all{|item| item.currency.eql?(currency) && item.timestamp >= start_time && item.timestamp < end_time}
|
151
|
+
puts "find_per_currency_and_day: found #{found.size} #{found.first} #{found.last}" if $VERBOSE
|
152
|
+
found
|
153
|
+
end
|
154
|
+
|
155
|
+
def find_lending_info_day(currency, date)
|
156
|
+
puts "Searching lending (close) for #{currency} in day #{date}" if $VERBOSE
|
157
|
+
found = @lending_history.find_all { |item| item.currency.eql?(currency) && date.eql?(Date.parse(item.close)) }
|
158
|
+
puts "find_lending_info_day: found #{found.size} #{found.first} #{found.last}" if $VERBOSE
|
159
|
+
found
|
160
|
+
end
|
161
|
+
|
162
|
+
# type is either buy or sell
|
163
|
+
def find_day_trade(currency, date, type)
|
164
|
+
found = []
|
165
|
+
@trade_history.each do |currency_pair, trades|
|
166
|
+
next unless /^#{currency}/.match(currency_pair)
|
167
|
+
trades.each do |trade|
|
168
|
+
if trade.type.eql?(type) && date.eql?(Date.parse(trade.date))
|
169
|
+
trade.cucurrency_pair = currency_pair
|
170
|
+
found << trade
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
puts "find_day_trade: #{date} #{currency} found #{found.size}" if $VERBOSE
|
175
|
+
found
|
176
|
+
end
|
177
|
+
def create_csv_file
|
178
|
+
binding.pry
|
179
|
+
puts "create_csv_file: already done"
|
180
|
+
end
|
181
|
+
|
182
|
+
def fetch_csv_history
|
183
|
+
load_history_info
|
184
|
+
@trade_history.values.collect{|values| values.collect{|x| x.date} }.max
|
185
|
+
|
186
|
+
max_time = [ @deposits.collect{|x| x.timestamp}.max,
|
187
|
+
Time.parse(@trade_history.values.collect{|values| values.collect{|x| x.date} }.max.max).to_i,
|
188
|
+
Time.parse(@lending_history.collect{|x| x.close}.max).to_i,
|
189
|
+
@withdrawals.collect{|x| x.timestamp}.max,].max
|
190
|
+
min_time = [ @deposits.collect{|x| x.timestamp}.min,
|
191
|
+
Time.parse(@trade_history.values.collect{|values| values.collect{|x| x.date} }.min.min).to_i,
|
192
|
+
Time.parse(@lending_history.collect{|x| x.close}.min).to_i,
|
193
|
+
@withdrawals.collect{|x| x.timestamp}.min,].min
|
194
|
+
|
195
|
+
min_date = Time.at(min_time).to_date
|
196
|
+
max_date = Time.at(max_time).to_date
|
197
|
+
|
198
|
+
puts "We start using the available_account_balances"
|
199
|
+
pp @available_account_balances
|
200
|
+
puts
|
201
|
+
puts "Should we better start using the complete_balances"
|
202
|
+
pp @complete_balances
|
203
|
+
puts "How should I handle the following currency_pair"
|
204
|
+
pp @trade_history.keys
|
205
|
+
@available_account_balances.each do |key, balances|
|
206
|
+
balances.each do |currency, balance|
|
207
|
+
puts "Calculation history for #{key} #{currency} with current balance of #{balance}"
|
208
|
+
out_name = "output/poloniex/#{key}_#{currency}.csv"
|
209
|
+
FileUtils.makedirs(File.dirname(out_name)) unless File.exists?(File.dirname(out_name))
|
210
|
+
@history = []
|
211
|
+
current_day = max_date
|
212
|
+
current_balance = balance.to_f
|
213
|
+
while (current_day >= min_date)
|
214
|
+
entry = OpenStruct.new
|
215
|
+
entry.current_day = current_day
|
216
|
+
entry.current_balance = current_balance
|
217
|
+
|
218
|
+
deposits = find_per_currency_and_day(@deposits, currency,current_day)
|
219
|
+
sum_deposits = 0.0; deposits.each{ |x| sum_deposits += x.amount.to_f }
|
220
|
+
entry.deposits = sum_deposits
|
221
|
+
|
222
|
+
withdrawals = find_per_currency_and_day(@withdrawals, currency, current_day)
|
223
|
+
sum_withdrawals = 0.0; withdrawals.each{ |x| sum_withdrawals += x.amount.to_f }
|
224
|
+
entry.withdrawals = sum_withdrawals
|
225
|
+
|
226
|
+
lendings = find_lending_info_day(currency, current_day)
|
227
|
+
earned = 0.0; sum_fee = 0.0; lendings.each{ |x| earned += x.earned.to_f; sum_fee += x.fee.to_f }
|
228
|
+
entry.earned = earned
|
229
|
+
entry.fees = sum_fee
|
230
|
+
|
231
|
+
# End_of_Day_Balance = End_of_Day_Balance(-1) + Deposits - Withdrawals + Lending_Income - Trading_Fees + Purchases - Sales
|
232
|
+
sales = find_day_trade(currency, current_day, 'sell')
|
233
|
+
sum_sales = 0.0; sales.each{ |sale| sum_sales += sale.amount.to_f }
|
234
|
+
entry.sales = sum_sales
|
235
|
+
|
236
|
+
purchases = find_day_trade(currency, current_day, 'buy')
|
237
|
+
sum_purchase = 0.0; purchases.each{ |purchase| sum_purchase += purchase.amount.to_f }
|
238
|
+
entry.purchases = sum_purchase
|
239
|
+
entry.day_difference = sum_deposits - sum_withdrawals + sum_purchase - sum_sales + sum_fee
|
240
|
+
@history << entry
|
241
|
+
current_day -= 1
|
242
|
+
# balance for previous day
|
243
|
+
current_balance = entry.current_balance - entry.day_difference
|
244
|
+
end
|
245
|
+
next unless @history.size > 0
|
246
|
+
CSV.open(out_name,'w+',
|
247
|
+
:col_sep => ';',
|
248
|
+
:write_headers=> true,
|
249
|
+
:headers => @history.first.to_h.keys
|
250
|
+
) do |csv|
|
251
|
+
@history.each do |info|
|
252
|
+
csv << info.to_h.values
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
private
|
259
|
+
def check_config
|
260
|
+
@spec_data = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec', 'data'))
|
261
|
+
['poloniex_api_key',
|
262
|
+
'poloniex_secret',
|
263
|
+
].each do |item|
|
264
|
+
raise "Must define #{item} in config.yml" unless Config[item]
|
265
|
+
end
|
266
|
+
::Poloniex.setup do | config |
|
267
|
+
config.key = Config['poloniex_api_key']
|
268
|
+
config.secret = Config['poloniex_secret']
|
269
|
+
end
|
270
|
+
nil
|
271
|
+
end
|
272
|
+
private
|
273
|
+
def load_or_save_json(name, param = nil)
|
274
|
+
json_file = File.join(@spec_data, name.to_s + '.json')
|
275
|
+
if File.exist?(json_file) && defined?(RSpec)
|
276
|
+
body = IO.read(json_file)
|
277
|
+
else
|
278
|
+
cmd = param ? "::Poloniex.#{name.to_s}('#{param}').body" : "::Poloniex.#{name.to_s}.body"
|
279
|
+
body = eval(cmd)
|
280
|
+
File.open(json_file, 'w+') { |f| f.write(body)}
|
281
|
+
end
|
282
|
+
eval("@#{name} = JSON.parse(body)")
|
283
|
+
end
|
284
|
+
def load_history_info
|
285
|
+
check_config
|
286
|
+
begin
|
287
|
+
@balances = load_or_save_json(:balances)
|
288
|
+
rescue => error
|
289
|
+
puts "Error was #{error.inspect}"
|
290
|
+
puts "Calling @balances from poloniex failed. Configuration was"
|
291
|
+
pp ::Poloniex.configuration
|
292
|
+
exit 1
|
293
|
+
end
|
294
|
+
@active_loans = load_or_save_json(:active_loans)
|
295
|
+
@available_account_balances = load_or_save_json(:available_account_balances)
|
296
|
+
all = load_or_save_json(:complete_balances)
|
297
|
+
@complete_balances = all.find_all{ | currency, values| values["available"].to_f != 0.0 }
|
298
|
+
@deposit_addresses = load_or_save_json(:deposit_addresses)
|
299
|
+
|
300
|
+
@deposits_withdrawals = load_or_save_json(:deposits_withdrawls)
|
301
|
+
# deposits and withdrawals have a different structure
|
302
|
+
@deposits = []
|
303
|
+
@deposits_withdrawals['deposits'].each {|x| @deposits << OpenStruct.new(x) };
|
304
|
+
@withdrawals =[]
|
305
|
+
@deposits_withdrawals['withdrawals'].each {|x| @withdrawals << OpenStruct.new(x) };
|
306
|
+
info = load_or_save_json(:lending_history)
|
307
|
+
@lending_history = []
|
308
|
+
info.each {|x| @lending_history << OpenStruct.new(x) };
|
309
|
+
|
310
|
+
@open_orders = load_or_save_json(:open_orders, 'all')
|
311
|
+
info = load_or_save_json(:trade_history, 'all')
|
312
|
+
@trade_history = {}
|
313
|
+
info.each do |currency_pair, trades|
|
314
|
+
@trade_history[currency_pair] = []
|
315
|
+
trades.each {|x| @trade_history[currency_pair] << OpenStruct.new(x) };
|
316
|
+
@trade_history[currency_pair].sort!{|x,y| x[:date] <=> y[:date]}.collect{ |x| x[:date]}
|
317
|
+
end
|
318
|
+
# @trade_history.values.first.first.tradeID
|
319
|
+
@tradable_balances = load_or_save_json(:tradable_balances)
|
320
|
+
@active_loans # key
|
321
|
+
@provided_loans = []; @active_loans['provided'].each {|x| @provided_loans << OpenStruct.new(x) };
|
322
|
+
@used_loans = []; @active_loans['used'].each {|x| @used_loans << OpenStruct.new(x) };
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
data/lib/rapflag/version.rb
CHANGED
data/rapflag.gemspec
CHANGED
@@ -0,0 +1,128 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'rapflag/bitfinex'
|
4
|
+
require 'vcr'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
VCR.configure do |config|
|
8
|
+
config.cassette_library_dir = "fixtures/vcr_cassettes"
|
9
|
+
config.hook_into :faraday # or :fakeweb
|
10
|
+
end
|
11
|
+
|
12
|
+
VCR.eject_cassette # we use insert/eject around each example
|
13
|
+
describe RAPFLAG::Bitfinex do
|
14
|
+
OUTPUT_ROOT = File.expand_path(File.join(__FILE__, '..', '..', 'output', 'bitfinex'))
|
15
|
+
Bitfinex_CSV_Test_File = OUTPUT_ROOT + '/BTC_exchange.csv'
|
16
|
+
BITFINEX_SUMMARY_EXCHANGE_BTC_File = OUTPUT_ROOT + '/BTC_exchange_summary.csv'
|
17
|
+
BITFINEX_SUMMARY_DEPOSIT_BFX_File = OUTPUT_ROOT + '/BFX_deposit_summary.csv'
|
18
|
+
|
19
|
+
# include ServerMockHelper
|
20
|
+
before(:all) do
|
21
|
+
end
|
22
|
+
after(:all) do
|
23
|
+
end
|
24
|
+
context 'bitfinex' do
|
25
|
+
before(:all) do
|
26
|
+
VCR.use_cassette("rapflag", :record => :new_episodes) do
|
27
|
+
FileUtils.rm_f(Bitfinex_CSV_Test_File) if File.exist?(Bitfinex_CSV_Test_File)
|
28
|
+
FileUtils.rm_f(BITFINEX_SUMMARY_DEPOSIT_BFX_File) if File.exist?(BITFINEX_SUMMARY_DEPOSIT_BFX_File)
|
29
|
+
FileUtils.rm_f(BITFINEX_SUMMARY_EXCHANGE_BTC_File) if File.exist?(Bitfinex_CSV_Test_File)
|
30
|
+
expect(File.exist?(Bitfinex_CSV_Test_File)).to eql(false)
|
31
|
+
@rap = RAPFLAG::Bitfinex.new('exchange', 'BTC')
|
32
|
+
@rap.fetch_csv_history
|
33
|
+
@rap.create_csv_file
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context 'history' do
|
37
|
+
it 'should have correct currency' do
|
38
|
+
expect(@rap.currency).to eql('BTC')
|
39
|
+
end
|
40
|
+
it 'should have correct size' do
|
41
|
+
expect(@rap.history.size).to eql(206)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
context 'bitfinex CSV' do
|
46
|
+
context 'csv' do
|
47
|
+
it 'should have generated a correct CSV file' do
|
48
|
+
expect(File.exist?(Bitfinex_CSV_Test_File)).to eql(true)
|
49
|
+
lines = IO.readlines(Bitfinex_CSV_Test_File)
|
50
|
+
expect(lines.first.chomp).to eql('currency;amount;balance;description;date_time')
|
51
|
+
expect(lines[1].chomp).to eql(
|
52
|
+
'BTC;-0.00000005;0.0;Transfer of 0.0 BTC from wallet Exchange to Deposit on wallet Exchange;2016.12.03 21:20:47')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
context 'exchange option --clean' do
|
57
|
+
before(:all) do
|
58
|
+
@date_bfx_1 = Date.new(2017,1,10)
|
59
|
+
@date_btx_1 = Date.new(2017,1,21)
|
60
|
+
@date_btx_2 = Date.new(2017,1,10)
|
61
|
+
VCR.use_cassette("rapflag", :record => :new_episodes) do
|
62
|
+
FileUtils.rm_f(BITFINEX_SUMMARY_EXCHANGE_BTC_File) if File.exist?(Bitfinex_CSV_Test_File)
|
63
|
+
expect(File.exist?(BITFINEX_SUMMARY_EXCHANGE_BTC_File)).to eql(false)
|
64
|
+
@exchange = RAPFLAG::Bitfinex.new('exchange', 'BTC')
|
65
|
+
@exchange.fetch_csv_history
|
66
|
+
@exchange.create_summary
|
67
|
+
@bfx = @exchange.get_usd_exchange(@date_bfx_1, 'BFX')
|
68
|
+
@btx_1 = @exchange.get_usd_exchange(@date_btx_1, 'BTC')
|
69
|
+
@btx_2 = @exchange.get_usd_exchange(@date_btx_2, 'BTC')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
it 'should have generated a correct summary CSV file' do
|
73
|
+
expect(File.exist?(BITFINEX_SUMMARY_EXCHANGE_BTC_File)).to eql(true)
|
74
|
+
lines = IO.readlines(BITFINEX_SUMMARY_EXCHANGE_BTC_File)
|
75
|
+
expect(lines.first.chomp).to eql('currency;date;income;balance;rate;balance_in_usd')
|
76
|
+
expect(lines[1].chomp).to eql('BTC;2016.01.15;0.0;8.99788147;;')
|
77
|
+
expect(lines[-1].chomp).to eql('BTC;2016.12.03;0.0;0.0;765.46;0.0')
|
78
|
+
end
|
79
|
+
it 'should have a balance for for each day' do
|
80
|
+
expect(File.exist?(BITFINEX_SUMMARY_EXCHANGE_BTC_File)).to eql(true)
|
81
|
+
lines = IO.readlines(BITFINEX_SUMMARY_EXCHANGE_BTC_File)
|
82
|
+
first_date = Date.strptime(lines[1].chomp.split(';')[1], '%Y.%m.%d')
|
83
|
+
last_date = Date.strptime(lines[-1].chomp.split(';')[1], '%Y.%m.%d')
|
84
|
+
(last_date > first_date).should be true
|
85
|
+
nr_dates = 323
|
86
|
+
(last_date - first_date).to_i.should eql nr_dates
|
87
|
+
(1..nr_dates).each do |j|
|
88
|
+
wish_date = (first_date + j).strftime('%Y.%m.%d')
|
89
|
+
binding.pry unless lines.find_all{|line| line.index(wish_date)}.size == 1
|
90
|
+
lines.find_all{|line| line.index(wish_date)}.size.should eql 1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
it 'should have NOT have generated a correct summary deposit BFX CSV file' do
|
94
|
+
expect(File.exist?(BITFINEX_SUMMARY_DEPOSIT_BFX_File)).to eql(false)
|
95
|
+
end
|
96
|
+
it 'should have the correct BTC -> USD rate' do
|
97
|
+
expect(@btx_1).to eql 924.02
|
98
|
+
expect(@btx_2).to eql 905.76
|
99
|
+
end
|
100
|
+
it 'should have the correct BFX -> USD rate' do
|
101
|
+
expect(@bfx).to eql 0.5697
|
102
|
+
end
|
103
|
+
end
|
104
|
+
context 'deposit option --clean' do
|
105
|
+
before(:all) do
|
106
|
+
FileUtils.rm_f(BITFINEX_SUMMARY_EXCHANGE_BTC_File) if File.exist?(BITFINEX_SUMMARY_EXCHANGE_BTC_File)
|
107
|
+
FileUtils.rm_f(BITFINEX_SUMMARY_DEPOSIT_BFX_File) if File.exist?(Bitfinex_CSV_Test_File)
|
108
|
+
@date_bfx_1 = Date.new(2017,1,10)
|
109
|
+
@date_btx_1 = Date.new(2017,1,21)
|
110
|
+
@date_btx_2 = Date.new(2017,1,10)
|
111
|
+
VCR.use_cassette("rapflag", :record => :new_episodes) do
|
112
|
+
expect(File.exist?(BITFINEX_SUMMARY_DEPOSIT_BFX_File)).to eql(false)
|
113
|
+
@deposit = RAPFLAG::Bitfinex.new('deposit', 'BFX')
|
114
|
+
@deposit.fetch_csv_history
|
115
|
+
@deposit.create_summary
|
116
|
+
end
|
117
|
+
end
|
118
|
+
it 'should have NOT generated a exchange BTC summary CSV file' do
|
119
|
+
expect(File.exist?(BITFINEX_SUMMARY_EXCHANGE_BTC_File)).to eql(false)
|
120
|
+
end
|
121
|
+
it 'should have NOT generated a correct summary CSV file' do
|
122
|
+
expect(File.exist?(BITFINEX_SUMMARY_DEPOSIT_BFX_File)).to eql(true)
|
123
|
+
lines = IO.readlines(BITFINEX_SUMMARY_DEPOSIT_BFX_File)
|
124
|
+
expect(lines.first.chomp).to eql('currency;date;income;balance;rate;balance_in_usd')
|
125
|
+
expect(lines[1].chomp).to eql('BFX;2016.01.15;0.0;8.99788147;;')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'rapflag/poloniex'
|
4
|
+
require 'vcr'
|
5
|
+
|
6
|
+
VCR.configure do |config|
|
7
|
+
config.cassette_library_dir = "fixtures/vcr_cassettes"
|
8
|
+
config.hook_into :faraday
|
9
|
+
end
|
10
|
+
|
11
|
+
VCR.eject_cassette # we use insert/eject around each example
|
12
|
+
|
13
|
+
describe RAPFLAG::Poloniex do
|
14
|
+
TEST_OUTPUT_ROOT = File.expand_path(File.join(__FILE__, '..', '..', 'output/poloniex'))
|
15
|
+
Poloniex_CSV_Test_File = TEST_OUTPUT_ROOT + '/BTC_exchange.csv'
|
16
|
+
Poloniex_SUMMARY_EXCHANGE_BTC_File = TEST_OUTPUT_ROOT + '/BTC_exchange_summary.csv'
|
17
|
+
Poloniex_SUMMARY_DEPOSIT_BFX_File = TEST_OUTPUT_ROOT + '/BFX_deposit_summary.csv'
|
18
|
+
|
19
|
+
context 'poloniex' do
|
20
|
+
before(:all) do
|
21
|
+
# skip("We cannot yet use VCR here. Therefore omitting all spec tests")
|
22
|
+
# VCR.use_cassette("poloniex", :record => :new_episodes) do
|
23
|
+
FileUtils.rm_f(Poloniex_CSV_Test_File) if File.exist?(Poloniex_CSV_Test_File)
|
24
|
+
FileUtils.rm_f(Poloniex_SUMMARY_DEPOSIT_BFX_File) if File.exist?(Poloniex_SUMMARY_DEPOSIT_BFX_File)
|
25
|
+
FileUtils.rm_f(Poloniex_SUMMARY_EXCHANGE_BTC_File) if File.exist?(Poloniex_CSV_Test_File)
|
26
|
+
expect(File.exist?(Poloniex_CSV_Test_File)).to eql(false)
|
27
|
+
@rap = RAPFLAG::Poloniex.new('exchange', 'BTC')
|
28
|
+
@rap.fetch_csv_history
|
29
|
+
# @rap.create_csv_file
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
context 'history' do
|
33
|
+
it 'should have correct currency' do
|
34
|
+
expect(@rap.currency).to eql('BTC')
|
35
|
+
end
|
36
|
+
it 'should have correct size' do
|
37
|
+
expect(@rap.history.size).to eql(368)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
context 'poloniex CSV' do
|
42
|
+
before(:all) do
|
43
|
+
skip("We cannot yet use VCR here. Therefore omitting all spec tests")
|
44
|
+
end
|
45
|
+
context 'csv' do
|
46
|
+
it 'should have generated a correct CSV file' do
|
47
|
+
expect(File.exist?(Poloniex_CSV_Test_File)).to eql(true)
|
48
|
+
lines = IO.readlines(Poloniex_CSV_Test_File)
|
49
|
+
expect(lines.first.chomp).to eql('currency,amount,balance,description,date_time')
|
50
|
+
expect(lines[1].chomp).to eql(
|
51
|
+
'BTC,-0.00000005,0.0,Transfer of 0.0 BTC from wallet Exchange to Deposit on wallet Exchange,2016.12.03 21:20:47')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
context 'exchange option --clean' do
|
56
|
+
before(:all) do
|
57
|
+
skip("We cannot yet use VCR here. Therefore omitting all spec tests")
|
58
|
+
@date_bfx_1 = Date.new(2017,1,10)
|
59
|
+
@date_btx_1 = Date.new(2017,1,21)
|
60
|
+
@date_btx_2 = Date.new(2017,1,10)
|
61
|
+
VCR.use_cassette("poloniex", :record => :new_episodes) do
|
62
|
+
FileUtils.rm_f(Poloniex_SUMMARY_EXCHANGE_BTC_File) if File.exist?(Poloniex_CSV_Test_File)
|
63
|
+
expect(File.exist?(Poloniex_SUMMARY_EXCHANGE_BTC_File)).to eql(false)
|
64
|
+
@exchange = RAPFLAG::Poloniex.new('exchange', 'BTC')
|
65
|
+
@exchange.fetch_csv_history
|
66
|
+
@exchange.create_summary
|
67
|
+
@bfx = @exchange.get_usd_exchange(@date_bfx_1, 'BFX')
|
68
|
+
@btx_1 = @exchange.get_usd_exchange(@date_btx_1, 'BTC')
|
69
|
+
@btx_2 = @exchange.get_usd_exchange(@date_btx_2, 'BTC')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
it 'should have generated a correct summary CSV file' do
|
73
|
+
expect(File.exist?(Poloniex_SUMMARY_EXCHANGE_BTC_File)).to eql(true)
|
74
|
+
lines = IO.readlines(Poloniex_SUMMARY_EXCHANGE_BTC_File)
|
75
|
+
expect(lines.first.chomp).to eql('currency,date,income,balance,rate,balance_in_usd')
|
76
|
+
expect(lines[1].chomp).to eql('BTC,2016.01.15,0.0,8.99788147,,')
|
77
|
+
expect(lines[-1].chomp).to eql('BTC,2016.12.03,0.0,0.0,765.46,0.0')
|
78
|
+
end
|
79
|
+
it 'should have NOT have generated a correct summary deposit BFX CSV file' do
|
80
|
+
expect(File.exist?(Poloniex_SUMMARY_DEPOSIT_BFX_File)).to eql(false)
|
81
|
+
end
|
82
|
+
it 'should have the correct BTC -> USD rate' do
|
83
|
+
expect(@btx_1).to eql 924.02
|
84
|
+
expect(@btx_2).to eql 905.76
|
85
|
+
end
|
86
|
+
it 'should have the correct BFX -> USD rate' do
|
87
|
+
expect(@bfx).to eql 0.5697
|
88
|
+
end
|
89
|
+
end
|
90
|
+
context 'deposit option --clean' do
|
91
|
+
before(:all) do
|
92
|
+
skip("We cannot yet use VCR here. Therefore omitting all spec tests")
|
93
|
+
FileUtils.rm_f(Poloniex_SUMMARY_EXCHANGE_BTC_File) if File.exist?(Poloniex_SUMMARY_EXCHANGE_BTC_File)
|
94
|
+
FileUtils.rm_f(Poloniex_SUMMARY_DEPOSIT_BFX_File) if File.exist?(Poloniex_CSV_Test_File)
|
95
|
+
@date_bfx_1 = Date.new(2017,1,10)
|
96
|
+
@date_btx_1 = Date.new(2017,1,21)
|
97
|
+
@date_btx_2 = Date.new(2017,1,10)
|
98
|
+
VCR.use_cassette("rapflag", :record => :new_episodes) do
|
99
|
+
expect(File.exist?(Poloniex_SUMMARY_DEPOSIT_BFX_File)).to eql(false)
|
100
|
+
@deposit = RAPFLAG::Poloniex.new('deposit', 'BFX')
|
101
|
+
@deposit.fetch_csv_history
|
102
|
+
@deposit.create_summary
|
103
|
+
end
|
104
|
+
end
|
105
|
+
it 'should have NOT generated a exchange BTC summary CSV file' do
|
106
|
+
expect(File.exist?(Poloniex_SUMMARY_EXCHANGE_BTC_File)).to eql(false)
|
107
|
+
end
|
108
|
+
it 'should have NOT generated a correct summary CSV file' do
|
109
|
+
expect(File.exist?(Poloniex_SUMMARY_DEPOSIT_BFX_File)).to eql(true)
|
110
|
+
lines = IO.readlines(Poloniex_SUMMARY_DEPOSIT_BFX_File)
|
111
|
+
expect(lines.first.chomp).to eql('currency,date,income,balance,rate,balance_in_usd')
|
112
|
+
expect(lines[1].chomp).to eql('BFX,2016.01.15,0.0,8.99788147,,')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,9 @@ rescue LOAD_ERROR
|
|
4
4
|
end
|
5
5
|
|
6
6
|
require 'rapflag/version'
|
7
|
+
require 'rapflag/config'
|
7
8
|
require 'bitfinex-api-rb'
|
9
|
+
require 'poloniex'
|
8
10
|
|
9
11
|
module RAPFLAG
|
10
12
|
# create dummy config for spec tests
|
@@ -13,6 +15,10 @@ module RAPFLAG
|
|
13
15
|
conf.secret = 'SECRECT_KEY'
|
14
16
|
conf.websocket_api_endpoint = 'wss://api.bitfinex.com/ws'
|
15
17
|
end
|
18
|
+
Poloniex.setup do | config |
|
19
|
+
config.key = 'P_123467889'
|
20
|
+
config.secret = 'P_SECRECT_KEY'
|
21
|
+
end
|
16
22
|
end
|
17
23
|
|
18
24
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rapflag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zeno R.R. Davatz, Niklaus Giger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: poloniex
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bitfinex-rb
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,16 +147,20 @@ files:
|
|
133
147
|
- ".rspec"
|
134
148
|
- ".travis.yml"
|
135
149
|
- Gemfile
|
150
|
+
- History.md
|
136
151
|
- LICENSE
|
137
152
|
- README.md
|
138
153
|
- Rakefile
|
139
154
|
- bin/rapflag
|
140
155
|
- fixtures/vcr_cassettes/rapflag.yml
|
156
|
+
- lib/rapflag/bitfinex.rb
|
141
157
|
- lib/rapflag/config.rb
|
142
|
-
- lib/rapflag/
|
158
|
+
- lib/rapflag/history.rb
|
159
|
+
- lib/rapflag/poloniex.rb
|
143
160
|
- lib/rapflag/version.rb
|
144
161
|
- rapflag.gemspec
|
145
|
-
- spec/
|
162
|
+
- spec/bitfinex_spec.rb
|
163
|
+
- spec/poloniex_spec.rb
|
146
164
|
- spec/spec_helper.rb
|
147
165
|
homepage: https://github.com/zdavatz/rapflag
|
148
166
|
licenses:
|
@@ -169,5 +187,6 @@ signing_key:
|
|
169
187
|
specification_version: 4
|
170
188
|
summary: Bitfinex Exporter for your Taxman from ywesee
|
171
189
|
test_files:
|
172
|
-
- spec/
|
190
|
+
- spec/bitfinex_spec.rb
|
191
|
+
- spec/poloniex_spec.rb
|
173
192
|
- spec/spec_helper.rb
|