Skip to content
This repository has been archived by the owner on Aug 6, 2021. It is now read-only.

Commit

Permalink
Implement first CERTF schedule test case and fix ap-contracts test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
jo-es committed Jun 24, 2020
1 parent 941320d commit c3ab8e7
Show file tree
Hide file tree
Showing 24 changed files with 415 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,54 @@
"CERTF_01": {
"identifier": "CERTF_01",
"terms": {
"contractID": "CERTF_01",
"contractType": "CERTF",
"statusDate": "2020-06-01T00:00:00",
"marketObjectCode": "CH012D2FLV21",
"contractRole": "BUY",
"creatorID": "549300L7V4",
"counterpartyID": "2490L72UCL4",
"currency": "CHF",
"settlementCurrency": "CHF",
"nominalPrice": "100",
"issuePrice": "100",
"quantity": "100000",
"contractStructure": "[ {\"object\":\"CH02315F1WD\",\"type\":\"MOC\",\"role\":\"UDL\"} ]",
"contractDealDate": "2020-06-01T00:00:00",
"issueDate": "2020-06-02T00:00:00",
"fixingPeriod": "0D",
"exercisePeriod": "5D",
"settlementPeriod": "10D",
"cycleAnchorDateOfRedemption": "2020-09-01T00:00:00",
"cycleOfRedemption": "3M+",
"contractPerformance": "PF",
"calendar": "NC",
"tMax": "2021-06-12T00:00:00",
"dataObserved": "[{\"identifier\":\"CH02315F1WD\",\"times\":[\"2020-06-02T00:00:00\",\"2020-09-01T00:00:00\",\"2020-12-01T00:00:00\",\"2021-03-01T00:00:00\",\"2021-06-01T00:00:00\"],\"values\":[100,110,120,130,140]}]"
},
"contractID": "CERTF_01",
"contractType": "CERTF",
"statusDate": "2020-06-01T00:00:00",
"marketObjectCode": "CH012D2FLV21",
"contractRole": "BUY",
"creatorID": "549300L7V4",
"counterpartyID": "2490L72UCL4",
"currency": "CHF",
"settlementCurrency": "CHF",
"nominalPrice": "100",
"issuePrice": "100",
"quantity": "100000",
"contractStructure": [ { "object": "CH02315F1WD", "type": "MOC", "role": "UDL"} ],
"contractDealDate": "2020-06-01T00:00:00",
"issueDate": "2020-06-02T00:00:00",
"fixingPeriod": "0D",
"exercisePeriod": "5D",
"settlementPeriod": "10D",
"cycleAnchorDateOfRedemption": "2020-09-01T00:00:00",
"cycleOfRedemption": "3M-",
"contractPerformance": "PF",
"calendar": "NC",
"tMax": "2021-06-12T00:00:00"
},
"externalData": {
"CH02315F1WD": [
{
"timestamp": "2020-06-02T00:00:00",
"value": "100"
},
{
"timestamp": "2020-09-01T00:00:00",
"value": "110"
},
{
"timestamp": "2020-12-01T00:00:00",
"value": "120"
},
{
"timestamp": "2021-03-01T00:00:00",
"value": "130"
},
{
"timestamp": "2021-06-01T00:00:00",
"value": "140"
}
]
},
"results": [
{
"eventDate": "2020-06-02T00:00:00",
Expand Down
38 changes: 21 additions & 17 deletions packages/actus-solidity/contracts/Engines/CERTF/CERTFEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,19 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
}

// initial exchange
if (isInSegment(terms.initialExchangeDate, segmentStart, segmentEnd)) {
events[index] = encodeEvent(EventType.IED, terms.initialExchangeDate);
index++;
if (terms.initialExchangeDate != 0) {
if (isInSegment(terms.initialExchangeDate, segmentStart, segmentEnd)) {
events[index] = encodeEvent(EventType.IED, terms.initialExchangeDate);
index++;
}
}

// maturity event
if (isInSegment(terms.maturityDate, segmentStart, segmentEnd) == true) {
events[index] = encodeEvent(EventType.MD, terms.maturityDate);
index++;
if (terms.maturityDate != 0) {
if (isInSegment(terms.maturityDate, segmentStart, segmentEnd) == true) {
events[index] = encodeEvent(EventType.MD, terms.maturityDate);
index++;
}
}

// remove null entries from returned array
Expand Down Expand Up @@ -186,9 +190,9 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
if (terms.cycleOfCoupon.isSet == true && terms.cycleAnchorDateOfCoupon != 0) {
uint256[MAX_CYCLE_SIZE] memory couponSchedule = computeDatesFromCycleSegment(
terms.cycleAnchorDateOfCoupon,
terms.maturityDate,
(terms.maturityDate > 0) ? terms.maturityDate : segmentEnd,
terms.cycleOfCoupon,
true,
(terms.maturityDate > 0) ? true : false,
segmentStart,
segmentEnd
);
Expand All @@ -205,9 +209,9 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
if (terms.cycleOfCoupon.isSet == true && terms.cycleAnchorDateOfCoupon != 0) {
uint256[MAX_CYCLE_SIZE] memory couponSchedule = computeDatesFromCycleSegment(
terms.cycleAnchorDateOfCoupon,
terms.maturityDate,
(terms.maturityDate > 0) ? terms.maturityDate : segmentEnd,
terms.cycleOfCoupon,
true,
(terms.maturityDate > 0) ? true : false,
segmentStart,
segmentEnd
);
Expand All @@ -225,9 +229,9 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
if (terms.cycleOfRedemption.isSet == true && terms.cycleAnchorDateOfRedemption != 0) {
uint256[MAX_CYCLE_SIZE] memory redemptionSchedule = computeDatesFromCycleSegment(
terms.cycleAnchorDateOfRedemption,
terms.maturityDate,
(terms.maturityDate > 0) ? terms.maturityDate : segmentEnd,
terms.cycleOfRedemption,
true,
(terms.maturityDate > 0) ? true : false,
segmentStart,
segmentEnd
);
Expand All @@ -244,9 +248,9 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
if (terms.cycleOfRedemption.isSet == true && terms.cycleAnchorDateOfRedemption != 0) {
uint256[MAX_CYCLE_SIZE] memory redemptionSchedule = computeDatesFromCycleSegment(
terms.cycleAnchorDateOfRedemption,
terms.maturityDate,
(terms.maturityDate > 0) ? terms.maturityDate : segmentEnd,
terms.cycleOfRedemption,
true,
(terms.maturityDate > 0) ? true : false,
segmentStart,
segmentEnd
);
Expand All @@ -264,9 +268,9 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
if (terms.cycleOfRedemption.isSet == true && terms.cycleAnchorDateOfRedemption != 0) {
uint256[MAX_CYCLE_SIZE] memory redemptionSchedule = computeDatesFromCycleSegment(
terms.cycleAnchorDateOfRedemption,
terms.maturityDate,
(terms.maturityDate > 0) ? terms.maturityDate : segmentEnd,
terms.cycleOfRedemption,
true,
(terms.maturityDate > 0) ? true : false,
segmentStart,
segmentEnd
);
Expand All @@ -275,7 +279,7 @@ contract CERTFEngine is Core, CERTFSTF, CERTFPOF, ICERTFEngine {
if (redemptionSchedule[i] == terms.maturityDate) continue;
uint256 executionDateScheduleTime = getTimestampPlusPeriod(terms.exercisePeriod, redemptionSchedule[i]);
if (isInSegment(executionDateScheduleTime, segmentStart, segmentEnd) == false) continue;
events[index] = encodeEvent(EventType.RFD, executionDateScheduleTime);
events[index] = encodeEvent(EventType.XD, executionDateScheduleTime);
index++;
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/actus-solidity/contracts/Engines/CERTF/CERTFSTF.sol
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ contract CERTFSTF is Core {
pure
returns (State memory)
{
state.quantity -= state.exerciseQuantity;
state.quantity = state.quantity.sub(state.exerciseQuantity);
state.exerciseQuantity = 0;
state.exerciseAmount = 0;
state.statusDate = scheduleTime;

if (scheduleTime == state.maturityDate) {
state.contractPerformance = ContractPerformance.MD;
Expand Down
119 changes: 119 additions & 0 deletions packages/actus-solidity/test/Engines/CERTF/TestCERTFSchedules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const CERTFEngine = artifacts.require('CERTFEngine.sol');

const { getTestCases, compareTestResults } = require('../../helper/tests');
const { parseToTestEventCERTF, isoToUnix, unixToISO } = require('../../helper/parser');
const { decodeEvent, sortEvents } = require('../../helper/schedule');

contract('CERTFEngine', () => {

const computeEventScheduleSegment = async (terms, segmentStart, segmentEnd) => {
const schedule = [];

schedule.push(... await this.CERTFEngineInstance.computeNonCyclicScheduleSegment(
terms,
segmentStart,
segmentEnd
));
schedule.push(... await this.CERTFEngineInstance.computeCyclicScheduleSegment(
terms,
segmentStart,
segmentEnd,
21 // CFD
));
schedule.push(... await this.CERTFEngineInstance.computeCyclicScheduleSegment(
terms,
segmentStart,
segmentEnd,
22 // CPD
));
schedule.push(... await this.CERTFEngineInstance.computeCyclicScheduleSegment(
terms,
segmentStart,
segmentEnd,
23 // RFD
));
schedule.push(... await this.CERTFEngineInstance.computeCyclicScheduleSegment(
terms,
segmentStart,
segmentEnd,
24 // RPD
));
schedule.push(... await this.CERTFEngineInstance.computeCyclicScheduleSegment(
terms,
segmentStart,
segmentEnd,
26 // XD
));

return sortEvents(schedule);
}

before(async () => {
this.CERTFEngineInstance = await CERTFEngine.new();
this.testCases = await getTestCases('CERTF');
});

const evaluateEventSchedule = async (terms, dataObserved) => {
const initialState = await this.CERTFEngineInstance.computeInitialState(terms);
const schedule = await computeEventScheduleSegment(
terms,
terms.contractDealDate,
(terms.maturityDate > 0) ? terms.maturityDate : 1623448800
);

const evaluatedSchedule = [];
let state = initialState;

for (_event of schedule) {
const { eventType, scheduleTime } = decodeEvent(_event);
if (scheduleTime == 0) { break; }

const eventTime = await this.CERTFEngineInstance.computeEventTimeForEvent(
_event,
terms.businessDayConvention,
terms.calendar,
terms.maturityDate
);

let externalData = '0';

if (eventType === 23) {
// logic which is implemented in BaseActor
const redemptionAmountIssueDate = Object.values(dataObserved[web3.utils.toAscii(terms.contractReference_1.object)])
.find((value) => {
return String(isoToUnix(value.timestamp)) === terms.issueDate.toString()
}).value;
const redemptionAmountScheduleTime = Object.values(dataObserved[web3.utils.toAscii(terms.contractReference_1.object)])
.find((value) => {
return String(isoToUnix(value.timestamp)) === scheduleTime.toString()
}).value;
externalData = web3.utils.toWei(String(Number(redemptionAmountScheduleTime) / Number(redemptionAmountIssueDate)));
}

const payoff = await this.CERTFEngineInstance.computePayoffForEvent(
terms,
state,
_event,
web3.utils.toHex(externalData)
);
const nextState = await this.CERTFEngineInstance.computeStateForEvent(
terms,
state,
_event,
web3.utils.padLeft(web3.utils.toHex(externalData), 64)
);

state = nextState;

evaluatedSchedule.push(parseToTestEventCERTF(eventType, eventTime, payoff, state));
}

return evaluatedSchedule;
};

it('should yield the expected evaluated contract schedule for test CERTF_01', async () => {
const testDetails = this.testCases['CERTF_01'];
const evaluatedSchedule = await evaluateEventSchedule(testDetails['terms'], testDetails.externalData);
compareTestResults(evaluatedSchedule, testDetails['results']);
});
});
Loading

0 comments on commit c3ab8e7

Please sign in to comment.