aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/Dawn/models.py68
-rw-r--r--python/Dawn/templates/base.html2
-rw-r--r--python/Dawn/templates/capfloor_blotter.html40
-rw-r--r--python/Dawn/views.py23
4 files changed, 125 insertions, 8 deletions
diff --git a/python/Dawn/models.py b/python/Dawn/models.py
index d11a6394..ef686dd3 100644
--- a/python/Dawn/models.py
+++ b/python/Dawn/models.py
@@ -84,11 +84,18 @@ SWAP_TYPE = ENUM('CD_INDEX', 'CD_INDEX_TRANCHE', 'CD_BASKET_TRANCHE', 'ABS_CDS',
ISDA = ENUM('ISDA2014', 'ISDA2003Cred', name='isda')
DAY_COUNT = ENUM('ACT/360', 'ACT/ACT', '30/360', 'ACT/365', name='day_count')
-
+FREQ = ENUM('Yearly', 'Half-Yearly', 'Quarterly', 'Bi-Monthly', 'Monthly',
+ 'Weekly', 'Daily', 'Straight', name='frequency')
BUS_DAY_CONVENTION = ENUM('Modified Following', 'Following', 'Modified Preceding', 'Preceding',
'Second-Day-After', 'End-of-Month', name='bus_day_convention')
PROTECTION = ENUM('Buyer', 'Seller', name='protection')
+CAPFLOOR_TYPE = ENUM('CAPFLOOR', 'CMS_OPTION', 'STRUCTURED', 'FORWARD_PREMIUM', name='capfloor_type')
+CAPFLOOR = ENUM('C', 'F', name='cap_or_floor')
+PAYMENT_MODE = ENUM('F', 'S', name='payment_mode')
+PRICING_TYPE = ENUM('PlainVanilla', 'EquityIndex', name='pricing_type')
+BEGIN_OR_END = ENUM('B', 'E', name='begin_or_end')
+
class BondDeal(db.Model):
__tablename__ = 'bonds'
id = db.Column('id', db.Integer, primary_key=True)
@@ -112,9 +119,9 @@ class BondDeal(db.Model):
identifier = db.Column(db.String(12), info={'filters': [lambda x: x or None,],
'trim': True})
description = db.Column(db.String(32), nullable = False, info={'trim': True})
- buysell = db.Column(db.Boolean, nullable = False, info={'choices':[(0, 'sell'), (1, 'buy')],
- 'coerce': lambda x: bool(int(x)) \
- if x is not None else x})
+ buysell = db.Column(db.Boolean, nullable=False, info={'choices': [(0, 'sell'), (1, 'buy')],
+ 'coerce': lambda x: bool(int(x)) \
+ if x is not None else x})
faceamount = db.Column(db.Float, nullable=False)
price = db.Column(db.Float, nullable=False)
accrued = db.Column(db.Float, nullable = False)
@@ -292,6 +299,59 @@ class CashFlowDeal(db.Model):
trade_date = db.Column(db.Date, nullable=False)
account = db.relationship(Accounts)
+class CapFloorDeal(db.Model):
+ __tablename__ = 'capfloors'
+ id = db.Column('id', db.Integer, primary_key=True)
+ dealid = db.Column(db.String(28))
+ lastupdate = db.Column(db.DateTime, server_default=db.func.now(), onupdate=db.func.now())
+ action = db.Column(ACTION)
+ folder = db.Column(SWAPTION_STRAT, nullable=False)
+ custodian = db.Column(db.String(12), default='NONE', nullable=False)
+ cashaccount = db.Column(db.String(10), default='SGNSCLMASW', nullable=False)
+ cp_code = db.Column(db.String(12), db.ForeignKey('counterparties.code'),
+ info={'choices': [(None, '')],
+ 'label': 'counterparty'}, nullable=False)
+ comments = db.Column(db.String(100))
+ floating_rate_index = db.Column(db.String(12), nullable=False,
+ info={'label': 'Floating Rate Index'})
+ floating_rate_index_desc = db.Column(db.String(32))
+ buysell = db.Column(db.Boolean, nullable=False, info={'choices':[(0, 'sell'), (1, 'buy')],
+ 'coerce': lambda x: bool(int(x)) \
+ if x is not None else x})
+ cap_or_floor = db.Column(CAPFLOOR, nullable=False,
+ info={'choices': [('C', 'Cap'), ('F', 'Floor')],
+ 'label': 'Cap or Floor?'})
+ strike = db.Column(db.Float, nullable=False)
+ value_date = db.Column(db.Date, nullable=False)
+ expiration_date = db.Column(db.Date, nullable=False)
+ premium_percent = db.Column(db.Float, nullable=False)
+ pricing_type = db.Column(PRICING_TYPE, nullable=False)
+ payment_frequency = db.Column(FREQ, nullable=False, default='Straight')
+ fixing_frequency = db.Column(FREQ, nullable=False, default='Straight')
+ day_count_counvention = db.Column(DAY_COUNT, default='Act/Act')
+ bdc_convention = db.Column(BUS_DAY_CONVENTION, default='Modified')
+ payment_mode = db.Column(PAYMENT_MODE, nullable=False,
+ info={'choices': [('F', 'Flat'), ('S', 'Schedule')]})
+ payment_at_beginning_or_end = db.Column(BEGIN_OR_END, nullable=False,
+ info={'label': 'In arrears?',
+ 'choices': [('E', True),
+ ('B', False)]})
+ initial_margin_percentage = db.Column(db.Float)
+ initial_margin_currency = db.Column(CCY)
+ amount = db.Column(db.Float, nullable=False, info={'label': 'notional'})
+ trade_date = db.Column(db.Date, nullable=False)
+ swap_type = db.Column(CAPFLOOR_TYPE, nullable=False)
+ reset_lag = db.Column(db.Integer, default=2)
+ trade_confirm = db.Column(db.String, info={'form_field_class': FileField})
+ termination_date = db.Column(db.Date)
+ termination_amount = db.Column(db.Float)
+ termination_cp = db.Column(db.String(12), db.ForeignKey('counterparties.code'),
+ info={'choices': [(None, '')],
+ 'label': 'termination counterparty'})
+ counterparty = db.relationship(Counterparties, foreign_keys=[cp_code])
+ termination_counterparty = db.relationship(Counterparties,
+ foreign_keys=[termination_cp])
+
BaseModelForm = model_form_factory(FlaskForm)
class ModelForm(BaseModelForm):
@classmethod
diff --git a/python/Dawn/templates/base.html b/python/Dawn/templates/base.html
index 3e261e42..97ba4e3d 100644
--- a/python/Dawn/templates/base.html
+++ b/python/Dawn/templates/base.html
@@ -29,6 +29,7 @@
<li><a href="{{url_for('list_trades', kind='swaption')}}">Swaptions</a></li>
<li><a href="{{url_for('list_trades', kind='future')}}">Futures</a></li>
<li><a href="{{url_for('list_trades', kind='wire')}}">Wires</a></li>
+ <li><a href="{{url_for('list_trades', kind='capfloor')}}">Caps and Floors</a></li>
</ul>
</li>
<li class="dropdown">
@@ -44,6 +45,7 @@
<li><a href="{{url_for('trade_manage', kind='swaption')}}">Swaptions</a></li>
<li><a href="{{url_for('trade_manage', kind='future')}}">Futures</a></li>
<li><a href="{{url_for('wire_manage')}}">Wires</a></li>
+ <li><a href="{{url_for('trade_manage', kind='capfloor')}}">Caps and Floors</a></li>
</ul>
</li>
<li class="dropdown">
diff --git a/python/Dawn/templates/capfloor_blotter.html b/python/Dawn/templates/capfloor_blotter.html
new file mode 100644
index 00000000..e8cf14cf
--- /dev/null
+++ b/python/Dawn/templates/capfloor_blotter.html
@@ -0,0 +1,40 @@
+{% extends "base.html" %}
+{% block content %}
+<table class="table table-striped">
+ <thead>
+ <tr>
+ <td>Deal ID</td>
+ <td>Trade Date</td>
+ <td>Settle Date</td>
+ <td>Buy/Sell</td>
+ <td>Notional</td>
+ <td>Type</td>
+ <td>Expiry</td>
+ <td>Strike</td>
+ <td>Price</td>
+ <td>Description</td>
+ <td>Red Code</td>
+ <td>Counterparty</td>
+ <td>Strategy</td>
+ </tr>
+ </thead>
+ {% for trade in trades %}
+ <tr>
+ <td><a href="{{url_for('trade_manage', tradeid=trade.id, kind='swaption')}}">{{trade.dealid}}</a></td>
+ <td>{{trade.trade_date}}</td>
+ <td>{{trade.settle_date}}</td>
+ <td>{% if trade.buysell %}Buy{% else %}Sell{% endif %}</td>
+ <td>{{"{0:,.2f}".format(trade.amount)}}</td>
+ <td>{{trade.option_type}}</td>
+ <td>{{trade.expiration_date}}</td>
+ <td>{{trade.strike}}</td>
+ <td>{{trade.premium_percent}}</td>
+ <td>{{trade.floating_rate_index}}</td>
+ <td>{{trade.floating_rate_index_desc}}</td>
+ <td><a href="{{url_for('edit_counterparty',
+ cpcode=trade.counterparty.code)}}">{{trade.counterparty.name}}</a></td>
+ <td>{{trade.folder}}</td>
+ </tr>
+ {% endfor %}
+</table>
+{% endblock %}
diff --git a/python/Dawn/views.py b/python/Dawn/views.py
index 3aa374ac..c427e97c 100644
--- a/python/Dawn/views.py
+++ b/python/Dawn/views.py
@@ -10,7 +10,7 @@ from flask import (abort, request, render_template, redirect,
from .models import (ModelForm, CASH_STRAT, CCY,
BondDeal, CDSDeal, SwaptionDeal, FutureDeal, CashFlowDeal,
- Counterparties, Accounts)
+ CapFloorDeal, Counterparties, Accounts)
from sqlalchemy.exc import IntegrityError
from wtforms.fields import BooleanField
@@ -36,7 +36,7 @@ def cp_choices(kind='bond'):
with_entities(Counterparties.code, Counterparties.name))
elif kind == 'future':
return []
- elif kind == 'cds' or kind == 'swaption':
+ elif kind in ['cds', 'swaption', 'capfloor']:
return (Counterparties.query.
order_by('name').
filter(Counterparties.name.ilike('%CDS%')).
@@ -117,6 +117,14 @@ class FutureForm(ModelForm):
include_foreign_keys = True
exclude = ['dealid', 'lastupdate']
+class CapFloorForm(ModelForm):
+ upload_globeop = BooleanField(label="Upload to globeop?")
+
+ class Meta:
+ model = CapFloorDeal
+ include_foreign_keys = True
+ exclude = ['dealid', 'lastupdate', 'termination_amount',
+ 'termination_cp', 'termination_date']
def get_deal(kind):
if kind == 'cds':
@@ -129,6 +137,8 @@ def get_deal(kind):
return FutureDeal
elif kind == 'wire':
return CashFlowDeal
+ elif kind == 'capfloor':
+ return CapFloorDeal
else:
raise RuntimeError(f'Unknown Deal type: {kind}')
@@ -142,6 +152,8 @@ def _get_form(kind):
return SwaptionForm
elif kind == 'future':
return FutureForm
+ elif kind == 'capfloor':
+ return CapFloorForm
else:
raise RuntimeError('Unknown Deal type')
@@ -389,11 +401,14 @@ def get_bbg_id():
tenor = tenor[:-1] + 'yr'
series = int(series[1:])
sqlstr1 = "SELECT * FROM index_redcode(%s::index_type, %s::smallint, %s)"
- sqlstr2 = "SELECT maturity, coupon FROM index_maturity WHERE index=%s and series=%s and tenor=%s"
+ sqlstr2 = ("SELECT maturity, coupon FROM index_maturity WHERE index=%s "
+ "and series=%s and tenor=%s")
db = get_db()
with db.cursor() as c:
c.execute(sqlstr1, (indextype, series, pd.datetime.today().date()))
(redcode,) = c.fetchone()
c.execute(sqlstr2, (indextype, series, tenor))
maturity, coupon = c.fetchone()
- return jsonify({'maturity': maturity.strftime('%Y-%m-%d'), 'redcode': redcode, 'coupon': coupon})
+ return jsonify({'maturity': maturity.strftime('%Y-%m-%d'),
+ 'redcode': redcode,
+ 'coupon': coupon})