mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Universal: example parties renamed
This commit is contained in:
parent
1ceee48696
commit
c7b164897b
@ -12,7 +12,6 @@ import java.util.*
|
||||
|
||||
interface Arrangement
|
||||
|
||||
|
||||
// A base arrangement with no rights and no obligations. Contract cancellation/termination is a transition to ``Zero``.
|
||||
class Zero() : Arrangement {
|
||||
override fun hashCode(): Int {
|
||||
@ -28,11 +27,7 @@ class Zero() : Arrangement {
|
||||
//
|
||||
// todo: should be replaced with something that uses Corda assets and/or cash?
|
||||
// todo: should only be allowed to transfer non-negative amounts
|
||||
data class Transfer(val amount: Perceivable<BigDecimal>, val currency: Currency, val from: Party, val to: Party) : Arrangement {
|
||||
constructor(amount: BigDecimal, currency: Currency, from: Party, to: Party ) : this(const(amount), currency, from, to)
|
||||
constructor(amount: Amount<Currency>, from: Party, to: Party ) : this(const(BigDecimal(amount.quantity)), amount.token, from, to)
|
||||
}
|
||||
|
||||
data class Transfer(val amount: Perceivable<BigDecimal>, val currency: Currency, val from: Party, val to: Party) : Arrangement
|
||||
|
||||
// A combinator over a list of arrangements. Each arrangement in list will create a separate independent arrangement state.
|
||||
// The ``And`` combinator cannot be root in a arrangement.
|
||||
|
@ -141,7 +141,7 @@ class UniversalContract : Contract {
|
||||
is Transfer -> {
|
||||
val amount = eval(tx, arrangement.amount)
|
||||
requireThat { "transferred quantity is non-negative" by (amount >= BigDecimal.ZERO) }
|
||||
Transfer(amount, arrangement.currency, arrangement.from, arrangement.to)
|
||||
Transfer(const(amount), arrangement.currency, arrangement.from, arrangement.to)
|
||||
}
|
||||
is And -> And(arrangement.arrangements.map { validateImmediateTransfers(tx, it) }.toSet())
|
||||
else -> arrangement
|
||||
|
@ -24,7 +24,7 @@ open class ContractBuilder {
|
||||
val contracts = mutableListOf<Arrangement>()
|
||||
|
||||
fun Party.gives(beneficiary: Party, amount: BigDecimal, currency: Currency) : Transfer {
|
||||
val c = Transfer(amount, currency, this, beneficiary)
|
||||
val c = Transfer(const(amount), currency, this, beneficiary)
|
||||
contracts.add( c )
|
||||
return c
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ class Cap {
|
||||
|
||||
val contract = arrange {
|
||||
rollOut("2016-04-01", "2017-04-01", Frequency.Quarterly) {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"exercise".anytime {
|
||||
val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("6M")), start, end)
|
||||
val fixed = interest(notional, "act/365", 0.5.bd, start, end)
|
||||
wileECoyote.gives(roadRunner, floating - fixed, currency)
|
||||
highStreetBank.gives(acmeCorp, floating - fixed, currency)
|
||||
next()
|
||||
}
|
||||
} or roadRunner.may {
|
||||
} or acmeCorp.may {
|
||||
"skip".anytime {
|
||||
next()
|
||||
}
|
||||
@ -42,15 +42,15 @@ class Cap {
|
||||
rollOut("2016-04-01", "2017-04-01", Frequency.Quarterly, object {
|
||||
val limit = variable(150.K)
|
||||
}) {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"exercise".anytime {
|
||||
val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("6M")), start, end)
|
||||
val fixed = interest(notional, "act/365", 0.5.bd, start, end)
|
||||
val payout = (floating - fixed).plus()
|
||||
wileECoyote.gives(roadRunner, payout, currency)
|
||||
highStreetBank.gives(acmeCorp, payout, currency)
|
||||
next(vars.limit to vars.limit - payout)
|
||||
}
|
||||
} or roadRunner.may {
|
||||
} or acmeCorp.may {
|
||||
"skip".anytime {
|
||||
next()
|
||||
}
|
||||
@ -67,11 +67,11 @@ class Cap {
|
||||
this `fails with` "transaction has a single command"
|
||||
|
||||
tweak {
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
||||
this `fails with` "the transaction is signed by all liable parties"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
|
@ -24,26 +24,26 @@ class Caplet {
|
||||
val currency = EUR
|
||||
|
||||
val contract = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"exercise".anytime() {
|
||||
val floating = interest(notional, "act/365", fix("LIBOR", dt, Tenor("6M")), "2016-04-01", "2016-10-01")
|
||||
val fixed = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-10-01")
|
||||
wileECoyote.gives(roadRunner, (floating - fixed).plus(), currency)
|
||||
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val contractFixed = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"exercise".anytime() {
|
||||
val floating = interest(notional, "act/365", 1.0.bd, "2016-04-01", "2016-10-01")
|
||||
val fixed = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-10-01")
|
||||
wileECoyote.gives(roadRunner, (floating - fixed).plus(), currency)
|
||||
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val contractFinal = arrange { wileECoyote.gives(roadRunner, 250.K, EUR) }
|
||||
val contractFinal = arrange { highStreetBank.gives(acmeCorp, 250.K, EUR) }
|
||||
|
||||
val stateStart = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), contract)
|
||||
|
||||
@ -60,11 +60,11 @@ class Caplet {
|
||||
this `fails with` "transaction has a single command"
|
||||
|
||||
tweak {
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
||||
this `fails with` "the transaction is signed by all liable parties"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -78,11 +78,11 @@ class Caplet {
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
this `fails with` "action must be defined"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("exercise") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -96,38 +96,38 @@ class Caplet {
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
this `fails with` "action must be defined"
|
||||
}
|
||||
|
||||
tweak {
|
||||
// wrong source
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBORx", dt, Tenor("6M")), 1.0.bd))) }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBORx", dt, Tenor("6M")), 1.0.bd))) }
|
||||
|
||||
this `fails with` "relevant fixing must be included"
|
||||
}
|
||||
|
||||
tweak {
|
||||
// wrong date
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt.plusYears(1), Tenor("6M")), 1.0.bd))) }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt.plusYears(1), Tenor("6M")), 1.0.bd))) }
|
||||
|
||||
this `fails with` "relevant fixing must be included"
|
||||
}
|
||||
|
||||
tweak {
|
||||
// wrong tenor
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("3M")), 1.0.bd))) }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("3M")), 1.0.bd))) }
|
||||
|
||||
this `fails with` "relevant fixing must be included"
|
||||
}
|
||||
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.5.bd))) }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.5.bd))) }
|
||||
|
||||
this `fails with` "output state does not reflect fix command"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.0.bd))) }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", dt, Tenor("6M")), 1.0.bd))) }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ import java.util.*
|
||||
*/
|
||||
|
||||
// Test parties
|
||||
val roadRunner = Party("Road Runner", generateKeyPair().public)
|
||||
val wileECoyote = Party("Wile E. Coyote", generateKeyPair().public)
|
||||
val porkyPig = Party("Porky Pig", generateKeyPair().public)
|
||||
val acmeCorp = Party("ACME Corporation", generateKeyPair().public)
|
||||
val highStreetBank = Party("High Street Bank", generateKeyPair().public)
|
||||
val momAndPop = Party("Mom and Pop", generateKeyPair().public)
|
||||
|
||||
val acmeCorporationHasDefaulted = DummyPerceivable<Boolean>()
|
||||
|
||||
@ -28,11 +28,11 @@ class ContractDefinition {
|
||||
|
||||
|
||||
val cds_contract = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"payout".givenThat(acmeCorporationHasDefaulted and before("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1.M, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, USD)
|
||||
}
|
||||
} or wileECoyote.may {
|
||||
} or highStreetBank.may {
|
||||
"expire".givenThat(after("2017-09-01")) {
|
||||
zero
|
||||
}
|
||||
@ -41,12 +41,12 @@ class ContractDefinition {
|
||||
|
||||
|
||||
val american_fx_option = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"exercise".anytime {
|
||||
wileECoyote.gives(roadRunner, 1.M, EUR)
|
||||
roadRunner.gives(wileECoyote, 1200.K, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, EUR)
|
||||
acmeCorp.gives(highStreetBank, 1200.K, USD)
|
||||
}
|
||||
} or wileECoyote.may {
|
||||
} or highStreetBank.may {
|
||||
"expire".givenThat(after("2017-09-01")) {
|
||||
zero
|
||||
}
|
||||
@ -55,16 +55,16 @@ class ContractDefinition {
|
||||
|
||||
|
||||
val european_fx_option = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"exercise".anytime {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1.M, EUR)
|
||||
roadRunner.gives(wileECoyote, 1200.K, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, EUR)
|
||||
acmeCorp.gives(highStreetBank, 1200.K, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
} or wileECoyote.may {
|
||||
} or highStreetBank.may {
|
||||
"expire".givenThat(after("2017-09-01")) {
|
||||
zero
|
||||
}
|
||||
|
@ -15,23 +15,23 @@ class FXSwap {
|
||||
val TEST_TX_TIME_TOO_EARLY: Instant get() = Instant.parse("2017-08-31T12:00:00.00Z")
|
||||
|
||||
val contract = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1200.K, USD)
|
||||
roadRunner.gives(wileECoyote, 1.M, EUR)
|
||||
highStreetBank.gives(acmeCorp, 1200.K, USD)
|
||||
acmeCorp.gives(highStreetBank, 1.M, EUR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val transfer1 = arrange { wileECoyote.gives(roadRunner, 1200.K, USD) }
|
||||
val transfer2 = arrange { roadRunner.gives(wileECoyote, 1.M, EUR) }
|
||||
val transfer1 = arrange { highStreetBank.gives(acmeCorp, 1200.K, USD) }
|
||||
val transfer2 = arrange { acmeCorp.gives(highStreetBank, 1.M, EUR) }
|
||||
|
||||
val outState1 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transfer1 )
|
||||
val outState2 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transfer2 )
|
||||
|
||||
val transferBad1 = arrange { wileECoyote.gives(roadRunner, 1200.K, GBP) } // wrong currency
|
||||
val transferBad2 = arrange { roadRunner.gives(wileECoyote, 900.K, EUR) } // wrong amount
|
||||
val transferBad3 = arrange { wileECoyote.gives(wileECoyote, 1.M, EUR) } // wrong party
|
||||
val transferBad1 = arrange { highStreetBank.gives(acmeCorp, 1200.K, GBP) } // wrong currency
|
||||
val transferBad2 = arrange { acmeCorp.gives(highStreetBank, 900.K, EUR) } // wrong amount
|
||||
val transferBad3 = arrange { highStreetBank.gives(highStreetBank, 1.M, EUR) } // wrong party
|
||||
|
||||
val outStateBad1 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad1 )
|
||||
val outStateBad2 = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), transferBad2 )
|
||||
@ -49,15 +49,15 @@ class FXSwap {
|
||||
this `fails with` "transaction has a single command"
|
||||
|
||||
tweak {
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
||||
this `fails with` "the transaction is signed by all liable parties"
|
||||
}
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
||||
this `fails with` "the transaction is signed by all liable parties"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey, roadRunner.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(highStreetBank.owningKey, acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -72,11 +72,11 @@ class FXSwap {
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
this `fails with` "action must be defined"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -91,11 +91,11 @@ class FXSwap {
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
this `fails with` "action must be defined"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -109,7 +109,7 @@ class FXSwap {
|
||||
output { outState2 }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(momAndPop.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "action must be authorized"
|
||||
}
|
||||
}
|
||||
@ -122,7 +122,7 @@ class FXSwap {
|
||||
output { outState2 }
|
||||
timestamp(TEST_TX_TIME_TOO_EARLY)
|
||||
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "condition must be met"
|
||||
}
|
||||
}
|
||||
@ -134,7 +134,7 @@ class FXSwap {
|
||||
output { outState1 }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "output state must match action result state"
|
||||
}
|
||||
}
|
||||
@ -147,7 +147,7 @@ class FXSwap {
|
||||
output { outStateBad2 }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "output states must match action result state"
|
||||
}
|
||||
}
|
||||
@ -160,7 +160,7 @@ class FXSwap {
|
||||
output { outState2 }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "output states must match action result state"
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ class FXSwap {
|
||||
output { outStateBad3 }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "output states must match action result state"
|
||||
}
|
||||
}
|
||||
|
@ -17,28 +17,28 @@ class Swaption {
|
||||
val coupon = 1.5.bd
|
||||
|
||||
val dreary_contract = arrange {
|
||||
(wileECoyote or roadRunner).may {
|
||||
(highStreetBank or acmeCorp).may {
|
||||
"proceed".givenThat(after("01/07/2015")) {
|
||||
wileECoyote.gives(roadRunner, libor(notional, "01/04/2015", "01/07/2015"), currency)
|
||||
roadRunner.gives(wileECoyote, interest(notional, "act/365", coupon, "01/04/2015", "01/07/2015"), currency)
|
||||
(wileECoyote or roadRunner).may {
|
||||
highStreetBank.gives(acmeCorp, libor(notional, "01/04/2015", "01/07/2015"), currency)
|
||||
acmeCorp.gives(highStreetBank, interest(notional, "act/365", coupon, "01/04/2015", "01/07/2015"), currency)
|
||||
(highStreetBank or acmeCorp).may {
|
||||
"proceed".givenThat(after("01/10/2015")) {
|
||||
wileECoyote.gives(roadRunner, libor(notional, "01/07/2015", "01/10/2015"), currency)
|
||||
roadRunner.gives(wileECoyote, interest(notional, "act/365", coupon, "01/07/2015", "01/10/2015"), currency)
|
||||
highStreetBank.gives(acmeCorp, libor(notional, "01/07/2015", "01/10/2015"), currency)
|
||||
acmeCorp.gives(highStreetBank, interest(notional, "act/365", coupon, "01/07/2015", "01/10/2015"), currency)
|
||||
|
||||
(wileECoyote or roadRunner).may {
|
||||
(highStreetBank or acmeCorp).may {
|
||||
// etc ...
|
||||
}
|
||||
}
|
||||
} or roadRunner.may {
|
||||
} or acmeCorp.may {
|
||||
"cancel".anytime {
|
||||
roadRunner.gives(wileECoyote, 10.K, USD)
|
||||
acmeCorp.gives(highStreetBank, 10.K, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
} or roadRunner.may {
|
||||
} or acmeCorp.may {
|
||||
"cancel".anytime {
|
||||
roadRunner.gives(wileECoyote, 10.K, USD)
|
||||
acmeCorp.gives(highStreetBank, 10.K, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,15 +46,15 @@ class Swaption {
|
||||
|
||||
val elegant_contract = arrange {
|
||||
rollOut("01/04/2015", "01/04/2025", Frequency.Quarterly) {
|
||||
(wileECoyote or roadRunner).may {
|
||||
(highStreetBank or acmeCorp).may {
|
||||
"proceed".givenThat(after(start)) {
|
||||
wileECoyote.gives(roadRunner, libor(notional, start, end), currency)
|
||||
roadRunner.gives(wileECoyote, interest(notional, "act/365", coupon, start, end), currency)
|
||||
highStreetBank.gives(acmeCorp, libor(notional, start, end), currency)
|
||||
acmeCorp.gives(highStreetBank, interest(notional, "act/365", coupon, start, end), currency)
|
||||
next()
|
||||
}
|
||||
} or roadRunner.may {
|
||||
} or acmeCorp.may {
|
||||
"cancel".anytime {
|
||||
roadRunner.gives(wileECoyote, 10.K, currency)
|
||||
acmeCorp.gives(highStreetBank, 10.K, currency)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,18 +66,18 @@ class Swaption {
|
||||
rollOut("01/04/2015", "01/04/2016", Frequency.Quarterly, object {
|
||||
val cap = variable(150.K)
|
||||
}) {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"exercise".givenThat(before(end)) {
|
||||
val payout = (EUR / USD - strike).plus() * notional
|
||||
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"proceed".givenThat(after(end)) {
|
||||
wileECoyote.gives(roadRunner, payout, USD)
|
||||
highStreetBank.gives(acmeCorp, payout, USD)
|
||||
next(vars.cap to vars.cap - payout)
|
||||
}
|
||||
}
|
||||
}
|
||||
} or (roadRunner or wileECoyote).may {
|
||||
} or (acmeCorp or highStreetBank).may {
|
||||
"proceedWithoutExercise".givenThat(after(end)) {
|
||||
next()
|
||||
}
|
||||
@ -89,18 +89,18 @@ class Swaption {
|
||||
rollOut("01/04/2015", "01/04/2016", Frequency.Quarterly, object {
|
||||
val uses = variable(4)
|
||||
}) {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"exercise".givenThat(before(end)) {
|
||||
val payout = (EUR / USD - strike).plus() * notional
|
||||
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"proceed".givenThat(after(end)) {
|
||||
wileECoyote.gives(roadRunner, payout, currency)
|
||||
highStreetBank.gives(acmeCorp, payout, currency)
|
||||
next(vars.uses to vars.uses - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
} or (roadRunner or wileECoyote).may {
|
||||
} or (acmeCorp or highStreetBank).may {
|
||||
"proceedWithoutExercise".givenThat(after(end)) {
|
||||
next()
|
||||
}
|
||||
|
@ -12,26 +12,26 @@ import java.time.Instant
|
||||
class ZeroCouponBond {
|
||||
|
||||
val contract = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 100.K, GBP)
|
||||
highStreetBank.gives(acmeCorp, 100.K, GBP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val contractMove = arrange {
|
||||
(porkyPig or wileECoyote).may {
|
||||
(momAndPop or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(porkyPig, 100.K, GBP)
|
||||
highStreetBank.gives(momAndPop, 100.K, GBP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
|
||||
|
||||
val transfer = arrange { wileECoyote.gives(roadRunner, 100.K, GBP) }
|
||||
val transferWrong = arrange { wileECoyote.gives(roadRunner, 80.K, GBP) }
|
||||
val transfer = arrange { highStreetBank.gives(acmeCorp, 100.K, GBP) }
|
||||
val transferWrong = arrange { highStreetBank.gives(acmeCorp, 80.K, GBP) }
|
||||
|
||||
val inState = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), contract )
|
||||
|
||||
@ -55,11 +55,11 @@ class ZeroCouponBond {
|
||||
this `fails with` "transaction has a single command"
|
||||
|
||||
tweak {
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
||||
this `fails with` "the transaction is signed by all liable parties"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -73,11 +73,11 @@ class ZeroCouponBond {
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
tweak {
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||
this `fails with` "action must be defined"
|
||||
}
|
||||
|
||||
command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
|
||||
this.verifies()
|
||||
}
|
||||
@ -90,7 +90,7 @@ class ZeroCouponBond {
|
||||
output { outState }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(momAndPop.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "action must be authorized"
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ class ZeroCouponBond {
|
||||
output { outStateWrong }
|
||||
timestamp(TEST_TX_TIME_1)
|
||||
|
||||
command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
command(acmeCorp.owningKey) { UniversalContract.Commands.Action("execute") }
|
||||
this `fails with` "output state must match action result state"
|
||||
}
|
||||
}
|
||||
@ -114,24 +114,24 @@ class ZeroCouponBond {
|
||||
|
||||
tweak {
|
||||
output { outStateMove }
|
||||
command(roadRunner.owningKey) {
|
||||
UniversalContract.Commands.Move(roadRunner, porkyPig)
|
||||
command(acmeCorp.owningKey) {
|
||||
UniversalContract.Commands.Move(acmeCorp, momAndPop)
|
||||
}
|
||||
this `fails with` "the transaction is signed by all liable parties"
|
||||
}
|
||||
|
||||
tweak {
|
||||
output { inState }
|
||||
command(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) {
|
||||
UniversalContract.Commands.Move(roadRunner, porkyPig)
|
||||
command(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey) {
|
||||
UniversalContract.Commands.Move(acmeCorp, momAndPop)
|
||||
}
|
||||
this `fails with` "output state does not reflect move command"
|
||||
}
|
||||
|
||||
output { outStateMove}
|
||||
|
||||
command(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) {
|
||||
UniversalContract.Commands.Move(roadRunner, porkyPig)
|
||||
command(acmeCorp.owningKey, momAndPop.owningKey, highStreetBank.owningKey) {
|
||||
UniversalContract.Commands.Move(acmeCorp, momAndPop)
|
||||
}
|
||||
this.verifies()
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ import java.util.*
|
||||
// various example arrangements using basic syntax
|
||||
|
||||
val cds_contract = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"claim".givenThat(acmeCorporationHasDefaulted and before("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1.M, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,29 +24,29 @@ val cds_contract = arrange {
|
||||
// fx swap
|
||||
// both parties have the right to trigger the exchange of cash flows
|
||||
val an_fx_swap = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1200.K, USD)
|
||||
roadRunner.gives(wileECoyote, 1.M, EUR)
|
||||
highStreetBank.gives(acmeCorp, 1200.K, USD)
|
||||
acmeCorp.gives(highStreetBank, 1.M, EUR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val american_fx_option = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"exercise".givenThat(before("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1200.K, USD)
|
||||
roadRunner.gives(wileECoyote, 1.M, EUR)
|
||||
highStreetBank.gives(acmeCorp, 1200.K, USD)
|
||||
acmeCorp.gives(highStreetBank, 1.M, EUR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val european_fx_option = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"exercise".givenThat(before("2017-09-01")) {
|
||||
fx_swap("2017-09-01", 1.M, 1.2.bd, EUR, USD, roadRunner, wileECoyote)
|
||||
fx_swap("2017-09-01", 1.M, 1.2.bd, EUR, USD, acmeCorp, highStreetBank)
|
||||
}
|
||||
} or (roadRunner or wileECoyote).may {
|
||||
} or (acmeCorp or highStreetBank).may {
|
||||
"expire".anytime {
|
||||
zero
|
||||
}
|
||||
@ -54,18 +54,18 @@ val european_fx_option = arrange {
|
||||
}
|
||||
|
||||
val zero_coupon_bond_1 = arrange {
|
||||
roadRunner.may {
|
||||
acmeCorp.may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1.M, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maybe in the presence of negative interest rates you would want other side of contract to be able to take initiative as well
|
||||
val zero_coupon_bond_2 = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1.M, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,23 +80,23 @@ val zero_coupon_bond_2 = arrange {
|
||||
// Assume observable is using FX fixing
|
||||
//
|
||||
val no_touch = arrange {
|
||||
(roadRunner or wileECoyote).may {
|
||||
(acmeCorp or highStreetBank).may {
|
||||
"execute".givenThat(after("2017-09-01")) {
|
||||
wileECoyote.gives(roadRunner, 1.M, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, USD)
|
||||
}
|
||||
} or wileECoyote.may {
|
||||
} or highStreetBank.may {
|
||||
"knock out".givenThat(EUR/USD gt 1.3)
|
||||
}
|
||||
}
|
||||
|
||||
val one_touch = arrange {
|
||||
wileECoyote.may {
|
||||
highStreetBank.may {
|
||||
"expire".givenThat(after("2017-09-01")) {
|
||||
zero
|
||||
}
|
||||
} or roadRunner.may {
|
||||
} or acmeCorp.may {
|
||||
"knock in".givenThat(EUR / USD gt 1.3) {
|
||||
wileECoyote.gives(roadRunner, 1.M, USD)
|
||||
highStreetBank.gives(acmeCorp, 1.M, USD)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user