coinsync 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/coinsync/config.rb +2 -7
- data/lib/coinsync/currency_conversion_task.rb +2 -2
- data/lib/coinsync/currency_converters/base.rb +8 -11
- data/lib/coinsync/currency_converters/exchangeratesapi.rb +14 -1
- data/lib/coinsync/currency_converters/nbp.rb +15 -1
- data/lib/coinsync/formatter.rb +2 -1
- data/lib/coinsync/importers/binance_api.rb +25 -16
- data/lib/coinsync/importers/bitbay20.rb +6 -3
- data/lib/coinsync/importers/bitbay_api.rb +17 -8
- data/lib/coinsync/importers/bitcurex.rb +4 -2
- data/lib/coinsync/importers/bitstamp_csv.rb +73 -0
- data/lib/coinsync/importers/bittrex_csv.rb +1 -1
- data/lib/coinsync/importers/default.rb +4 -1
- data/lib/coinsync/importers/kucoin_api.rb +11 -2
- data/lib/coinsync/outputs/list.rb +5 -1
- data/lib/coinsync/version.rb +1 -1
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0072156912886d0dda428c95b5421b230ce73bb
|
4
|
+
data.tar.gz: 3cb523a19af17908648fad02113d63fea9c7cb47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57fe540967120d3926ad5ac5e7883aae9f49147b6e6eba82e0f4b1c38aa1ea54af70adfd1140545e75fa1255907b9bd4a6860094dd75f9f77e96d78d227a52ce
|
7
|
+
data.tar.gz: 4aa898c645ca40f083720d22b517e7d3dc8c53ab8246bf977c5fbe00dccbc8188c7b44e34b220c119076b9597a373ba031e6c8bc5a047002c0923ea8b9f7d272
|
data/lib/coinsync/config.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ostruct'
|
2
|
+
require 'tzinfo'
|
2
3
|
require 'yaml'
|
3
4
|
|
4
5
|
require_relative 'currencies'
|
@@ -28,8 +29,6 @@ module CoinSync
|
|
28
29
|
require(File.expand_path(File.join(*directory, file)))
|
29
30
|
end
|
30
31
|
end
|
31
|
-
|
32
|
-
set_timezone(timezone) if timezone
|
33
32
|
end
|
34
33
|
|
35
34
|
def sources
|
@@ -55,10 +54,6 @@ module CoinSync
|
|
55
54
|
Hash[included.map { |source| [source.key, source] }]
|
56
55
|
end
|
57
56
|
|
58
|
-
def set_timezone(timezone)
|
59
|
-
ENV['TZ'] = timezone
|
60
|
-
end
|
61
|
-
|
62
57
|
def base_cryptocurrencies
|
63
58
|
settings['base_cryptocurrencies'] || ['USDT', 'BTC', 'ETH', 'BNB', 'KCS', 'LTC', 'BCH', 'NEO']
|
64
59
|
end
|
@@ -88,7 +83,7 @@ module CoinSync
|
|
88
83
|
end
|
89
84
|
|
90
85
|
def timezone
|
91
|
-
settings['timezone']
|
86
|
+
settings['timezone'] && TZInfo::Timezone.get(settings['timezone'])
|
92
87
|
end
|
93
88
|
|
94
89
|
def translate(label)
|
@@ -26,7 +26,7 @@ module CoinSync
|
|
26
26
|
BigDecimal.new(1),
|
27
27
|
from: tx.bought_currency,
|
28
28
|
to: @target_currency,
|
29
|
-
|
29
|
+
time: tx.time
|
30
30
|
)
|
31
31
|
tx.converted.bought_amount = tx.bought_amount * tx.converted.exchange_rate
|
32
32
|
else
|
@@ -44,7 +44,7 @@ module CoinSync
|
|
44
44
|
BigDecimal.new(1),
|
45
45
|
from: tx.sold_currency,
|
46
46
|
to: @target_currency,
|
47
|
-
|
47
|
+
time: tx.time
|
48
48
|
)
|
49
49
|
tx.converted.sold_amount = tx.sold_amount * tx.converted.exchange_rate
|
50
50
|
else
|
@@ -23,20 +23,17 @@ module CoinSync
|
|
23
23
|
@cache = Cache.new(self.class.name.downcase.split('::').last)
|
24
24
|
end
|
25
25
|
|
26
|
-
def convert(amount, from:, to:,
|
26
|
+
def convert(amount, from:, to:, time:)
|
27
27
|
(amount > 0) or raise "#{self.class}: amount should be positive"
|
28
28
|
(amount.is_a?(BigDecimal)) or raise "#{self.class}: 'amount' should be a BigDecimal"
|
29
|
-
(from.is_a?(FiatCurrency)) or raise "#{self.class}: 'from' should be a FiatCurrency"
|
30
|
-
(to.is_a?(FiatCurrency)) or raise "#{self.class}: 'to' should be a FiatCurrency"
|
31
|
-
(date.is_a?(Date)) or raise "#{self.class}: 'date' should be a Date"
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
30
|
+
rate = get_conversion_rate(from: from, to: to, time: time)
|
31
|
+
|
32
|
+
rate * amount
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_conversion_rate(from:, to:, time:)
|
36
|
+
raise "not implemented"
|
40
37
|
end
|
41
38
|
|
42
39
|
def finalize
|
@@ -10,12 +10,23 @@ module CoinSync
|
|
10
10
|
register_converter :exchangeratesapi
|
11
11
|
|
12
12
|
BASE_URL = "https://exchangeratesapi.io/api"
|
13
|
+
ECB_TIMEZONE = TZInfo::Timezone.get('Europe/Berlin')
|
13
14
|
|
14
15
|
class Exception < StandardError; end
|
15
16
|
class NoDataException < Exception; end
|
16
17
|
class BadRequestException < Exception; end
|
17
18
|
|
18
|
-
def
|
19
|
+
def get_conversion_rate(from:, to:, time:)
|
20
|
+
(from.is_a?(FiatCurrency)) or raise "#{self.class}: 'from' should be a FiatCurrency"
|
21
|
+
(to.is_a?(FiatCurrency)) or raise "#{self.class}: 'to' should be a FiatCurrency"
|
22
|
+
(time.is_a?(Time)) or raise "#{self.class}: 'time' should be a Time"
|
23
|
+
|
24
|
+
date = ECB_TIMEZONE.utc_to_local(time.utc).to_date
|
25
|
+
|
26
|
+
if rate = @cache[from, to, date]
|
27
|
+
return rate
|
28
|
+
end
|
29
|
+
|
19
30
|
response = Request.get("#{BASE_URL}/#{date}?base=#{from.code}")
|
20
31
|
|
21
32
|
case response
|
@@ -24,6 +35,8 @@ module CoinSync
|
|
24
35
|
rate = json['rates'][to.code.upcase]
|
25
36
|
raise NoDataException.new("No exchange rate found for #{to.code.upcase}") if rate.nil?
|
26
37
|
|
38
|
+
@cache[from, to, date] = rate
|
39
|
+
|
27
40
|
return rate
|
28
41
|
when Net::HTTPBadRequest
|
29
42
|
raise BadRequestException.new(response)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'net/http'
|
3
|
+
require 'tzinfo'
|
3
4
|
|
4
5
|
require_relative 'base'
|
5
6
|
require_relative '../request'
|
@@ -10,14 +11,25 @@ module CoinSync
|
|
10
11
|
register_converter :nbp
|
11
12
|
|
12
13
|
BASE_URL = "https://api.nbp.pl/api"
|
14
|
+
POLISH_TIMEZONE = TZInfo::Timezone.get('Europe/Warsaw')
|
13
15
|
|
14
16
|
class Exception < StandardError; end
|
15
17
|
class NoDataException < Exception; end
|
16
18
|
class BadRequestException < Exception; end
|
17
19
|
|
18
|
-
def
|
20
|
+
def get_conversion_rate(from:, to:, time:)
|
21
|
+
(from.is_a?(FiatCurrency)) or raise "#{self.class}: 'from' should be a FiatCurrency"
|
22
|
+
(to.is_a?(FiatCurrency)) or raise "#{self.class}: 'to' should be a FiatCurrency"
|
23
|
+
(time.is_a?(Time)) or raise "#{self.class}: 'time' should be a Time"
|
24
|
+
|
19
25
|
raise "Only conversions to PLN are supported" if to.code != 'PLN'
|
20
26
|
|
27
|
+
date = POLISH_TIMEZONE.utc_to_local(time.utc).to_date
|
28
|
+
|
29
|
+
if rate = @cache[from, to, date]
|
30
|
+
return rate
|
31
|
+
end
|
32
|
+
|
21
33
|
response = Request.get("#{BASE_URL}/exchangerates/rates/a/#{from.code}/#{date - 8}/#{date - 1}/?format=json")
|
22
34
|
|
23
35
|
case response
|
@@ -26,6 +38,8 @@ module CoinSync
|
|
26
38
|
rate = json['rates'] && json['rates'].last && json['rates'].last['mid']
|
27
39
|
raise NoDataException.new("No exchange rate found for #{from.code.upcase}") if rate.nil?
|
28
40
|
|
41
|
+
@cache[from, to, date] = rate
|
42
|
+
|
29
43
|
return rate
|
30
44
|
when Net::HTTPBadRequest
|
31
45
|
raise BadRequestException.new(response)
|
data/lib/coinsync/formatter.rb
CHANGED
@@ -33,7 +33,8 @@ module CoinSync
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def format_time(time)
|
36
|
-
|
36
|
+
local_time = @config.timezone ? @config.timezone.utc_to_local(time.utc) : time
|
37
|
+
local_time.strftime(@config.time_format || '%Y-%m-%d %H:%M:%S')
|
37
38
|
end
|
38
39
|
|
39
40
|
def parse_decimal(string)
|
@@ -68,23 +68,30 @@ module CoinSync
|
|
68
68
|
transactions = []
|
69
69
|
|
70
70
|
@traded_pairs.uniq.each do |pair|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
lastId = 0
|
72
|
+
|
73
|
+
loop do
|
74
|
+
response = make_request('/v3/myTrades', limit: 500, fromId: lastId + 1, symbol: pair)
|
75
|
+
|
76
|
+
case response
|
77
|
+
when Net::HTTPSuccess
|
78
|
+
json = JSON.parse(response.body)
|
79
|
+
|
80
|
+
if !json.is_a?(Array)
|
81
|
+
raise "Binance importer: Invalid response: #{response.body}"
|
82
|
+
elsif json.empty?
|
83
|
+
break
|
84
|
+
else
|
85
|
+
json.each { |tx| tx['symbol'] = pair }
|
86
|
+
lastId = json.map { |j| j['id'] }.sort.last
|
87
|
+
|
88
|
+
transactions.concat(json)
|
89
|
+
end
|
90
|
+
when Net::HTTPBadRequest
|
91
|
+
raise "Binance importer: Bad request: #{response} (#{response.body})"
|
92
|
+
else
|
93
|
+
raise "Binance importer: Bad response: #{response}"
|
79
94
|
end
|
80
|
-
|
81
|
-
json.each { |tx| tx['symbol'] = pair }
|
82
|
-
|
83
|
-
transactions.concat(json)
|
84
|
-
when Net::HTTPBadRequest
|
85
|
-
raise "Binance importer: Bad request: #{response} (#{response.body})"
|
86
|
-
else
|
87
|
-
raise "Binance importer: Bad response: #{response}"
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
@@ -187,6 +194,8 @@ module CoinSync
|
|
187
194
|
private
|
188
195
|
|
189
196
|
def make_request(path, params = {}, signed = true)
|
197
|
+
print '.'
|
198
|
+
|
190
199
|
if signed
|
191
200
|
(@api_key && @secret_key) or raise "Public and secret API keys must be provided"
|
192
201
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
require 'csv'
|
3
3
|
require 'time'
|
4
|
+
require 'tzinfo'
|
4
5
|
|
5
6
|
require_relative 'base'
|
6
7
|
require_relative '../currencies'
|
@@ -24,10 +25,12 @@ module CoinSync
|
|
24
25
|
class HistoryEntry
|
25
26
|
attr_accessor :date, :accounting_date, :type, :amount, :currency
|
26
27
|
|
28
|
+
POLISH_TIMEZONE = TZInfo::Timezone.get('Europe/Warsaw')
|
29
|
+
|
27
30
|
def initialize(line)
|
28
|
-
|
29
|
-
@
|
30
|
-
|
31
|
+
@date = POLISH_TIMEZONE.local_to_utc(Time.parse(line[0])) unless line[0] == '-'
|
32
|
+
@accounting_date = POLISH_TIMEZONE.local_to_utc(Time.parse(line[1])) unless line[1] == '-'
|
33
|
+
|
31
34
|
@type = line[2]
|
32
35
|
|
33
36
|
amount, currency = line[3].split(' ')
|
@@ -3,6 +3,7 @@ require 'json'
|
|
3
3
|
require 'net/http'
|
4
4
|
require 'openssl'
|
5
5
|
require 'time'
|
6
|
+
require 'tzinfo'
|
6
7
|
require 'uri'
|
7
8
|
|
8
9
|
require_relative 'base'
|
@@ -22,14 +23,16 @@ module CoinSync
|
|
22
23
|
OP_SALE = '-pay_for_currency'
|
23
24
|
OP_FEE = '-fee'
|
24
25
|
|
25
|
-
MAX_TIME_DIFFERENCE =
|
26
|
+
MAX_TIME_DIFFERENCE = 5.0
|
26
27
|
TRANSACTION_TYPES = [OP_PURCHASE, OP_SALE, OP_FEE]
|
27
28
|
|
29
|
+
POLISH_TIMEZONE = TZInfo::Timezone.get('Europe/Warsaw')
|
30
|
+
|
28
31
|
class HistoryEntry
|
29
32
|
attr_accessor :date, :amount, :type, :currency
|
30
33
|
|
31
34
|
def initialize(hash)
|
32
|
-
@date = Time.parse(hash['time'])
|
35
|
+
@date = POLISH_TIMEZONE.local_to_utc(Time.parse(hash['time']))
|
33
36
|
@amount = BigDecimal.new(hash['amount'])
|
34
37
|
@type = hash['operation_type']
|
35
38
|
@currency = parse_currency(hash['currency'])
|
@@ -94,7 +97,8 @@ module CoinSync
|
|
94
97
|
currencies.each do |currency|
|
95
98
|
sleep 1 # rate limiting
|
96
99
|
|
97
|
-
|
100
|
+
# TODO: does this limit really work? (no way to test it really and docs don't mention a max value)
|
101
|
+
response = make_request('history', currency: currency, limit: 10000)
|
98
102
|
|
99
103
|
case response
|
100
104
|
when Net::HTTPSuccess
|
@@ -144,15 +148,17 @@ module CoinSync
|
|
144
148
|
|
145
149
|
next unless TRANSACTION_TYPES.include?(entry.type)
|
146
150
|
|
147
|
-
if !matching.empty?
|
148
|
-
|
151
|
+
if !matching.empty?
|
152
|
+
must_match = matching.any? { |e| (e.date - entry.date).abs > MAX_TIME_DIFFERENCE }
|
153
|
+
transaction = process_matched(matching, must_match)
|
154
|
+
transactions << transaction if transaction
|
149
155
|
end
|
150
156
|
|
151
157
|
matching << entry
|
152
158
|
end
|
153
159
|
|
154
160
|
if !matching.empty?
|
155
|
-
transactions << process_matched(matching)
|
161
|
+
transactions << process_matched(matching, true)
|
156
162
|
end
|
157
163
|
|
158
164
|
transactions
|
@@ -161,7 +167,7 @@ module CoinSync
|
|
161
167
|
|
162
168
|
private
|
163
169
|
|
164
|
-
def process_matched(matching)
|
170
|
+
def process_matched(matching, must_match)
|
165
171
|
if matching.length % 3 == 0
|
166
172
|
purchases = matching.select { |tx| tx.type == OP_PURCHASE }
|
167
173
|
sales = matching.select { |tx| tx.type == OP_SALE }
|
@@ -186,7 +192,10 @@ module CoinSync
|
|
186
192
|
end
|
187
193
|
end
|
188
194
|
|
189
|
-
|
195
|
+
if must_match
|
196
|
+
raise "BitBay API importer error: Couldn't match some history lines: " +
|
197
|
+
matching.map { |m| "\n#{m.inspect}" }.join
|
198
|
+
end
|
190
199
|
end
|
191
200
|
|
192
201
|
def make_request(method, params = {})
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
require 'csv'
|
3
3
|
require 'time'
|
4
|
+
require 'tzinfo'
|
4
5
|
|
5
6
|
require_relative 'base'
|
6
7
|
require_relative '../currencies'
|
@@ -14,11 +15,12 @@ module CoinSync
|
|
14
15
|
class HistoryEntry
|
15
16
|
attr_accessor :lp, :type, :date, :market, :amount, :price, :total, :fee, :fee_currency, :id
|
16
17
|
|
18
|
+
POLISH_TIMEZONE = TZInfo::Timezone.get('Europe/Warsaw')
|
19
|
+
|
17
20
|
def initialize(line)
|
18
|
-
# TODO: force parsing in Polish timezone
|
19
21
|
@lp = line[0].to_i
|
20
22
|
@type = line[1]
|
21
|
-
@date = Time.parse(line[2])
|
23
|
+
@date = POLISH_TIMEZONE.local_to_utc(Time.parse(line[2]))
|
22
24
|
@market = FiatCurrency.new(line[3])
|
23
25
|
@amount = BigDecimal.new(line[4])
|
24
26
|
@price = BigDecimal.new(line[5].split(' ').first)
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'csv'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
require_relative 'base'
|
6
|
+
require_relative '../currencies'
|
7
|
+
require_relative '../transaction'
|
8
|
+
|
9
|
+
module CoinSync
|
10
|
+
module Importers
|
11
|
+
class BitstampCSV < Base
|
12
|
+
register_importer :bitstamp_csv
|
13
|
+
|
14
|
+
class HistoryEntry
|
15
|
+
attr_accessor :lp, :type, :date, :market, :amount, :price, :total, :fee, :fee_currency, :id
|
16
|
+
|
17
|
+
def initialize(line)
|
18
|
+
@type = line[0]
|
19
|
+
@date = Time.parse(line[1])
|
20
|
+
@account = line[2]
|
21
|
+
|
22
|
+
|
23
|
+
@lp = line[0].to_i
|
24
|
+
@market = FiatCurrency.new(line[3])
|
25
|
+
@amount = BigDecimal.new(line[4])
|
26
|
+
@price = BigDecimal.new(line[5].split(' ').first)
|
27
|
+
@total = BigDecimal.new(line[6].split(' ').first)
|
28
|
+
@fee = BigDecimal.new(line[7].split(' ').first)
|
29
|
+
@fee_currency = line[7].split(' ').last
|
30
|
+
@id = line[8].to_i
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_transaction_list(source)
|
35
|
+
csv = CSV.new(source, col_sep: ',')
|
36
|
+
|
37
|
+
transactions = []
|
38
|
+
bitcoin = CryptoCurrency.new('BTC')
|
39
|
+
|
40
|
+
csv.each do |line|
|
41
|
+
next if line.empty?
|
42
|
+
next if line[0] == 'Type'
|
43
|
+
|
44
|
+
entry = HistoryEntry.new(line)
|
45
|
+
|
46
|
+
if entry.type == 'Kup'
|
47
|
+
transactions << Transaction.new(
|
48
|
+
exchange: 'Bitcurex',
|
49
|
+
bought_currency: bitcoin,
|
50
|
+
sold_currency: entry.market,
|
51
|
+
time: entry.date,
|
52
|
+
bought_amount: entry.amount,
|
53
|
+
sold_amount: entry.total
|
54
|
+
)
|
55
|
+
elsif entry.type == 'Sprzedaj'
|
56
|
+
transactions << Transaction.new(
|
57
|
+
exchange: 'Bitcurex',
|
58
|
+
bought_currency: entry.market,
|
59
|
+
sold_currency: bitcoin,
|
60
|
+
time: entry.date,
|
61
|
+
bought_amount: entry.total,
|
62
|
+
sold_amount: entry.amount
|
63
|
+
)
|
64
|
+
else
|
65
|
+
raise "Bitcurex importer error: unexpected entry type '#{entry.type}'"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
transactions.reverse
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -58,7 +58,7 @@ module CoinSync
|
|
58
58
|
transactions << Transaction.new(
|
59
59
|
exchange: 'Bittrex',
|
60
60
|
time: entry.time_closed,
|
61
|
-
bought_amount: entry.price - entry.commission,
|
61
|
+
bought_amount: entry.price - entry.commission,
|
62
62
|
bought_currency: entry.currency,
|
63
63
|
sold_amount: entry.quantity,
|
64
64
|
sold_currency: entry.asset
|
@@ -68,7 +68,10 @@ module CoinSync
|
|
68
68
|
entry.lp = line[0].to_i
|
69
69
|
entry.exchange = line[1]
|
70
70
|
entry.type = line[2]
|
71
|
-
|
71
|
+
|
72
|
+
time = Time.parse(line[3])
|
73
|
+
entry.date = @config.timezone ? @config.timezone.local_to_utc(time) : time
|
74
|
+
|
72
75
|
entry.amount = @formatter.parse_decimal(line[4])
|
73
76
|
entry.asset = CryptoCurrency.new(line[5])
|
74
77
|
entry.total = @formatter.parse_decimal(line[6])
|
@@ -43,7 +43,8 @@ module CoinSync
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def import_transactions(filename)
|
46
|
-
|
46
|
+
# TODO: what if there's more than 100? (looks like we might need to switch to loading each market separately…)
|
47
|
+
response = make_request('/order/dealt', limit: 100)
|
47
48
|
|
48
49
|
case response
|
49
50
|
when Net::HTTPSuccess
|
@@ -128,8 +129,16 @@ module CoinSync
|
|
128
129
|
sold_amount: entry.deal_value,
|
129
130
|
sold_currency: entry.coin_type_pair
|
130
131
|
)
|
132
|
+
elsif entry.direction == 'SELL'
|
133
|
+
transactions << Transaction.new(
|
134
|
+
exchange: 'Kucoin',
|
135
|
+
time: entry.created_at,
|
136
|
+
sold_amount: entry.amount,
|
137
|
+
sold_currency: entry.coin_type,
|
138
|
+
bought_amount: entry.deal_value - entry.fee,
|
139
|
+
bought_currency: entry.coin_type_pair
|
140
|
+
)
|
131
141
|
else
|
132
|
-
# TODO sell
|
133
142
|
raise "Kucoin importer error: unexpected entry direction '#{entry.direction}'"
|
134
143
|
end
|
135
144
|
end
|
@@ -16,7 +16,7 @@ module CoinSync
|
|
16
16
|
csv << headers
|
17
17
|
|
18
18
|
transactions.each do |tx|
|
19
|
-
|
19
|
+
process_transaction(tx, csv)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -45,6 +45,10 @@ module CoinSync
|
|
45
45
|
line
|
46
46
|
end
|
47
47
|
|
48
|
+
def process_transaction(tx, csv)
|
49
|
+
csv << transaction_to_csv(tx)
|
50
|
+
end
|
51
|
+
|
48
52
|
def transaction_to_csv(tx)
|
49
53
|
if tx.purchase? || tx.sale?
|
50
54
|
fiat_transaction_to_csv(tx)
|
data/lib/coinsync/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coinsync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kuba Suder
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04-
|
12
|
-
dependencies:
|
11
|
+
date: 2018-04-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: tzinfo
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.2.5
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.2.5
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
13
33
|
description:
|
14
34
|
email:
|
15
35
|
- jakub.suder@gmail.com
|
@@ -45,6 +65,7 @@ files:
|
|
45
65
|
- lib/coinsync/importers/bitbay20.rb
|
46
66
|
- lib/coinsync/importers/bitbay_api.rb
|
47
67
|
- lib/coinsync/importers/bitcurex.rb
|
68
|
+
- lib/coinsync/importers/bitstamp_csv.rb
|
48
69
|
- lib/coinsync/importers/bittrex_api.rb
|
49
70
|
- lib/coinsync/importers/bittrex_csv.rb
|
50
71
|
- lib/coinsync/importers/changelly.rb
|