mirror of
https://github.com/we-promise/sure
synced 2026-04-25 17:15:07 +02:00
Increasing trades.price decimal scale (#89)
* Changing trades.price to have a larger scale - a scale of 4 causes destructive rounding when calculating transaction cost; changes to the UI to allow for inputting and showing increased scale trade prices; test case
This commit is contained in:
@@ -48,14 +48,14 @@
|
||||
inline: true,
|
||||
placeholder: "100",
|
||||
value: if options[:value]
|
||||
sprintf("%.#{currency.default_precision}f", options[:value])
|
||||
sprintf("%.#{options[:precision].presence || currency.default_precision}f", options[:value])
|
||||
elsif form.object && form.object.respond_to?(amount_method)
|
||||
val = form.object.public_send(amount_method)
|
||||
sprintf("%.#{currency.default_precision}f", val) if val.present?
|
||||
sprintf("%.#{options[:precision].presence || currency.default_precision}f", val) if val.present?
|
||||
end,
|
||||
min: options[:min] || -99999999999999,
|
||||
max: options[:max] || 99999999999999,
|
||||
step: currency.step,
|
||||
step: options[:step] || currency.step,
|
||||
disabled: options[:disabled],
|
||||
data: {
|
||||
"money-field-target": "amount",
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
<% if %w[buy sell].include?(type) %>
|
||||
<%= form.number_field :qty, label: t(".qty"), placeholder: "10", min: 0.000000000000000001, step: "any", required: true %>
|
||||
<%= form.money_field :price, label: t(".price"), required: true %>
|
||||
<%= form.money_field :price, label: t(".price"), step: 'any', precision: 10, required: true %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
disable_currency: true,
|
||||
auto_submit: true,
|
||||
min: 0,
|
||||
step: "any",
|
||||
precision: 10,
|
||||
disabled: @entry.linked? %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class IncreaseTradePricePrecision < ActiveRecord::Migration[7.2]
|
||||
def up
|
||||
change_column :trades, :price, :decimal, precision: 19, scale: 10
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :trades, :price, :decimal, precision: 19, scale: 4
|
||||
end
|
||||
end
|
||||
2
db/schema.rb
generated
2
db/schema.rb
generated
@@ -789,7 +789,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_08_08_143007) do
|
||||
create_table "trades", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
|
||||
t.uuid "security_id", null: false
|
||||
t.decimal "qty", precision: 19, scale: 4
|
||||
t.decimal "price", precision: 19, scale: 4
|
||||
t.decimal "price", precision: 19, scale: 10
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "currency"
|
||||
|
||||
@@ -20,4 +20,38 @@ class TradeTest < ActiveSupport::TestCase
|
||||
name = Trade.build_name("buy", 0.25, "BTC")
|
||||
assert_equal "Buy 0.25 shares of BTC", name
|
||||
end
|
||||
|
||||
test "price scale is preserved at 10 decimal places" do
|
||||
security = Security.create!(ticker: "TEST", exchange_operating_mic: "XNAS")
|
||||
|
||||
# up to 10 decimal places — should persist exactly
|
||||
precise_price = BigDecimal("12.3456789012")
|
||||
trade = Trade.create!(
|
||||
security: security,
|
||||
price: precise_price,
|
||||
qty: 10000,
|
||||
currency: "USD"
|
||||
)
|
||||
|
||||
trade.reload
|
||||
|
||||
assert_equal precise_price, trade.price
|
||||
end
|
||||
|
||||
test "price is rounded to 10 decimal places" do
|
||||
security = Security.create!(ticker: "TEST", exchange_operating_mic: "XNAS")
|
||||
|
||||
# over 10 decimal places — will be rounded
|
||||
price_with_too_many_decimals = BigDecimal("1.123456789012345")
|
||||
trade = Trade.create!(
|
||||
security: security,
|
||||
price: price_with_too_many_decimals,
|
||||
qty: 1,
|
||||
currency: "USD"
|
||||
)
|
||||
|
||||
trade.reload
|
||||
|
||||
assert_equal BigDecimal("1.1234567890"), trade.price
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user