349 lines
10 KiB
Ruby
349 lines
10 KiB
Ruby
# encoding: UTF-8
|
|
# frozen_string_literal: true
|
|
|
|
describe Trade, '#for_notify' do
|
|
let(:order_ask) { create(:order_ask, :btcusd) }
|
|
let(:order_bid) { create(:order_bid, :btcusd) }
|
|
let(:trade) { create(:trade, :btcusd, maker_order: order_ask, taker_order: order_bid) }
|
|
|
|
subject(:notify) { trade.for_notify(order_ask.member) }
|
|
|
|
it do
|
|
expect(notify).not_to be_blank
|
|
expect(notify[:side]).not_to be_blank
|
|
expect(notify[:created_at]).not_to be_blank
|
|
expect(notify[:price]).not_to be_blank
|
|
expect(notify[:amount]).not_to be_blank
|
|
expect(notify[:order_id]).to eq(order_ask.id)
|
|
end
|
|
|
|
it 'should use side as kind' do
|
|
expect(trade.for_notify(Member.find(trade.maker_id))[:side]).to eq 'sell'
|
|
end
|
|
|
|
context 'notify for bid member' do
|
|
subject(:notify) { trade.for_notify(order_bid.member) }
|
|
|
|
it do
|
|
expect(notify).not_to be_blank
|
|
expect(notify[:side]).not_to be_blank
|
|
expect(notify[:created_at]).not_to be_blank
|
|
expect(notify[:price]).not_to be_blank
|
|
expect(notify[:amount]).not_to be_blank
|
|
expect(notify[:order_id]).to eq(order_bid.id)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe Trade, '#trade_from_influx_after_date' do
|
|
after { delete_measurments("trades") }
|
|
|
|
context 'no trades executed yet' do
|
|
it 'returns trade' do
|
|
expect(Trade.trade_from_influx_after_date(:btcusd, Time.now)).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'single trade was executing' do
|
|
let(:trade) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
|
let(:expected_trade) do
|
|
{
|
|
:id=>trade.id,
|
|
:price=>5,
|
|
:amount=>1.1,
|
|
:total=>5.5,
|
|
:taker_type=>trade.taker_type,
|
|
:market=>'btcusd',
|
|
:created_at=>trade.created_at.to_i
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade.write_to_influx
|
|
end
|
|
|
|
it 'returns trade' do
|
|
expect(Trade.trade_from_influx_after_date(trade.market_id, Time.now - 1.minutes).except(:time)).to eq(expected_trade)
|
|
end
|
|
end
|
|
|
|
context 'multiple trades were executed' do
|
|
let!(:trade1) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d, created_at: Time.now)}
|
|
let!(:trade2) { create(:trade, :btcusd, price: '6.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d, created_at: Time.now + 3.minutes)}
|
|
let!(:trade3) { create(:trade, :btcusd, price: '7.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d, created_at: Time.now + 4.minutes)}
|
|
|
|
let(:expected_trade) do
|
|
{
|
|
:id=>trade1.id,
|
|
:price=>5.0,
|
|
:amount=>1.1,
|
|
:total=>5.5,
|
|
:taker_type=>trade1.taker_type,
|
|
:market=>'btcusd',
|
|
:created_at=>trade1.created_at.to_i
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade1.write_to_influx
|
|
trade2.write_to_influx
|
|
trade3.write_to_influx
|
|
end
|
|
|
|
it 'returns trade' do
|
|
expect(Trade.trade_from_influx_after_date(trade1.market_id, Time.now - 1.minutes).except(:time)).to eq(expected_trade)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe Trade, '#trade_from_influx_before_date' do
|
|
after { delete_measurments("trades") }
|
|
|
|
context 'no trades executed yet' do
|
|
it 'returns trade' do
|
|
expect(Trade.trade_from_influx_before_date(:btcusd, Time.now)).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'single trade was executed' do
|
|
let(:trade) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
|
let(:expected_trade) do
|
|
{
|
|
:id=>trade.id,
|
|
:price=>5,
|
|
:amount=>1.1,
|
|
:total=>5.5,
|
|
:taker_type=>trade.taker_type,
|
|
:market=>'btcusd',
|
|
:created_at=>trade.created_at.to_i
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade.write_to_influx
|
|
end
|
|
|
|
it 'returns trade' do
|
|
expect(Trade.trade_from_influx_before_date(trade.market_id, Time.now + 3.minutes).except(:time)).to eq(expected_trade)
|
|
end
|
|
end
|
|
|
|
context 'multiple trades were executed' do
|
|
let!(:trade3) { create(:trade, :btcusd, price: '7.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d, created_at: Time.now)}
|
|
let!(:trade2) { create(:trade, :btcusd, price: '6.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d, created_at: 2.days.ago)}
|
|
let!(:trade1) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d, created_at: 3.days.ago)}
|
|
let(:expected_trade) do
|
|
{
|
|
:id=>trade3.id,
|
|
:price=>7,
|
|
:amount=>0.9,
|
|
:total=>5.4,
|
|
:taker_type=>trade3.taker_type,
|
|
:market=>'btcusd',
|
|
:created_at=>trade3.created_at.to_i
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade1.write_to_influx
|
|
trade2.write_to_influx
|
|
trade3.write_to_influx
|
|
end
|
|
|
|
it 'returns trade' do
|
|
expect(Trade.trade_from_influx_before_date(trade1.market_id, Time.now + 3.minutes).except(:time)).to eq(expected_trade)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe Trade, '#nearest_trade_from_influx' do
|
|
after { delete_measurments("trades") }
|
|
|
|
context 'no trades executed yet' do
|
|
it 'returns trade' do
|
|
expect(Trade.nearest_trade_from_influx(:btcusd, Time.now)).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'trade executed before date' do
|
|
let(:trade) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
|
let(:expected_trade) do
|
|
{
|
|
:id=>trade.id,
|
|
:price=>5,
|
|
:amount=>1.1,
|
|
:total=>5.5,
|
|
:taker_type=>trade.taker_type,
|
|
:market=>'btcusd',
|
|
:created_at=>trade.created_at.to_i
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade.write_to_influx
|
|
end
|
|
|
|
it 'returns trade' do
|
|
expect(Trade.nearest_trade_from_influx(trade.market_id, Time.now + 3.minutes).except(:time)).to eq(expected_trade)
|
|
end
|
|
end
|
|
|
|
context 'trade executed after date' do
|
|
let(:trade) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
|
let(:expected_trade) do
|
|
{
|
|
:id=>trade.id,
|
|
:price=>5,
|
|
:amount=>1.1,
|
|
:total=>5.5,
|
|
:taker_type=>trade.taker_type,
|
|
:market=>'btcusd',
|
|
:created_at=>trade.created_at.to_i
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade.write_to_influx
|
|
end
|
|
|
|
it 'returns trade' do
|
|
expect(Trade.nearest_trade_from_influx(trade.market_id, Time.now).except(:time)).to eq(expected_trade)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe Trade, '#market_ticker_from_influx' do
|
|
after { delete_measurments("trades") }
|
|
|
|
context 'no trades executed yet' do
|
|
it 'returns ticker' do
|
|
expect(Trade.market_ticker_from_influx(:btcusd)).to eq([])
|
|
end
|
|
end
|
|
|
|
context 'single trade was executed' do
|
|
let!(:trade) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
|
let(:expected_ticker) do
|
|
{
|
|
:min=>5,
|
|
:max=>5,
|
|
:first=>5,
|
|
:last=>5,
|
|
:volume=>5.5,
|
|
:amount=>1.1,
|
|
:vwap=>5
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade.write_to_influx
|
|
end
|
|
|
|
it 'returns ticker' do
|
|
expect(Trade.market_ticker_from_influx(trade.market_id).except(:time)).to eq(expected_ticker)
|
|
end
|
|
end
|
|
|
|
context 'multiple trades were executed' do
|
|
let!(:trade1) { create(:trade, :btcusd, price: '5.0'.to_d, amount: '1.1'.to_d, total: '5.5'.to_d)}
|
|
let!(:trade2) { create(:trade, :btcusd, price: '6.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d)}
|
|
let!(:trade3) { create(:trade, :btcusd, price: '7.0'.to_d, amount: '0.9'.to_d, total: '5.4'.to_d)}
|
|
let(:expected_ticker) do
|
|
{
|
|
:amount => 2.9,
|
|
:first => 5,
|
|
:last => 7,
|
|
:max => 7,
|
|
:min => 5,
|
|
:volume => 16.3,
|
|
:vwap => 5.620689655172415
|
|
}
|
|
end
|
|
|
|
before do
|
|
trade1.write_to_influx
|
|
trade2.write_to_influx
|
|
trade3.write_to_influx
|
|
end
|
|
|
|
it 'returns ticker' do
|
|
expect(Trade.market_ticker_from_influx(trade1.market_id).except(:time)).to eq(expected_ticker)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe Trade, '#record_complete_operations!' do
|
|
# Persist orders and trades in database.
|
|
let!(:trade){ create(:trade, :btcusd, :with_deposit_liability) }
|
|
|
|
let(:ask){ trade.maker_order }
|
|
let(:bid){ trade.taker_order }
|
|
|
|
let(:ask_currency_outcome){ trade.amount }
|
|
let(:bid_currency_outcome){ trade.total }
|
|
|
|
let(:ask_currency_fee){ trade.amount * trade.order_fee(bid) }
|
|
let(:bid_currency_fee){ trade.total * trade.order_fee(ask) }
|
|
|
|
let(:ask_currency_income){ ask_currency_outcome - ask_currency_fee }
|
|
let(:bid_currency_income){ bid_currency_outcome - bid_currency_fee }
|
|
|
|
subject{ trade }
|
|
|
|
it 'creates four liability operations' do
|
|
expect{ subject.record_complete_operations! }.to change{ Operations::Liability.count }.by(4)
|
|
end
|
|
|
|
it 'doesn\'t create asset operations' do
|
|
expect{ subject.record_complete_operations! }.to_not change{ Operations::Asset.count }
|
|
end
|
|
|
|
it 'debits locked ask liabilities for ask creator' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
ask.member.balance_for(currency: ask.currency, kind: :locked)
|
|
}.by(-ask_currency_outcome)
|
|
end
|
|
|
|
it 'debits locked bid liabilities for bid creator' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
bid.member.balance_for(currency: bid.currency, kind: :locked)
|
|
}.by(-bid_currency_outcome)
|
|
end
|
|
|
|
it 'credits main bid liabilities for ask creator' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
ask.member.balance_for(currency: bid.currency, kind: :main)
|
|
}.by(bid_currency_income)
|
|
end
|
|
|
|
it 'credits main ask liabilities for bid creator' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
bid.member.balance_for(currency: ask.currency, kind: :main)
|
|
}.by(ask_currency_income)
|
|
end
|
|
|
|
it 'credits ask currency revenues' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
Operations::Revenue.balance(currency: ask.currency)
|
|
}.by(ask_currency_fee)
|
|
end
|
|
|
|
it 'credits bid currency revenues' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
Operations::Revenue.balance(currency: bid.currency)
|
|
}.by(bid_currency_fee)
|
|
end
|
|
|
|
it 'creates ask currency revenue from bid creator' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
Operations::Revenue.where(currency: ask.currency, member: bid.member).count
|
|
}.by(1)
|
|
end
|
|
|
|
it 'creates bid currency revenue from ask creator' do
|
|
expect{ subject.record_complete_operations! }.to change {
|
|
Operations::Revenue.where(currency: bid.currency, member: ask.member).count
|
|
}.by(1)
|
|
end
|
|
end
|