utils.jl
1 using .Instances: ispos 2 using .OrderTypes: ByPos 3 using .Lang: @caller 4 5 @doc """ Returns a generator for orders matching a given position side and order side 6 7 $(TYPEDSIGNATURES) 8 9 This function iterates over the orders of a strategy, returning only those that match the provided position side and order side. 10 11 """ 12 orders(s::Strategy, ai, pos::PositionSide, os::Type{<:OrderSide}) 13 function orders(s::Strategy, ai, pos::PositionSide, os::Type{<:OrderSide}) 14 (tup for tup in orders(s, ai, os) if ispos(pos, tup.second)) 15 end 16 function orders(s::Strategy, ai, pos::PositionSide) 17 (tup for bs in (Buy, Sell) for tup in orders(s, ai, pos, bs)) 18 end 19 @doc """ Returns a generator for orders matching a given position side 20 21 $(TYPEDSIGNATURES) 22 23 This function iterates over the orders of a strategy for both Buy and Sell sides, returning those that match the provided position side. 24 25 """ 26 orders(s::Strategy, ai, pos::PositionSide) 27 @doc """ Returns a generator for short orders matching a given order side 28 29 $(TYPEDSIGNATURES) 30 31 This function utilizes the orders function to generate orders for the Short position side that match the provided order side. 32 33 """ 34 shortorders(s::Strategy, ai, os::Type{<:OrderSide}) = orders(s, ai, Short(), os) 35 @doc """ Returns a generator for long orders matching a given order side 36 37 $(TYPEDSIGNATURES) 38 39 This function utilizes the orders function to generate orders for the Long position side that match the provided order side. 40 41 """ 42 longorders(s::Strategy, ai, os::Type{<:OrderSide}) = orders(s, ai, Long(), os) 43 function shortorders(s::Strategy, ai) 44 (orders(s, ai, Short(), Sell)..., orders(s, ai, Short(), Buy)...) 45 end 46 function longorders(s::Strategy, ai) 47 (orders(s, ai, Long(), Buy)..., orders(s, ai, Long(), Sell)...) 48 end 49 50 function _hasorders(s::MarginStrategy, ai, ps::PositionSide, os::Type{<:OrderSide}) 51 for o in values(orders(s, ai, os)) 52 if positionside(o)() == ps 53 return true 54 end 55 end 56 return false 57 end 58 @doc """ Checks if there are any orders for a given position side 59 60 $(TYPEDSIGNATURES) 61 62 This function checks both Buy and Sell sides for any orders that match the provided position side in the Margin Strategy. 63 64 """ 65 function hasorders(s::MarginStrategy, ai, ps::PositionSide) 66 _hasorders(s, ai, ps, Buy) || _hasorders(s, ai, ps, Sell) 67 end 68 function hasorders(s::MarginStrategy, ai, ::Long, t::Type{<:OrderSide}) 69 hasorders(s, ai, t) 70 end 71 function hasorders(s::MarginStrategy, ai, ::Long, ::Type{Sell}) 72 _hasorders(s, ai, Long(), Sell) 73 end 74 function hasorders(s::MarginStrategy, ai, ::Short, ::Type{Buy}) 75 _hasorders(s, ai, Short(), Buy) 76 end 77 78 # NOTE: ByPos has higher priority than BySide for dispatching 79 @assert !hasmethod(hasorders, Tuple{MarginStrategy, AssetInstance, BySide}) 80 function hasorders(s::MarginStrategy, ai, ::ByPos{Long}) 81 hasorders(s, ai, Long(), Buy) || hasorders(s, ai, Long(), Sell) 82 end 83 function hasorders(s::MarginStrategy, ai, ::ByPos{Short}) 84 _hasorders(s, ai, Short(), Buy) || _hasorders(s, ai, Short(), Sell) 85 end 86 87 function hasorders(s::MarginStrategy, ::ByPos{P}) where {P<:PositionSide} 88 for ai in s.holdings 89 _hasorders(s, ai, P(), Buy) && return true 90 _hasorders(s, ai, P(), Sell) && return true 91 end 92 return false 93 end 94 95 function hasorders(s::MarginStrategy, ::ByPos{P}, ::Val{:universe}) where {P<:PositionSide} 96 for ai in universe(s) 97 _hasorders(s, ai, P(), Buy) && return true 98 _hasorders(s, ai, P(), Sell) && return true 99 end 100 return false 101 end 102 @doc """ Updates the position of the isolated strategy to the given position side at the specified date 103 104 $(TYPEDSIGNATURES) 105 106 This function updates the position of the strategy for the asset in question at the given date to the provided position side. 107 108 """ 109 function position!(s::IsolatedStrategy, ai, date::DateTime, p::PositionSide) 110 position!(s, ai, date, position(ai, p)) 111 end 112 position!(::IsolatedStrategy, ai, ::DateTime, ::Nothing) = nothing 113 114 position!(s::Strategy, args...) = @warn "`position!` not implemented for $(typeof(s))" @caller 115 116 @doc "Non margin strategies don't have positions." 117 position!(s::NoMarginStrategy, args...; kwargs...) = nothing 118 positions!(s::NoMarginStrategy, args...; kwargs...) = nothing 119 120 _commitside(::Long) = Sell 121 _commitside(::Short) = Buy 122 @doc """ Calculates the committed amount for a given position 123 124 $(TYPEDSIGNATURES) 125 126 This function sums the amounts of all the orders that match the given position in the Margin Strategy. 127 128 """ 129 function committed(s::MarginStrategy, ai::MarginInstance, ::ByPos{P}) where {P} 130 ans = zero(DFT) 131 for o in values(s, ai, P(), _commitside(P())) 132 ans += o.amount 133 end 134 ans 135 end