> Christopher: I think it might make sense to break out TermStructure and > pass it into your methods as an independent object. If you find yourself > "mixing and matching" pricing engines and term structures, then that sounds > to me like you should be making use of multiple dispatch. If a bond always > has the same pricing engine and term structure, then a parametric type > might make more sense. It really comes down to whether the internal types > will need to change.
It also occured to me that changing the PricingEngine underneath a Bond and invalidating all the cached fields, like nvp below, is very error prone. It is probably better to have it immutable to just make a new instance once the PricingEngine changes. > On Tue, Feb 2, 2016 at 1:49 AM, Mauro <mauro...@runbox.com> wrote: > >> I haven't been following this thread closely, so I have no frame of >> reference here, I'm like a child who wanders into the middle of a >> julia-users thread... >> >> A few observations: >> >> - functions being called with composite types which have some >> non-concrete fields suffer no performance penalty, as long as you >> don't use those non-concrete fields >> - if using a non-concrete field, you can use kernel >> functions (aka barrier funciton): >> >> http://docs.julialang.org/en/release-0.4/manual/performance-tips/#separate-kernel-functions >> The kernel fn could be what Tom suggested >> >> nvp(myBond) = isdefined(myBond, :nvp_val) ? myBond.nvp_val :_nvp!(myBond, >> myBond.pricingEngine) >> >> _nvp!(bond, pe:PricingEngine1) = ... # writes to nvp_val field and returns >> it >> _nvp!(bond, pe:PricingEngine2) = ... >> >> On Tue, 2016-02-02 at 00:41, Christopher Alexander <uvapa...@gmail.com> >> wrote: >> > I've been trying to think of a way to implement this, but I'm having some >> > trouble. Perhaps this can be a discussion around organizing objects in >> > Julia to best exploit the benefits of multiple dispatch. Let's say I >> have >> > a Bond type: >> > >> > type Bond{P <: PricingEngine} >> > # some attributes here >> > pricingEngine::P >> > end >> > >> > >> > Then the particular PricingEngine object for each instantiation of "Bond" >> > has its own term structure (perhaps this could be stored with the bond >> > itself?). Each PricingEngine sub type (in my code PricingEngine is >> > actually an abstract type itself) has its own calculation method, where >> > various components of the bond are calculated (e.g. NPV, etc). I suppose >> > this could be separated out, but I essentially want to provide to the end >> > user something like npv(myBond). The bond knows whether it's been >> > calculated or not, and if it hasn't, it does so via its pricing engine. >> > Otherwise, it returns a cached value of its NPV (already having been >> > calculated). If I break all of these things out (bond/instrument, term >> > structure, and pricing engine), I would envision a method like this: >> > npv(bond, pricing_engine, term_structure) >> > >> > Is there a better/more "Julian" way to organize this? Perhaps keeping >> the >> > TermStructure separate from everyone and passing it into methods where I >> > need it? >> > >> > >> > On Monday, February 1, 2016 at 5:05:21 PM UTC-5, Tom Breloff wrote: >> >> >> >> Just so you realize... in this example "pricingEngine" has an abstract >> >> type, and you've possibly lost whatever performance gain you were hoping >> >> for in your original question. To solve you either need to take the >> same >> >> approach in defining and updating the Bond object, or maybe rethink how >> >> you're doing this. You should consider utilizing multiple dispatch a >> >> little more keep your PricingEngine and TermStructure separate: >> >> >> >> do_something(engine::PricingEngine, term::TermStructure) = ... >> >> >> >> >> >> >> >> On Mon, Feb 1, 2016 at 2:07 PM, Christopher Alexander < >> uvap...@gmail.com >> >> <javascript:>> wrote: >> >> >> >>> This doesn't seem to work if your PricingEngine object is attached to >> >>> some other object. Like, for example if you have: >> >>> >> >>> type Bond >> >>> pricingEngine::PricingEngine >> >>> end >> >>> >> >>> >> >>> myPE = PricingEngine(4.5, 5.5, TermStructureA()) >> >>> >> >>> >> >>> myBond = Bond(myPE) >> >>> >> >>> >> >>> myPE = update_ts(myPE, TermStructureB()) >> >>> >> >>> >> >>> At that point, myBond's pricing engine still points to the older myPE >> >>> with TermStructureA. >> >>> >> >>> On Monday, February 1, 2016 at 1:58:54 PM UTC-5, Christopher Alexander >> >>> wrote: >> >>>> >> >>>> So something like: >> >>>> >> >>>> function update_ts(pe::PricingEngine, newTS::TermStructure) >> >>>> newPE = PricingEngine(pe.varA, pe.varB, newTS) >> >>>> return newPE >> >>>> end >> >>>> >> >>>> >> >>>> myPE = PricingEngine(4.5, 5.5, TermStructureA()) >> >>>> >> >>>> >> >>>> myPE = update_ts(myPE, TermStructureB()) >> >>>> >> >>>> You probably wouldn't be able to update the "myPE" object in place >> right >> >>>> (i.e. updating it in the actual update_ts method and then returning >> itself)? >> >>>> >> >>>> >> >>>> On Monday, February 1, 2016 at 1:50:41 PM UTC-5, Tom Breloff wrote: >> >>>>> >> >>>>> You could just construct a new object with the new TermStructure, >> >>>>> instead of overwriting the old one. >> >>>>> >> >>>>> On Mon, Feb 1, 2016 at 1:27 PM, Christopher Alexander < >> >>>>> uvap...@gmail.com> wrote: >> >>>>> >> >>>>>> Hello all, I have a question about the usage of parametric types. I >> >>>>>> know these bring about a performance boost (at least that was my >> >>>>>> understanding), but I have a situation where I have a parametric >> type >> >>>>>> defined as such: >> >>>>>> >> >>>>>> type PricingEngine{T <: TermStructure} >> >>>>>> varA::Float64 >> >>>>>> varB::Float64 >> >>>>>> ts::T >> >>>>>> end >> >>>>>> >> >>>>>> >> >>>>>> But then I need to actually swap the existing term structure with >> >>>>>> another subtype of TermStructure further down the road. Using >> parametric >> >>>>>> types, it complains because I guess it's locked in to using whatever >> >>>>>> TermStructure sub type is initially there when I instantiate the >> >>>>>> PricingEngine type. Is there anyway to do such an update while >> still using >> >>>>>> a type parameter, or am I stuck just with a definition that uses the >> >>>>>> broader abstract type? >> >>>>>> >> >>>>>> Thanks! >> >>>>>> >> >>>>>> Chris >> >>>>>> >> >>>>> >> >>>>> >> >> >>