/ SimMode / src / debug.jl
debug.jl
  1  using .OrderTypes: LimitOrderType, ordertype
  2  
  3  const CTR = Ref(0)
  4  const CTO = Ref(0)
  5  const PRICE_CHECKS = Ref(0)
  6  const VOL_CHECKS = Ref(0)
  7  const cash_tracking = Float64[]
  8  _vv(v) = v isa Vector ? v[] : v
  9  function _showcash(s, ai)
 10      @show s.cash s.cash_committed cash(ai) committed(ai)
 11  end
 12  function _showorder(o)
 13      display(("price: ", o.price))
 14      display(("comm: ", _vv(o.attrs.committed)))
 15      display(("unfill: ", _vv(o.attrs.unfilled)))
 16      display(("amount: ", o.amount))
 17      display(("trades: ", length(o.attrs.trades)))
 18  end
 19  function _globals()
 20      @show PRICE_CHECKS VOL_CHECKS CTR CTO
 21      nothing
 22  end
 23  function _resetglobals!(s)
 24      CTR[] = 0
 25      CTO[] = 0
 26      PRICE_CHECKS[] = 0
 27      VOL_CHECKS[] = 0
 28      empty!(cash_tracking)
 29      s[:debug_afterorder] = _afterorder
 30      s[:debug_beforetrade] = _beforetrade
 31      s[:debug_aftertrade] = _aftertrade
 32      s[:debug_check_committments] = _check_committments
 33  end
 34  function _afterorder()
 35      CTO[] += 1
 36  end
 37  function _beforetrade(s, ai, o, trade, actual_price)
 38      @assert trade.size != 0.0 "Trade must not be empty, size was $(trade.size)."
 39      CTR[] += 1
 40      push!(cash_tracking, actual_price)
 41      get(s.attrs, :verbose, false) || return nothing
 42      _showcash(s, ai)
 43      _showorder(o)
 44  end
 45  
 46  function _aftertrade(s, ai, o)
 47      get(s.attrs, :verbose, false) || return nothing
 48      _showorder(o)
 49      _showcash(s, ai)
 50      println("\n")
 51      get(s.attrs, :debug_maxtrades, Inf) == CTR[] && error()
 52  end
 53  
 54  function _check_committments(s::Strategy, ai)
 55      cash_comm = 0.0
 56      n = 0
 57      for (_, ords) in s.buyorders
 58          for (_, o) in ords
 59              o isa ShortBuyOrder && continue
 60              # cash_comm = toprecision(cash_comm + committed(o), s.cash.precision)
 61              cash_comm = cash_comm + committed(o)
 62              n += 1
 63          end
 64      end
 65      for (_, ords) in s.sellorders
 66          for (_, o) in ords
 67              if o isa ShortSellOrder
 68                  # cash_comm = toprecision(cash_comm + committed(o), s.cash.precision)
 69                  cash_comm = cash_comm + committed(o)
 70                  n +=1
 71              end
 72          end
 73      end
 74      @assert if orderscount(s) == 0
 75          iszero(cash_comm) && approxzero(s.cash_committed)
 76      else
 77          # NOTE: committment is imprecise when using fees overrides
 78          isapprox(cash_comm, s.cash_committed, atol=2s.cash_committed.precision) || haskey(s.attrs, :sim_fees)
 79      end  (; cash_comm, s.cash_committed.value, ai, n)
 80  end
 81  
 82  function _check_committments(s, ai::AssetInstance, t::Trade)
 83      get(s.attrs, :verbose, false) && begin
 84          @show (@something ai.longpos ai).cash_committed
 85          @show (@something ai.shortpos ai).cash_committed
 86      end
 87      orders_long = 0.0
 88      orders_short = 0.0
 89      for (_, o) in orders(s, ai, positionside(t)())
 90          @assert o.asset == ai.asset
 91          if o isa SellOrder
 92              @assert positionside(o) == Long o
 93              orders_long += committed(o)
 94          elseif o isa ShortBuyOrder
 95              @assert positionside(o) == Short o
 96              orders_short += committed(o)
 97          end
 98      end
 99      asset_long = committed(ai, Long())
100      asset_short = committed(ai, Short())
101      if t isa ShortBuyTrade
102          asset_short -= committed(t.order)
103      end
104      @assert isapprox(orders_long, asset_long, atol=1e-6) (; orders_long, asset_long, Long)
105      @assert isapprox(orders_short, asset_short, atol=1e-6) (;
106          orders_short, asset_short, Short
107      ),
108      collect(values(s.sellorders[ai]))
109  end