/
trade.rb
120 lines (90 loc) · 2.85 KB
/
trade.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class Trade < Operation
DEFAULT_COMMISSION_RATE = BigDecimal("0")
default_scope order("created_at DESC")
after_create :execute
belongs_to :purchase_order,
:class_name => "TradeOrder"
belongs_to :sale_order,
:class_name => "TradeOrder"
belongs_to :seller,
:class_name => "User"
belongs_to :buyer,
:class_name => "User"
has_many :transfers
validates :purchase_order,
:presence => true
validates :sale_order,
:presence=> true
validates :seller,
:presence => true
validates :buyer,
:presence=> true
validates :traded_btc,
:numericality => { :greater_than => 0 },
:presence => true
validates :traded_currency,
:numericality => { :greater_than => 0 },
:presence => true
validates :ppc,
:numericality => true,
:presence => true
validates :currency,
:inclusion => { :in => AccountOperation::CURRENCIES },
:presence => true
scope :last_24h, lambda {
where("created_at >= ?", DateTime.now.advance(:hours => -24))
}
scope :last_week, lambda {
where("created_at >= ?", DateTime.now.advance(:days => -7))
}
scope :involved, lambda { |user|
where("seller_id = ? OR buyer_id = ?", user.id, user.id)
}
# TODO : Dry up (duplicated in TradeOrder)
def self.with_currency(currency)
where("currency = ?", currency.to_s.upcase)
end
def self.plottable(currency)
with_exclusive_scope do
with_currency(currency).order("created_at ASC")
end
end
def execute
seller_commission_rate = sale_order.user.commission_rate || DEFAULT_COMMISSION_RATE
buyer_commission_rate = purchase_order.user.commission_rate || DEFAULT_COMMISSION_RATE
btc_fee = traded_btc * buyer_commission_rate
currency_fee = traded_currency * seller_commission_rate
account_operations << AccountOperation.new do |it|
it.currency = currency
it.amount = -traded_currency
it.account_id = purchase_order.user_id
end
account_operations << AccountOperation.new do |it|
it.currency = currency
it.amount = traded_currency - currency_fee
it.account_id = sale_order.user_id
end
account_operations << AccountOperation.new do |bt|
bt.currency = "BTC"
bt.amount = -traded_btc
bt.account_id = sale_order.user_id
bt.payee_id = purchase_order.user_id
end
account_operations << AccountOperation.new do |bt|
bt.currency = "BTC"
bt.amount = traded_btc - btc_fee
bt.account_id = purchase_order.user_id
end
account_operations << AccountOperation.new do |fee|
fee.currency = "BTC"
fee.amount = btc_fee
fee.account = Account.storage_account_for(:fees)
end
account_operations << AccountOperation.new do |fee|
fee.currency = currency
fee.amount = currency_fee
fee.account = Account.storage_account_for(:fees)
end
save!
end
end