mirror of
https://github.com/corda/corda.git
synced 2025-02-06 11:09:18 +00:00
Universal: checkpoint before refactor
This commit is contained in:
parent
dab883dcba
commit
b93aa71afa
@ -4,6 +4,7 @@ import com.r3corda.core.contracts.Amount
|
|||||||
import com.r3corda.core.contracts.Frequency
|
import com.r3corda.core.contracts.Frequency
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
import java.time.LocalDate
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,7 +50,7 @@ data class Or(val actions: Set<Action>) : Arrangement
|
|||||||
|
|
||||||
|
|
||||||
// Roll out of arrangement
|
// Roll out of arrangement
|
||||||
data class RollOut(val startDate: String, val endDate: String, val frequency: Frequency, val template: Arrangement) : Arrangement
|
data class RollOut(val startDate: LocalDate, val endDate: LocalDate, val frequency: Frequency, val template: Arrangement) : Arrangement
|
||||||
|
|
||||||
|
|
||||||
// Continuation of roll out
|
// Continuation of roll out
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.r3corda.contracts.universal
|
package com.r3corda.contracts.universal
|
||||||
|
|
||||||
|
import com.r3corda.core.contracts.BusinessCalendar
|
||||||
import com.r3corda.core.contracts.Tenor
|
import com.r3corda.core.contracts.Tenor
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -44,14 +45,16 @@ class EndDate : Perceivable<Instant>
|
|||||||
*/
|
*/
|
||||||
data class TimePerceivable(val cmp: Comparison, val instant: Perceivable<Instant>) : Perceivable<Boolean>
|
data class TimePerceivable(val cmp: Comparison, val instant: Perceivable<Instant>) : Perceivable<Boolean>
|
||||||
|
|
||||||
fun parseDate(str: String) = Instant.parse(str+"T00:00:00Z")!!
|
fun parseDate(str: String) = BusinessCalendar.parseDateFromString(str)
|
||||||
|
|
||||||
|
// Instant.parse(str+"T00:00:00Z")!!
|
||||||
|
|
||||||
fun before(expiry: Perceivable<Instant>) = TimePerceivable(Comparison.LTE, expiry)
|
fun before(expiry: Perceivable<Instant>) = TimePerceivable(Comparison.LTE, expiry)
|
||||||
fun after(expiry: Perceivable<Instant>) = TimePerceivable(Comparison.GTE, expiry)
|
fun after(expiry: Perceivable<Instant>) = TimePerceivable(Comparison.GTE, expiry)
|
||||||
fun before(expiry: Instant) = TimePerceivable(Comparison.LTE, const(expiry))
|
fun before(expiry: Instant) = TimePerceivable(Comparison.LTE, const(expiry))
|
||||||
fun after(expiry: Instant) = TimePerceivable(Comparison.GTE, const(expiry))
|
fun after(expiry: Instant) = TimePerceivable(Comparison.GTE, const(expiry))
|
||||||
fun before(expiry: String) = TimePerceivable(Comparison.LTE, const(parseDate(expiry)))
|
fun before(expiry: String) = TimePerceivable(Comparison.LTE, const(parseDate(expiry).toInstant()))
|
||||||
fun after(expiry: String) = TimePerceivable(Comparison.GTE, const(parseDate(expiry)))
|
fun after(expiry: String) = TimePerceivable(Comparison.GTE, const(parseDate(expiry).toInstant()))
|
||||||
|
|
||||||
data class PerceivableAnd(val left: Perceivable<Boolean>, val right: Perceivable<Boolean>) : Perceivable<Boolean>
|
data class PerceivableAnd(val left: Perceivable<Boolean>, val right: Perceivable<Boolean>) : Perceivable<Boolean>
|
||||||
infix fun Perceivable<Boolean>.and(obs: Perceivable<Boolean>) = PerceivableAnd(this, obs)
|
infix fun Perceivable<Boolean>.and(obs: Perceivable<Boolean>) = PerceivableAnd(this, obs)
|
||||||
@ -102,23 +105,23 @@ class DummyPerceivable<T> : Perceivable<T>
|
|||||||
|
|
||||||
// todo: holidays
|
// todo: holidays
|
||||||
data class Interest(val amount: Perceivable<BigDecimal>, val dayCountConvention: String,
|
data class Interest(val amount: Perceivable<BigDecimal>, val dayCountConvention: String,
|
||||||
val interest: Perceivable<BigDecimal>, val start: LocalDate, val end: LocalDate) : Perceivable<BigDecimal>
|
val interest: Perceivable<BigDecimal>, val start: Perceivable<Instant>, val end: Perceivable<Instant>) : Perceivable<BigDecimal>
|
||||||
|
|
||||||
fun libor(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") start: String, @Suppress("UNUSED_PARAMETER") end: String) : Perceivable<BigDecimal> = DummyPerceivable()
|
fun libor(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") start: String, @Suppress("UNUSED_PARAMETER") end: String) : Perceivable<BigDecimal> = DummyPerceivable()
|
||||||
fun libor(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") start: Perceivable<Instant>, @Suppress("UNUSED_PARAMETER") end: Perceivable<Instant>) : Perceivable<BigDecimal> = DummyPerceivable()
|
fun libor(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") start: Perceivable<Instant>, @Suppress("UNUSED_PARAMETER") end: Perceivable<Instant>) : Perceivable<BigDecimal> = DummyPerceivable()
|
||||||
|
|
||||||
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: BigDecimal /* todo - appropriate type */,
|
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: BigDecimal /* todo - appropriate type */,
|
||||||
@Suppress("UNUSED_PARAMETER") start: String, @Suppress("UNUSED_PARAMETER") end: String) : Perceivable<BigDecimal> = Interest(Const(amount), dayCountConvention, Const(interest), parseDate(start).toLocalDate(), parseDate(end).toLocalDate())
|
@Suppress("UNUSED_PARAMETER") start: String, @Suppress("UNUSED_PARAMETER") end: String) : Perceivable<BigDecimal> = Interest(Const(amount), dayCountConvention, Const(interest), const(parseDate(start).toInstant()), const(parseDate(end).toInstant()))
|
||||||
|
|
||||||
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: Perceivable<BigDecimal> /* todo - appropriate type */,
|
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: Perceivable<BigDecimal> /* todo - appropriate type */,
|
||||||
@Suppress("UNUSED_PARAMETER") start: String, @Suppress("UNUSED_PARAMETER") end: String) : Perceivable<BigDecimal> =
|
@Suppress("UNUSED_PARAMETER") start: String, @Suppress("UNUSED_PARAMETER") end: String) : Perceivable<BigDecimal> =
|
||||||
Interest(Const(amount), dayCountConvention, interest, parseDate(start).toLocalDate(), parseDate(end).toLocalDate())
|
Interest(Const(amount), dayCountConvention, interest, const(parseDate(start).toInstant()), const(parseDate(end).toInstant()))
|
||||||
|
|
||||||
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: BigDecimal /* todo - appropriate type */,
|
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: BigDecimal /* todo - appropriate type */,
|
||||||
@Suppress("UNUSED_PARAMETER") start: Perceivable<Instant>, @Suppress("UNUSED_PARAMETER") end: Perceivable<Instant>) : Perceivable<BigDecimal> = DummyPerceivable()
|
@Suppress("UNUSED_PARAMETER") start: Perceivable<Instant>, @Suppress("UNUSED_PARAMETER") end: Perceivable<Instant>) : Perceivable<BigDecimal> = DummyPerceivable()
|
||||||
|
|
||||||
fun interest(@Suppress("UNUSED_PARAMETER") rate: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: Perceivable<BigDecimal> /* todo - appropriate type */,
|
fun interest(@Suppress("UNUSED_PARAMETER") amount: BigDecimal, @Suppress("UNUSED_PARAMETER") dayCountConvention: String, @Suppress("UNUSED_PARAMETER") interest: Perceivable<BigDecimal> /* todo - appropriate type */,
|
||||||
@Suppress("UNUSED_PARAMETER") start: Perceivable<Instant>, @Suppress("UNUSED_PARAMETER") end: Perceivable<Instant>) : Perceivable<BigDecimal> = DummyPerceivable()
|
@Suppress("UNUSED_PARAMETER") start: Perceivable<Instant>, @Suppress("UNUSED_PARAMETER") end: Perceivable<Instant>) : Perceivable<BigDecimal> = Interest(const(amount), dayCountConvention, interest, start, end)
|
||||||
|
|
||||||
class Fixing(val source: String, val date: Perceivable<Instant>, val tenor: Tenor) : Perceivable<BigDecimal>
|
class Fixing(val source: String, val date: Perceivable<Instant>, val tenor: Tenor) : Perceivable<BigDecimal>
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.r3corda.core.contracts.*
|
|||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.crypto.SecureHash
|
import com.r3corda.core.crypto.SecureHash
|
||||||
import com.r3corda.core.transactions.TransactionBuilder
|
import com.r3corda.core.transactions.TransactionBuilder
|
||||||
|
import com.sun.tools.corba.se.idl.InvalidArgument
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -39,19 +40,11 @@ class UniversalContract : Contract {
|
|||||||
class Issue : TypeOnlyCommandData(), Commands
|
class Issue : TypeOnlyCommandData(), Commands
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> eval(@Suppress("UNUSED_PARAMETER") tx: TransactionForContract, expr: Perceivable<T>): T = when (expr) {
|
|
||||||
is Const -> expr.value
|
|
||||||
else -> throw Error("Unable to evaluate")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun eval(@Suppress("UNUSED_PARAMETER") tx: TransactionForContract, expr: Perceivable<LocalDate>): LocalDate = when (expr) {
|
|
||||||
is Const -> expr.value
|
|
||||||
else -> throw Error("Unable to evaluate")
|
|
||||||
}
|
|
||||||
fun eval(@Suppress("UNUSED_PARAMETER") tx: TransactionForContract, expr: Perceivable<Instant>): Instant = when (expr) {
|
fun eval(@Suppress("UNUSED_PARAMETER") tx: TransactionForContract, expr: Perceivable<Instant>): Instant = when (expr) {
|
||||||
is Const -> expr.value
|
is Const -> expr.value
|
||||||
else -> throw Error("Unable to evaluate")
|
else -> throw Error("Unable to evaluate")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun eval(tx: TransactionForContract, expr: Perceivable<Boolean>): Boolean = when (expr) {
|
fun eval(tx: TransactionForContract, expr: Perceivable<Boolean>): Boolean = when (expr) {
|
||||||
is PerceivableAnd -> eval(tx, expr.left) && eval(tx, expr.right)
|
is PerceivableAnd -> eval(tx, expr.left) && eval(tx, expr.right)
|
||||||
is PerceivableOr -> eval(tx, expr.right) || eval(tx, expr.right)
|
is PerceivableOr -> eval(tx, expr.right) || eval(tx, expr.right)
|
||||||
@ -64,7 +57,6 @@ class UniversalContract : Contract {
|
|||||||
else -> throw NotImplementedError("eval - Boolean - " + expr.javaClass.name)
|
else -> throw NotImplementedError("eval - Boolean - " + expr.javaClass.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun eval(tx: TransactionForContract, expr: Perceivable<BigDecimal>): BigDecimal =
|
fun eval(tx: TransactionForContract, expr: Perceivable<BigDecimal>): BigDecimal =
|
||||||
when (expr) {
|
when (expr) {
|
||||||
is Const<BigDecimal> -> expr.value
|
is Const<BigDecimal> -> expr.value
|
||||||
@ -102,41 +94,6 @@ class UniversalContract : Contract {
|
|||||||
else -> throw NotImplementedError("eval - BigDecimal - " + expr.javaClass.name)
|
else -> throw NotImplementedError("eval - BigDecimal - " + expr.javaClass.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reduce(tx: TransactionForContract, expr: Perceivable<BigDecimal>): Perceivable<BigDecimal> = when (expr) {
|
|
||||||
is PerceivableOperation -> {
|
|
||||||
val left = reduce(tx, expr.left)
|
|
||||||
val right = reduce(tx, expr.right)
|
|
||||||
if (left is Const && right is Const)
|
|
||||||
when (expr.op) {
|
|
||||||
//Operation.DIV -> Const( left.value / right.value )
|
|
||||||
Operation.MINUS -> Const(left.value - right.value)
|
|
||||||
Operation.PLUS -> Const(left.value + right.value)
|
|
||||||
//Operation.TIMES -> Const( left.value * right.value )
|
|
||||||
else -> throw NotImplementedError("reduce - " + expr.op.name)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PerceivableOperation(left, expr.op, right)
|
|
||||||
}
|
|
||||||
is UnaryPlus -> {
|
|
||||||
val amount = reduce(tx, expr.arg)
|
|
||||||
if (amount is Const) {
|
|
||||||
if (amount.value > BigDecimal.ZERO)
|
|
||||||
amount
|
|
||||||
else
|
|
||||||
Const(BigDecimal.ZERO)
|
|
||||||
} else
|
|
||||||
UnaryPlus(amount)
|
|
||||||
}
|
|
||||||
is Interest -> Interest(reduce(tx, expr.amount), expr.dayCountConvention, reduce(tx, expr.interest), expr.start, expr.end)
|
|
||||||
else -> expr
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkAndReduce(tx: TransactionForContract, arrangement: Arrangement): Arrangement = when (arrangement) {
|
|
||||||
is Transfer -> Transfer(reduce(tx, arrangement.amount), arrangement.currency, arrangement.from, arrangement.to)
|
|
||||||
is And -> And(arrangement.arrangements.map { checkAndReduce(tx, it) }.toSet())
|
|
||||||
else -> arrangement
|
|
||||||
}
|
|
||||||
|
|
||||||
fun validateImmediateTransfers(tx: TransactionForContract, arrangement: Arrangement): Arrangement = when (arrangement) {
|
fun validateImmediateTransfers(tx: TransactionForContract, arrangement: Arrangement): Arrangement = when (arrangement) {
|
||||||
is Transfer -> {
|
is Transfer -> {
|
||||||
val amount = eval(tx, arrangement.amount)
|
val amount = eval(tx, arrangement.amount)
|
||||||
@ -147,6 +104,32 @@ class UniversalContract : Contract {
|
|||||||
else -> arrangement
|
else -> arrangement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: think about multi layered rollouts
|
||||||
|
fun reduceRollOut(rollOut: RollOut) : Arrangement {
|
||||||
|
val start = rollOut.startDate
|
||||||
|
val end = rollOut.endDate
|
||||||
|
|
||||||
|
// todo: calendar + rolling conventions
|
||||||
|
val schedule = BusinessCalendar.createGenericSchedule(start, rollOut.frequency, noOfAdditionalPeriods = 1, endDate = end)
|
||||||
|
|
||||||
|
val next = schedule.first() // fail if no dates
|
||||||
|
|
||||||
|
val newRollOut = RollOut(next, end, rollOut.frequency, rollOut.template)
|
||||||
|
|
||||||
|
return replaceNext(rollOut.template, newRollOut )
|
||||||
|
}
|
||||||
|
|
||||||
|
fun replaceNext(arrangement: Arrangement, nextReplacement: RollOut) : Arrangement {
|
||||||
|
return when (arrangement) {
|
||||||
|
is Or -> Or(arrangement.actions.map { replaceNext(it, nextReplacement)!! as Action }.toSet())
|
||||||
|
is And -> And(arrangement.arrangements.map { replaceNext(it, nextReplacement) }.toSet())
|
||||||
|
is Action -> Action( arrangement.name, arrangement.condition, arrangement.actors, replaceNext(arrangement.arrangement, nextReplacement))
|
||||||
|
is Transfer -> arrangement
|
||||||
|
is Zero -> arrangement
|
||||||
|
else -> throw NotImplementedError("replaceNext " + arrangement.javaClass.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun verify(tx: TransactionForContract) {
|
override fun verify(tx: TransactionForContract) {
|
||||||
|
|
||||||
requireThat {
|
requireThat {
|
||||||
@ -160,7 +143,14 @@ class UniversalContract : Contract {
|
|||||||
when (value) {
|
when (value) {
|
||||||
is Commands.Action -> {
|
is Commands.Action -> {
|
||||||
val inState = tx.inputs.single() as State
|
val inState = tx.inputs.single() as State
|
||||||
val actions = actions(inState.details)
|
val arr = when (inState.details) {
|
||||||
|
is Or -> inState.details
|
||||||
|
is Action -> inState.details
|
||||||
|
is RollOut -> reduceRollOut(inState.details)
|
||||||
|
else -> throw InvalidArgument("Unexpected arrangement, " + tx.inputs.single())
|
||||||
|
}
|
||||||
|
|
||||||
|
val actions = actions(arr)
|
||||||
|
|
||||||
val action = actions[value.name] ?: throw IllegalArgumentException("Failed requirement: action must be defined")
|
val action = actions[value.name] ?: throw IllegalArgumentException("Failed requirement: action must be defined")
|
||||||
|
|
||||||
@ -229,8 +219,8 @@ class UniversalContract : Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T> replaceFixing(tx: TransactionForContract, perceivable: Perceivable<T>,
|
fun <T> replaceFixing(tx: TransactionForContract, perceivable: Perceivable<T>,
|
||||||
fixings: Map<FixOf, BigDecimal>, unusedFixings: MutableSet<FixOf>): Perceivable<T> =
|
fixings: Map<FixOf, BigDecimal>, unusedFixings: MutableSet<FixOf>): Perceivable<T> {
|
||||||
when (perceivable) {
|
return when (perceivable) {
|
||||||
is Const -> perceivable
|
is Const -> perceivable
|
||||||
is UnaryPlus -> UnaryPlus(replaceFixing(tx, perceivable.arg, fixings, unusedFixings))
|
is UnaryPlus -> UnaryPlus(replaceFixing(tx, perceivable.arg, fixings, unusedFixings))
|
||||||
is PerceivableOperation -> PerceivableOperation(replaceFixing(tx, perceivable.left, fixings, unusedFixings),
|
is PerceivableOperation -> PerceivableOperation(replaceFixing(tx, perceivable.left, fixings, unusedFixings),
|
||||||
@ -244,6 +234,7 @@ class UniversalContract : Contract {
|
|||||||
} else perceivable
|
} else perceivable
|
||||||
else -> throw NotImplementedError("replaceFixing - " + perceivable.javaClass.name)
|
else -> throw NotImplementedError("replaceFixing - " + perceivable.javaClass.name)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun replaceFixing(tx: TransactionForContract, arr: Action,
|
fun replaceFixing(tx: TransactionForContract, arr: Action,
|
||||||
fixings: Map<FixOf, BigDecimal>, unusedFixings: MutableSet<FixOf>) =
|
fixings: Map<FixOf, BigDecimal>, unusedFixings: MutableSet<FixOf>) =
|
||||||
@ -256,6 +247,7 @@ class UniversalContract : Contract {
|
|||||||
is Zero -> arr
|
is Zero -> arr
|
||||||
is Transfer -> Transfer(replaceFixing(tx, arr.amount, fixings, unusedFixings), arr.currency, arr.from, arr.to)
|
is Transfer -> Transfer(replaceFixing(tx, arr.amount, fixings, unusedFixings), arr.currency, arr.from, arr.to)
|
||||||
is Or -> Or(arr.actions.map { replaceFixing(tx, it, fixings, unusedFixings) }.toSet())
|
is Or -> Or(arr.actions.map { replaceFixing(tx, it, fixings, unusedFixings) }.toSet())
|
||||||
|
is RollOut -> RollOut(arr.startDate, arr.endDate, arr.frequency, replaceFixing(tx, arr.template, fixings, unusedFixings))
|
||||||
else -> throw NotImplementedError("replaceFixing - " + arr.javaClass.name)
|
else -> throw NotImplementedError("replaceFixing - " + arr.javaClass.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.r3corda.contracts.universal
|
package com.r3corda.contracts.universal
|
||||||
|
|
||||||
|
import com.r3corda.core.contracts.BusinessCalendar
|
||||||
import com.r3corda.core.contracts.Frequency
|
import com.r3corda.core.contracts.Frequency
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
import java.time.LocalDate
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,19 +25,19 @@ val zero = Zero()
|
|||||||
open class ContractBuilder {
|
open class ContractBuilder {
|
||||||
val contracts = mutableListOf<Arrangement>()
|
val contracts = mutableListOf<Arrangement>()
|
||||||
|
|
||||||
fun Party.gives(beneficiary: Party, amount: BigDecimal, currency: Currency) : Transfer {
|
fun Party.gives(beneficiary: Party, amount: BigDecimal, currency: Currency): Transfer {
|
||||||
val c = Transfer(const(amount), currency, this, beneficiary)
|
val c = Transfer(const(amount), currency, this, beneficiary)
|
||||||
contracts.add( c )
|
contracts.add(c)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Party.gives(beneficiary: Party, amount: Perceivable<BigDecimal>, currency: Currency) : Transfer {
|
fun Party.gives(beneficiary: Party, amount: Perceivable<BigDecimal>, currency: Currency): Transfer {
|
||||||
val c = Transfer(amount, currency, this, beneficiary)
|
val c = Transfer(amount, currency, this, beneficiary)
|
||||||
contracts.add( c )
|
contracts.add(c)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Party.may(init: ActionBuilder.() -> Unit) : Or {
|
fun Party.may(init: ActionBuilder.() -> Unit): Or {
|
||||||
val b = ActionBuilder(setOf(this))
|
val b = ActionBuilder(setOf(this))
|
||||||
b.init()
|
b.init()
|
||||||
val c = Or(b.actions.toSet())
|
val c = Or(b.actions.toSet())
|
||||||
@ -43,7 +45,7 @@ open class ContractBuilder {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Set<Party>.may(init: ActionBuilder.() -> Unit) : Or {
|
fun Set<Party>.may(init: ActionBuilder.() -> Unit): Or {
|
||||||
val b = ActionBuilder(this)
|
val b = ActionBuilder(this)
|
||||||
b.init()
|
b.init()
|
||||||
val c = Or(b.actions.toSet())
|
val c = Or(b.actions.toSet())
|
||||||
@ -51,32 +53,48 @@ open class ContractBuilder {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
infix fun Or.or(ors: Or): Or {
|
||||||
|
assert(ors.actions.size == 1)
|
||||||
|
assert(contracts[contracts.lastIndex-1] == this)
|
||||||
|
assert(contracts[contracts.lastIndex] == ors)
|
||||||
|
contracts.removeAt(contracts.lastIndex)
|
||||||
|
|
||||||
|
val c = Or(this.actions + ors.actions.single())
|
||||||
|
contracts[contracts.lastIndex] = c
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
infix fun Party.or(party: Party) = setOf(this, party)
|
infix fun Party.or(party: Party) = setOf(this, party)
|
||||||
infix fun Set<Party>.or(party: Party) = this.plus(party)
|
infix fun Set<Party>.or(party: Party) = this.plus(party)
|
||||||
|
|
||||||
@Deprecated(level = DeprecationLevel.ERROR, message = "Not allowed")
|
@Deprecated(level = DeprecationLevel.ERROR, message = "Not allowed")
|
||||||
fun Action(@Suppress("UNUSED_PARAMETER") name: String, @Suppress("UNUSED_PARAMETER") condition: Perceivable<Boolean>,
|
fun Action(@Suppress("UNUSED_PARAMETER") name: String, @Suppress("UNUSED_PARAMETER") condition: Perceivable<Boolean>,
|
||||||
@Suppress("UNUSED_PARAMETER") actors: Set<Party>, @Suppress("UNUSED_PARAMETER") arrangement: Arrangement) {}
|
@Suppress("UNUSED_PARAMETER") actors: Set<Party>, @Suppress("UNUSED_PARAMETER") arrangement: Arrangement) {
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated(level = DeprecationLevel.ERROR, message = "Not available")
|
@Deprecated(level = DeprecationLevel.ERROR, message = "Not available")
|
||||||
fun<T> String.anytime(@Suppress("UNUSED_PARAMETER") ignore: T ) {}
|
fun <T> String.anytime(@Suppress("UNUSED_PARAMETER") ignore: T) {
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated(level = DeprecationLevel.ERROR, message = "Not available")
|
@Deprecated(level = DeprecationLevel.ERROR, message = "Not available")
|
||||||
fun<T> String.givenThat(@Suppress("UNUSED_PARAMETER") ignore: T ) {}
|
fun <T> String.givenThat(@Suppress("UNUSED_PARAMETER") ignore: T) {
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated(level = DeprecationLevel.ERROR, message = "Not available")
|
@Deprecated(level = DeprecationLevel.ERROR, message = "Not available")
|
||||||
fun<T> String.givenThat(@Suppress("UNUSED_PARAMETER") ignore1: T, @Suppress("UNUSED_PARAMETER") ignore2: T ) {}
|
fun <T> String.givenThat(@Suppress("UNUSED_PARAMETER") ignore1: T, @Suppress("UNUSED_PARAMETER") ignore2: T) {
|
||||||
|
}
|
||||||
|
|
||||||
/* fun Party.gives(beneficiary: Party, amount: Perceivable<Long>, currency: Currency) {
|
/* fun Party.gives(beneficiary: Party, amount: Perceivable<Long>, currency: Currency) {
|
||||||
contracts.add( Transfer(amount, currency, this, beneficiary))
|
contracts.add( Transfer(amount, currency, this, beneficiary))
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
infix fun Arrangement.and(arrangement: Arrangement) = And( setOf(this, arrangement) )
|
infix fun Arrangement.and(arrangement: Arrangement) = And(setOf(this, arrangement))
|
||||||
infix fun Action.or(arrangement: Action) = Or( setOf(this, arrangement) )
|
infix fun Action.or(arrangement: Action) = Or(setOf(this, arrangement))
|
||||||
infix fun Or.or(arrangement: Action) = Or( this.actions.plusElement(arrangement) )
|
// infix fun Or.or(arrangement: Action) = Or( this.actions.plusElement(arrangement) )
|
||||||
infix fun Or.or(ors: Or) = Or( this.actions.plus(ors.actions) )
|
// infix fun Or.or(ors: Or) = Or( this.actions.plus(ors.actions) )
|
||||||
|
|
||||||
fun rollOut(startDate: String, endDate: String, frequency: Frequency, init: RollOutBuilder<Dummy>.() -> Unit) : RollOut {
|
fun rollOut(startDate: LocalDate, endDate: LocalDate, frequency: Frequency, init: RollOutBuilder<Dummy>.() -> Unit): RollOut {
|
||||||
val b = RollOutBuilder(startDate, endDate, frequency, Dummy())
|
val b = RollOutBuilder(startDate, endDate, frequency, Dummy())
|
||||||
b.init()
|
b.init()
|
||||||
val c = b.final()
|
val c = b.final()
|
||||||
@ -84,7 +102,7 @@ open class ContractBuilder {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> rollOut(startDate: String, endDate: String, frequency: Frequency, vars: T, init: RollOutBuilder<T>.() -> Unit) : RollOut {
|
fun <T> rollOut(startDate: LocalDate, endDate: LocalDate, frequency: Frequency, vars: T, init: RollOutBuilder<T>.() -> Unit): RollOut {
|
||||||
val b = RollOutBuilder(startDate, endDate, frequency, vars)
|
val b = RollOutBuilder(startDate, endDate, frequency, vars)
|
||||||
b.init()
|
b.init()
|
||||||
val c = b.final()
|
val c = b.final()
|
||||||
@ -92,6 +110,8 @@ open class ContractBuilder {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val String.ld: LocalDate get() = BusinessCalendar.parseDateFromString(this)
|
||||||
|
|
||||||
open fun final() =
|
open fun final() =
|
||||||
when (contracts.size) {
|
when (contracts.size) {
|
||||||
0 -> zero
|
0 -> zero
|
||||||
@ -100,6 +120,7 @@ open class ContractBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface GivenThatResolve {
|
interface GivenThatResolve {
|
||||||
fun resolve(contract: Arrangement)
|
fun resolve(contract: Arrangement)
|
||||||
}
|
}
|
||||||
@ -139,7 +160,7 @@ data class Parameter<T>(val initialValue: T) : Perceivable<T>
|
|||||||
|
|
||||||
fun<T> variable(v: T) = Parameter<T>(v)
|
fun<T> variable(v: T) = Parameter<T>(v)
|
||||||
|
|
||||||
class RollOutBuilder<T>(val startDate: String, val endDate: String, val frequency: Frequency, val vars: T) : ContractBuilder() {
|
class RollOutBuilder<T>(val startDate: LocalDate, val endDate: LocalDate, val frequency: Frequency, val vars: T) : ContractBuilder() {
|
||||||
|
|
||||||
val start = StartDate()
|
val start = StartDate()
|
||||||
val end = EndDate()
|
val end = EndDate()
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.r3corda.contracts.universal
|
package com.r3corda.contracts.universal
|
||||||
|
|
||||||
|
import com.r3corda.core.contracts.FixOf
|
||||||
import com.r3corda.core.contracts.Frequency
|
import com.r3corda.core.contracts.Frequency
|
||||||
import com.r3corda.core.contracts.Tenor
|
import com.r3corda.core.contracts.Tenor
|
||||||
import com.r3corda.core.utilities.DUMMY_NOTARY
|
import com.r3corda.core.utilities.DUMMY_NOTARY
|
||||||
import com.r3corda.testing.transaction
|
import com.r3corda.testing.transaction
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sofusmortensen on 05/09/16.
|
* Created by sofusmortensen on 05/09/16.
|
||||||
@ -18,16 +20,19 @@ class Cap {
|
|||||||
val notional = 50.M
|
val notional = 50.M
|
||||||
val currency = EUR
|
val currency = EUR
|
||||||
|
|
||||||
|
val tradeDate: LocalDate = LocalDate.of(2016, 9, 1)
|
||||||
|
|
||||||
val contract = arrange {
|
val contract = arrange {
|
||||||
rollOut("2016-04-01", "2017-04-01", Frequency.Quarterly) {
|
rollOut("2016-09-01".ld, "2017-04-01".ld, Frequency.Quarterly) {
|
||||||
(acmeCorp or highStreetBank).may {
|
(acmeCorp or highStreetBank).may {
|
||||||
"exercise".anytime {
|
"exercise".anytime {
|
||||||
val floating = interest(notional, "act/365", fix("LIBOR", start, Tenor("6M")), start, end)
|
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 fixed = interest(notional, "act/365", 0.5.bd, start, end)
|
||||||
highStreetBank.gives(acmeCorp, floating - fixed, currency)
|
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
} or acmeCorp.may {
|
} or
|
||||||
|
acmeCorp.may {
|
||||||
"skip".anytime {
|
"skip".anytime {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
@ -35,11 +40,53 @@ class Cap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val contractFixed = arrange {
|
||||||
|
(acmeCorp or highStreetBank).may {
|
||||||
|
"exercise".anytime() {
|
||||||
|
val floating1 = interest(notional, "act/365", 1.0.bd, "2016-04-01", "2016-07-01")
|
||||||
|
val fixed1 = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-07-01")
|
||||||
|
highStreetBank.gives(acmeCorp, (floating1 - fixed1).plus(), currency)
|
||||||
|
rollOut("2016-07-01".ld, "2017-04-01".ld, Frequency.Quarterly) {
|
||||||
|
(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)
|
||||||
|
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
} or acmeCorp.may {
|
||||||
|
"skip".anytime {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} or acmeCorp.may {
|
||||||
|
"skip".anytime {
|
||||||
|
rollOut("2016-07-01".ld, "2017-04-01".ld, Frequency.Quarterly) {
|
||||||
|
(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)
|
||||||
|
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
} or acmeCorp.may {
|
||||||
|
"skip".anytime {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val stateStart = UniversalContract.State(listOf(DUMMY_NOTARY.owningKey), contract)
|
val stateStart = UniversalContract.State(listOf(DUMMY_NOTARY.owningKey), contract)
|
||||||
|
|
||||||
|
val stateFixed = UniversalContract.State( listOf(DUMMY_NOTARY.owningKey), contractFixed)
|
||||||
|
|
||||||
val contractTARN = arrange {
|
val contractTARN = arrange {
|
||||||
rollOut("2016-04-01", "2017-04-01", Frequency.Quarterly, object {
|
rollOut("2016-04-01".ld, "2017-04-01".ld, Frequency.Quarterly, object {
|
||||||
val limit = variable(150.K)
|
val limit = variable(150.K)
|
||||||
}) {
|
}) {
|
||||||
(acmeCorp or highStreetBank).may {
|
(acmeCorp or highStreetBank).may {
|
||||||
@ -77,4 +124,49 @@ class Cap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `fixing`() {
|
||||||
|
transaction {
|
||||||
|
input { stateStart }
|
||||||
|
output { stateFixed }
|
||||||
|
timestamp(TEST_TX_TIME_1)
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||||
|
this `fails with` "action must be defined"
|
||||||
|
}
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
// wrong source
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBORx", tradeDate, Tenor("6M")), 1.0.bd))) }
|
||||||
|
|
||||||
|
this `fails with` "relevant fixing must be included"
|
||||||
|
}
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
// wrong date
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", tradeDate.plusYears(1), Tenor("6M")), 1.0.bd))) }
|
||||||
|
|
||||||
|
this `fails with` "relevant fixing must be included"
|
||||||
|
}
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
// wrong tenor
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("3M")), 1.0.bd))) }
|
||||||
|
|
||||||
|
this `fails with` "relevant fixing must be included"
|
||||||
|
}
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("6M")), 1.5.bd))) }
|
||||||
|
|
||||||
|
this `fails with` "output state does not reflect fix command"
|
||||||
|
}
|
||||||
|
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Fix(listOf(com.r3corda.core.contracts.Fix(FixOf("LIBOR", tradeDate, Tenor("6M")), 1.0.bd))) }
|
||||||
|
|
||||||
|
this.verifies()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ class Caplet {
|
|||||||
|
|
||||||
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
|
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
|
||||||
|
|
||||||
val dt: LocalDate = LocalDate.of(2016, 9, 1)
|
val tradeDate: LocalDate = LocalDate.of(2016, 9, 1)
|
||||||
|
|
||||||
val notional = 50.M
|
val notional = 50.M
|
||||||
val currency = EUR
|
val currency = EUR
|
||||||
@ -26,7 +26,7 @@ class Caplet {
|
|||||||
val contract = arrange {
|
val contract = arrange {
|
||||||
(acmeCorp or highStreetBank).may {
|
(acmeCorp or highStreetBank).may {
|
||||||
"exercise".anytime() {
|
"exercise".anytime() {
|
||||||
val floating = interest(notional, "act/365", fix("LIBOR", dt, Tenor("6M")), "2016-04-01", "2016-10-01")
|
val floating = interest(notional, "act/365", fix("LIBOR", tradeDate, Tenor("6M")), "2016-04-01", "2016-10-01")
|
||||||
val fixed = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-10-01")
|
val fixed = interest(notional, "act/365", 0.5.bd, "2016-04-01", "2016-10-01")
|
||||||
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
highStreetBank.gives(acmeCorp, (floating - fixed).plus(), currency)
|
||||||
}
|
}
|
||||||
@ -102,32 +102,32 @@ class Caplet {
|
|||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong source
|
// wrong source
|
||||||
command(highStreetBank.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", tradeDate, Tenor("6M")), 1.0.bd))) }
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong date
|
// wrong date
|
||||||
command(highStreetBank.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", tradeDate.plusYears(1), Tenor("6M")), 1.0.bd))) }
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
// wrong tenor
|
// wrong tenor
|
||||||
command(highStreetBank.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", tradeDate, Tenor("3M")), 1.0.bd))) }
|
||||||
|
|
||||||
this `fails with` "relevant fixing must be included"
|
this `fails with` "relevant fixing must be included"
|
||||||
}
|
}
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
command(highStreetBank.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", tradeDate, Tenor("6M")), 1.5.bd))) }
|
||||||
|
|
||||||
this `fails with` "output state does not reflect fix command"
|
this `fails with` "output state does not reflect fix command"
|
||||||
}
|
}
|
||||||
|
|
||||||
command(highStreetBank.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", tradeDate, Tenor("6M")), 1.0.bd))) }
|
||||||
|
|
||||||
this.verifies()
|
this.verifies()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.r3corda.contracts.universal
|
||||||
|
|
||||||
|
import com.r3corda.core.contracts.BusinessCalendar
|
||||||
|
import com.r3corda.core.contracts.Frequency
|
||||||
|
import com.r3corda.core.utilities.DUMMY_NOTARY
|
||||||
|
import com.r3corda.testing.transaction
|
||||||
|
import org.junit.Test
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by sofusmortensen on 08/09/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class RollOutTests {
|
||||||
|
|
||||||
|
val TEST_TX_TIME_1: Instant get() = Instant.parse("2017-09-02T12:00:00.00Z")
|
||||||
|
|
||||||
|
val contract = arrange {
|
||||||
|
rollOut("2016-09-01".ld, "2017-09-01".ld, Frequency.Monthly) {
|
||||||
|
(acmeCorp or highStreetBank).may {
|
||||||
|
"transfer".givenThat(after(end)) {
|
||||||
|
highStreetBank.gives(acmeCorp, 10.K, USD)
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val stateStart = UniversalContract.State(listOf(DUMMY_NOTARY.owningKey), contract)
|
||||||
|
|
||||||
|
val contractStep1a = arrange {
|
||||||
|
rollOut("2016-12-01".ld, "2017-09-01".ld, Frequency.Monthly) {
|
||||||
|
(acmeCorp or highStreetBank).may {
|
||||||
|
"transfer".givenThat(after(end)) {
|
||||||
|
highStreetBank.gives(acmeCorp, 10.K, USD)
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val contractStep1b = arrange {
|
||||||
|
highStreetBank.gives(acmeCorp, 10.K, USD)
|
||||||
|
}
|
||||||
|
|
||||||
|
val stateStep1a = UniversalContract.State(listOf(DUMMY_NOTARY.owningKey), contractStep1a)
|
||||||
|
val stateStep1b = UniversalContract.State(listOf(DUMMY_NOTARY.owningKey), contractStep1b)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun dateTests() {
|
||||||
|
|
||||||
|
val d1 = BusinessCalendar.parseDateFromString("2016-09-10")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun issue() {
|
||||||
|
transaction {
|
||||||
|
output { stateStart }
|
||||||
|
timestamp(TEST_TX_TIME_1)
|
||||||
|
|
||||||
|
this `fails with` "transaction has a single command"
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(acmeCorp.owningKey) { UniversalContract.Commands.Issue() }
|
||||||
|
this `fails with` "the transaction is signed by all liable parties"
|
||||||
|
}
|
||||||
|
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Issue() }
|
||||||
|
|
||||||
|
this.verifies()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `execute`() {
|
||||||
|
transaction {
|
||||||
|
input { stateStart }
|
||||||
|
output { stateStep1a }
|
||||||
|
output { stateStep1b }
|
||||||
|
timestamp(TEST_TX_TIME_1)
|
||||||
|
|
||||||
|
tweak {
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("some undefined name") }
|
||||||
|
this `fails with` "action must be defined"
|
||||||
|
}
|
||||||
|
|
||||||
|
command(highStreetBank.owningKey) { UniversalContract.Commands.Action("exercise") }
|
||||||
|
|
||||||
|
this.verifies()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -45,7 +45,7 @@ class Swaption {
|
|||||||
|
|
||||||
|
|
||||||
val elegant_contract = arrange {
|
val elegant_contract = arrange {
|
||||||
rollOut("01/04/2015", "01/04/2025", Frequency.Quarterly) {
|
rollOut("01/04/2015".ld, "01/04/2025".ld, Frequency.Quarterly) {
|
||||||
(highStreetBank or acmeCorp).may {
|
(highStreetBank or acmeCorp).may {
|
||||||
"proceed".givenThat(after(start)) {
|
"proceed".givenThat(after(start)) {
|
||||||
highStreetBank.gives(acmeCorp, libor(notional, start, end), currency)
|
highStreetBank.gives(acmeCorp, libor(notional, start, end), currency)
|
||||||
@ -63,7 +63,7 @@ class Swaption {
|
|||||||
val strike = 1.2
|
val strike = 1.2
|
||||||
|
|
||||||
val tarf = arrange {
|
val tarf = arrange {
|
||||||
rollOut("01/04/2015", "01/04/2016", Frequency.Quarterly, object {
|
rollOut("01/04/2015".ld, "01/04/2016".ld, Frequency.Quarterly, object {
|
||||||
val cap = variable(150.K)
|
val cap = variable(150.K)
|
||||||
}) {
|
}) {
|
||||||
acmeCorp.may {
|
acmeCorp.may {
|
||||||
@ -86,7 +86,7 @@ class Swaption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val tarf2 = arrange {
|
val tarf2 = arrange {
|
||||||
rollOut("01/04/2015", "01/04/2016", Frequency.Quarterly, object {
|
rollOut("01/04/2015".ld, "01/04/2016".ld, Frequency.Quarterly, object {
|
||||||
val uses = variable(4)
|
val uses = variable(4)
|
||||||
}) {
|
}) {
|
||||||
acmeCorp.may {
|
acmeCorp.may {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user