Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added lifecycle test example for IbericoPig #31

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

judywu-da
Copy link
Collaborator

Hello Financial Engineering team,
I am playing around with the FinLib 2.0 and as suggested by @georg-da, I tried to create an example to model the lifecycle of processed food. I wrote this example using IbericoPig: the cycle from Pig to Ham (details of the flow is drafted in the comment
I used FixRate Bond as an example to follow, yet I found that it does not seem to fit with the flow where we need Timed Event.
I wonder if anyone can kindly provide me a direction to better rewrite this flow.

getClaimFromState targetState =
scale (Observe (show targetState)) $ one cashInstrumentCid -- todo as it turn out I cannot put target as Observable

-- getRemainingClaims: [Claim Date Decimal Deliverable Text] -- todo how have all claims for remaining state in pig
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally, I tried to model the claims in IbericoPig to have all remaining claims depending on remaining State.
E.g. When the pig is in Butchered State it should have claims for Food Processor Selling To Restaurant, and Restaurant Selling To customer. However, it seems hard to do so, as I have no Timed Event in the flow. So I have to model it as: when the pig is in Butchered State, there's only one claim FoodProcessor Selling To Restaurant (only one claim for transitioning to next State)


getClaimFromState: State -> Claim Date Decimal Deliverable Text -- todo I don't really need time/date
getClaimFromState targetState =
scale (Observe (show targetState)) $ one cashInstrumentCid -- todo as it turn out I cannot put target as Observable
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the constraint in C type which is Claim Date Decimal Deliverable Text I cannot use my State type to denote the Observable

let
instrumentKey = InstrumentKey with depository = farmer; issuer = farmer; id

getClaimFromState: State -> Claim Date Decimal Deliverable Text -- todo I don't really need time/date
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the flow, I don't really need TimedEvent, I am using StateTransitionEvent, which can happen any time.
I feel like I am doing the wrong thing try to model this kind of non TimedEvent with HasClaim interface

Copy link
Contributor

@matteolimberto-da matteolimberto-da Aug 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that contingent claims is a powerful modelling framework to describe a payoff that depends on

  • time
  • elections from one of the parties

In the Iberico example most transitions from one state to the next do not depend on either time or election, which makes the framework less powerful as most contracts are of type one pig or one pigLeg.

Where I could see time kicking in is in the aging process, where I assume that the longer meat is aged, the more valuable it becomes.

You could see this as a contract anytime (t >= start) [ Give (one ham) and scale ( appreciationFunction (one USD) ) where appreciationFunction is an increasing function of time.

The party aging the meat can choose when to deliver meat in exchange for cash. The cash payout will depend on how long the meat has been aged.

pure [taggedClaim tag claims]


mapClaimToUTCTime : Claim Date Decimal Deliverable Text -> C
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot avoid this redundant conversion, even when I don't really need time constraint on claim

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get rid of that conversion by changing the signature of getClaimFromState from State -> Claim Date Decimal Deliverable Text to State -> Claim Time Decimal Deliverable Text.

There shouldn't be any other change required given that time is currently not being used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes you are totally right! thanks for the tip

with
custodian = bank
owner = farmer
claimers = S.singleton farmer -- Can I make new instrument go into butcher's account? No, not in the current rule implementation
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current SettlementRule does not seem to allow producedInstrument to go to other people's account (it will always use the account of targetInstrument)
Should I

  1. use produced in the Effect instead
  2. create a different SettlementRule implementation

Copy link
Contributor

@matteolimberto-da matteolimberto-da Aug 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is right, currently each holding identifies

  • a custodian
  • an owner

and the life-cycling of an instrument does not change them. This is handled in a separate step (via Dvps).

I feel this represents what happens with the iberico in the real world, e.g.:

  • farmer sells pig to butcher in exchange for cash (this is just a trade, the pig instrument does not change)
  • butcher butchers the pig and produces unprocessed ham. This is the lifecycling event (pig changes to ham), owner on the holding does not change (it is still the butcher)
  • butcher sells unprocessed meat to food processor (transfer)
  • ...

In order to atomically do the lifecycling + transfer, you would need to wrap the SettlementRule in another rule contract taking care of the Transfer part.

[paymentForPigInstructionCid] = result.instructionCids
paymentBatchForPigCid = result.containerCid

-- can we setup instruction for butcher to pay farmer not for bank to pay farmer? No, not in the current rule implementation
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For farmer selling Pig to Butcher, the settlement instruction should really be butcher paying cash to farmer via bank, not bank to farmer directly. Yet I am not sure how to properly set up the instruction with current implementation of SettlementRule.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is indeed not possible currently (see my other comment) as lifecycle events are between custodian and owner.


getClaimFromState: State -> Claim Date Decimal Deliverable Text -- todo I don't really need time/date
getClaimFromState targetState =
scale (Observe (show targetState)) $ one cashInstrumentCid -- todo as it turn out I cannot put target as Observable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scale is used to scale an asset (in this case the cash instrument) by a numerical amount. In this case, targetState does not seem to be a numerical amount.

@matteolimberto-da
Copy link
Contributor

Pretty cool example, although I just had lunch you still made me crave for some iberico :)

Some suggestions that came to my mind to re-write the flow based on the current state of the library:

  • decouple lifecycle events from holding transfers (see one of my comments in that regard)
  • you probably do not need contingent claims if your payoff does not have a time dependency (which seems to be the case for most of the flow except aging)

Some extra ideas:

  • You could consider having a different custodian for the cash holdings (the bank) and the pig holdings (for instance, an authority that guarantees traceability and authenticity of the food).
  • You can think whether your holdings should be fungible or non-fungible and use the corresponding holding implementation. If you want to guarantee traceability at the single pig level, each pig and pig-leg would be different instruments with non-fungible holdings. Otherwise, you could make pigs and unprocessed ham fungible, but aged ham non-fungible, ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants