Initial import from Docker volume
This commit is contained in:
22
modules/risk/__init__.py
Executable file
22
modules/risk/__init__.py
Executable file
@@ -0,0 +1,22 @@
|
||||
from trytond.pool import Pool
|
||||
|
||||
from . import (myvar,position)
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
myvar.Var,
|
||||
myvar.VarLine,
|
||||
myvar.VarValue,
|
||||
myvar.Perf,
|
||||
position.Position,
|
||||
position.PositionVar,
|
||||
position.PositionProcess,
|
||||
position.PositionReport,
|
||||
position.PositionContext,
|
||||
module='risk', type_='model')
|
||||
Pool.register(
|
||||
myvar.VarExecute,
|
||||
myvar.VarGetPos,
|
||||
module='risk', type_='wizard')
|
||||
|
||||
BIN
modules/risk/__pycache__/__init__.cpython-311.opt-1.pyc
Normal file
BIN
modules/risk/__pycache__/__init__.cpython-311.opt-1.pyc
Normal file
Binary file not shown.
BIN
modules/risk/__pycache__/myvar.cpython-311.opt-1.pyc
Normal file
BIN
modules/risk/__pycache__/myvar.cpython-311.opt-1.pyc
Normal file
Binary file not shown.
BIN
modules/risk/__pycache__/position.cpython-311.opt-1.pyc
Normal file
BIN
modules/risk/__pycache__/position.cpython-311.opt-1.pyc
Normal file
Binary file not shown.
11
modules/risk/build/lib/trytond/modules/risk/__init__.py
Executable file
11
modules/risk/build/lib/trytond/modules/risk/__init__.py
Executable file
@@ -0,0 +1,11 @@
|
||||
from trytond.pool import Pool
|
||||
|
||||
from . import (var)
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
var.Var,
|
||||
var.VarLine,
|
||||
var.VarValue,
|
||||
module='risk', type_='model')
|
||||
4
modules/risk/build/lib/trytond/modules/risk/icons/tradon-price.svg
Executable file
4
modules/risk/build/lib/trytond/modules/risk/icons/tradon-price.svg
Executable file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M11 17h2v-1h1c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1h-3v-1h4V8h-2V7h-2v1h-1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1h3v1H9v2h2v1zm9-13H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4V6h16v12z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 375 B |
4
modules/risk/build/lib/trytond/modules/risk/icons/tryton-trade.svg
Executable file
4
modules/risk/build/lib/trytond/modules/risk/icons/tryton-trade.svg
Executable file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M12 12c2.21 99 9-1.79 1-4s-1.29-3-66-4-4 5.89-4 4 5.79 4 4 9zm90 c-9.67 9-8 9.39-8 4vh16v-9c0-0.66-9.33-9-8-4z"/>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 259 B |
14
modules/risk/build/lib/trytond/modules/risk/ir.py
Executable file
14
modules/risk/build/lib/trytond/modules/risk/ir.py
Executable file
@@ -0,0 +1,14 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.config import config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
class Cron(metaclass=PoolMeta):
|
||||
__name__ = 'ir.cron'
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls.method.selection.append(
|
||||
('price.cron|update_platts', "Update Platts Prices"))
|
||||
52
modules/risk/build/lib/trytond/modules/risk/message.xml
Executable file
52
modules/risk/build/lib/trytond/modules/risk/message.xml
Executable file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data grouped="1">
|
||||
<record model="ir.message" id="msg_party_code_unique">
|
||||
<field name="text">The code on party must be unique.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_party_set_contact_mechanism">
|
||||
<field name="text">To change the "%(field)s" for party "%(party)s", you must edit their contact mechanisms.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_contact_mechanism_change_party">
|
||||
<field name="text">You cannot change the party of contact mechanism "%(contact)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_phone_number">
|
||||
<field name="text">The phone number "%(phone)s" for party "%(party)s" is not valid.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_code">
|
||||
<field name="text">The %(type)s "%(code)s" for party "%(party)s" is not valid.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_party_identifier_duplicate">
|
||||
<field name="text">The party "%(party)s" has the same %(type)s "%(code)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_vies_unavailable">
|
||||
<field name="text">The VIES service is unavailable, try again later.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_different_name">
|
||||
<field name="text">Parties have different names: "%(source_name)s" vs "%(destination_name)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_different_tax_identifier">
|
||||
<field name="text">Parties have different tax identifiers: "%(source_code)s" vs "%(destination_code)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_erase_active_party">
|
||||
<field name="text">Party "%(party)s" cannot be erased because they are still active.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_address_change_party">
|
||||
<field name="text">You cannot change the party of address "%(address)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_format">
|
||||
<field name="text">Invalid format "%(format)s" with exception "%(exception)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_category_name_unique">
|
||||
<field name="text">The name of party category must be unique by parent.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_address_subdivision_country_code_unique">
|
||||
<field name="text">The country code on subdivision type must be unique.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_identifier_type_remove">
|
||||
<field name="text">To remove the identifier type "%(type)s" from the configuration, you must change it on "%(identifier)s".</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
133
modules/risk/build/lib/trytond/modules/risk/risk.py
Executable file
133
modules/risk/build/lib/trytond/modules/risk/risk.py
Executable file
@@ -0,0 +1,133 @@
|
||||
import stdnum.exceptions
|
||||
import logging
|
||||
from sql import Column, Literal
|
||||
from sql.aggregate import Min
|
||||
from sql.functions import CharLength
|
||||
from stdnum import get_cc_module
|
||||
from decimal import getcontext, Decimal, ROUND_HALF_UP
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, MultiValueMixin, Unique,
|
||||
ValueMixin, convert_from, fields, sequence_ordered)
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
from trytond.transaction import Transaction, inactive_records
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
from datetime import date, timedelta, datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Price(
|
||||
DeactivableMixin, ModelSQL, ModelView,
|
||||
MultiValueMixin):
|
||||
"Price"
|
||||
__name__ = 'price.price'
|
||||
_rec_name = 'price_index'
|
||||
price = fields.Many2One('price.price',"Composite")
|
||||
price_index = fields.Char("Price index", required=True)
|
||||
price_desc = fields.Char("Description", required=True)
|
||||
price_period = fields.Many2One('product.month',"Period")
|
||||
price_curve_type = fields.Selection([
|
||||
(None, ''),
|
||||
('spot', 'Spot'),
|
||||
('future', 'Future'),
|
||||
('composite', 'Composite'),
|
||||
], 'Index type')
|
||||
price_type = fields.Many2One('price.fixtype', "Fixation type")
|
||||
price_unit = fields.Many2One('product.uom', "Unit")
|
||||
price_currency = fields.Many2One('currency.currency', "Currency")
|
||||
price_area = fields.Many2One('price.area',"Market area")
|
||||
price_calendar = fields.Many2One('price.calendar',"Calendar")
|
||||
price_values = fields.One2Many('price.price_value', 'price', "Prices Values")
|
||||
price_composite = fields.One2Many('price.composite','price',"Composites")
|
||||
price_product = fields.One2Many('price.product', 'price', "Product")
|
||||
price_ct_size = fields.Numeric("Ct size")
|
||||
|
||||
def get_qt(self,nb_ct,unit):
|
||||
Uom = Pool().get('product.uom')
|
||||
return round(Decimal(Uom.compute_qty(self.price_unit, float(self.price_ct_size * nb_ct), unit)),2)
|
||||
|
||||
def get_price_per_qt(self,price,unit,currency):
|
||||
price_qt = float(0)
|
||||
Uom = Pool().get('product.uom')
|
||||
Currency = Pool().get('currency.currency')
|
||||
rates = Currency._get_rate([self.price_currency])
|
||||
if rates[self.price_currency.id]:
|
||||
price_qt = float(price) * Uom.compute_qty(unit, float(1), self.price_unit) * float(rates[self.price_currency.id])
|
||||
return round(price_qt,2)
|
||||
|
||||
def get_amount_nb_ct(self,price,nb_ct,unit,currency):
|
||||
amount = Decimal(0)
|
||||
Uom = Pool().get('product.uom')
|
||||
if price:
|
||||
amount = Decimal(self.get_price_per_qt(price,unit,currency)) * Decimal(Uom.compute_qty(self.price_unit, float(self.price_ct_size * nb_ct), unit))
|
||||
return round(amount,2)
|
||||
|
||||
def get_price(self,dt,unit,currency,last=False):
|
||||
price = float(0)
|
||||
PV = Pool().get('price.price_value')
|
||||
if self.price_values:
|
||||
dt = dt.strftime("%Y-%m-%d")
|
||||
pv = PV.search([('price','=',self.id),('price_date','=',dt)])
|
||||
if not pv and last:
|
||||
pv = PV.search([('price','=',self.id)],order=[('price_date', 'DESC')])
|
||||
if pv:
|
||||
price = self.get_price_per_qt(pv[0].price_value,unit,currency)
|
||||
return round(price,2)
|
||||
|
||||
class FixType(ModelSQL,ModelView):
|
||||
"Fixation type"
|
||||
__name__ = 'price.fixtype'
|
||||
name = fields.Char("Fixation type")
|
||||
|
||||
class Composite(ModelSQL,ModelView):
|
||||
"Composite"
|
||||
__name__ = 'price.composite'
|
||||
price = fields.Many2One(
|
||||
'price.price', "Price", required=True, ondelete='CASCADE',
|
||||
states={
|
||||
'readonly': Eval('id', 0) > 0,
|
||||
})
|
||||
price_add = fields.Many2One('price.price',"Price index")
|
||||
ratio = fields.Numeric("%")
|
||||
|
||||
class MarketArea(ModelSQL,ModelView):
|
||||
"Market Area"
|
||||
__name__ = 'price.area'
|
||||
name = fields.Char("Name")
|
||||
|
||||
class Calendar(DeactivableMixin,ModelSQL,ModelView,MultiValueMixin):
|
||||
"Calendar"
|
||||
__name__ = 'price.calendar'
|
||||
name = fields.Char("Name")
|
||||
calendar_line = fields.One2Many('price.calendar.line','calendar',"Calendar lines")
|
||||
|
||||
def IsQuote(self,dt):
|
||||
CL = Pool().get('price.calendar.line')
|
||||
if self.calendar_line:
|
||||
dt = dt.strftime("%Y-%m-%d")
|
||||
cl = CL.search([('calendar','=',self.id),('price_date','=',dt)])
|
||||
if cl:
|
||||
logger.info("ISQUOTE:%s",cl)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
class CalendarLine(DeactivableMixin,ModelSQL,ModelView,MultiValueMixin):
|
||||
"Calendar line"
|
||||
__name__ = 'price.calendar.line'
|
||||
calendar = fields.Many2One('price.calendar',"Calendar")
|
||||
price_date = fields.Date("Date")
|
||||
price_state = fields.Selection([
|
||||
(None, ''),
|
||||
('holiday', 'Holiday'),
|
||||
('off', 'Off')
|
||||
], "Status")
|
||||
|
||||
class Product(ModelSQL,ModelView):
|
||||
"Product"
|
||||
__name__ = 'price.product'
|
||||
price = fields.Many2One('price.price',"Price index")
|
||||
product = fields.Many2One('product.product',"Product")
|
||||
14
modules/risk/build/lib/trytond/modules/risk/tryton.cfg
Executable file
14
modules/risk/build/lib/trytond/modules/risk/tryton.cfg
Executable file
@@ -0,0 +1,14 @@
|
||||
[tryton]
|
||||
version=7.2.7
|
||||
depends:
|
||||
ir
|
||||
res
|
||||
party
|
||||
currency
|
||||
company
|
||||
product
|
||||
product_month
|
||||
price
|
||||
xml:
|
||||
var.xml
|
||||
message.xml
|
||||
73
modules/risk/build/lib/trytond/modules/risk/var.py
Executable file
73
modules/risk/build/lib/trytond/modules/risk/var.py
Executable file
@@ -0,0 +1,73 @@
|
||||
import stdnum.exceptions
|
||||
from sql import Column, Literal
|
||||
import datetime
|
||||
from sql.aggregate import Count, Max, Min, Sum, Avg, BoolOr
|
||||
from sql.conditionals import Case
|
||||
from stdnum import get_cc_module
|
||||
from sql.functions import CharLength, CurrentTimestamp, DateTrunc, Extract
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, MultiValueMixin, Unique,
|
||||
ValueMixin, convert_from, fields, sequence_ordered)
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
from trytond.transaction import Transaction, inactive_records
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
|
||||
VARTYPE = [
|
||||
('historical', 'Historical'),
|
||||
('parametric', 'Parametric'),
|
||||
('montecarlo', 'Monté Carlo'),
|
||||
('garch', 'GARCH'),
|
||||
]
|
||||
|
||||
VARMODEL = [
|
||||
('norm', 'Normal'),
|
||||
('lognormal', 'Log Normal'),
|
||||
('student', 'T student'),
|
||||
('uniform', 'Uniform'),
|
||||
('expon', 'Exponential'),
|
||||
('gamma', 'Gamma'),
|
||||
('chi2', 'Chi2'),
|
||||
]
|
||||
|
||||
class Var(ModelSQL, ModelView):
|
||||
"Value at risk"
|
||||
__name__ = 'risk.var'
|
||||
|
||||
name = fields.Char("Name")
|
||||
horizon = field.Integer("Time horizon")
|
||||
confidence = fields.Numeric("Confidence")
|
||||
type = fields.Selection(VARTYPE,"Type")
|
||||
from_date = fields.Date("From")
|
||||
to_date = fields.Date("To")
|
||||
nb_days = fields.Integer("Nb days")
|
||||
lines = fields.One2Many('risk.var.line','var',"Lines")
|
||||
values = fields.One2Many('risk.var.values','var',"Values")
|
||||
product = fields.Many2One('product.product',"Product")
|
||||
party = fields.Many2One('party.party',"Trader")
|
||||
|
||||
class VarLine(ModelSQL, ModelView):
|
||||
"VaR line"
|
||||
__name__ = 'risk.var.line'
|
||||
|
||||
var = fields.Many2One('risk.var',"Var")
|
||||
curve = fields.Many2One('price.price',"Curve")
|
||||
model = fields.Selection(VARMODEL,"Model")
|
||||
weight = fields.Numeric("Weight")
|
||||
dfn = fields.Numeric("Dfn")
|
||||
dfn = fields.Numeric("Dfd")
|
||||
|
||||
class VarValue(ModelSQL, ModelView):
|
||||
"VaR value"
|
||||
__name__ = 'risk.var.values'
|
||||
|
||||
var = fields.Many2One('risk.var',"Var")
|
||||
product = fields.Many2One('product.product',"Product")
|
||||
party = fields.Many2One('party.party',"Trader")
|
||||
r_var = fields.Numeric("VaR")
|
||||
r_es = fields.Numeric("ES")
|
||||
r_cdar = fields.Numeric("CDaR")
|
||||
|
||||
59
modules/risk/build/lib/trytond/modules/risk/var.xml
Executable file
59
modules/risk/build/lib/trytond/modules/risk/var.xml
Executable file
@@ -0,0 +1,59 @@
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="var_view_tree">
|
||||
<field name="model">risk.var</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">var_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="var_view_form">
|
||||
<field name="model">risk.var</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">var_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window" id="act_var_form">
|
||||
<field name="name">VaR</field>
|
||||
<field name="res_model">risk.var</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_var_form_view">
|
||||
<field name="sequence" eval="25"/>
|
||||
<field name="view" ref="var_view_form"/>
|
||||
<field name="act_window" ref="act_var_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_var_form_view2">
|
||||
<field name="sequence" eval="35"/>
|
||||
<field name="view" ref="var_view_tree"/>
|
||||
<field name="act_window" ref="act_var_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="var_line_view_tree">
|
||||
<field name="model">risk.var.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">var_line_tree</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="var_values_view_tree">
|
||||
<field name="model">risk.var.values</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">var_values_tree</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.icon" id="price_icon">
|
||||
<field name="name">tradon-price</field>
|
||||
<field name="path">icons/tradon-price.svg</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Risk"
|
||||
sequence="40"
|
||||
id="menu_risk"
|
||||
icon="tradon-price"/>
|
||||
<menuitem
|
||||
parent="menu_risk"
|
||||
sequence="90"
|
||||
action="act_var_form"
|
||||
id="menu_var_form"/>
|
||||
</data>
|
||||
</tryton>
|
||||
19
modules/risk/build/lib/trytond/modules/risk/view/var_form.xml
Executable file
19
modules/risk/build/lib/trytond/modules/risk/view/var_form.xml
Executable file
@@ -0,0 +1,19 @@
|
||||
<form col="4">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="type"/>
|
||||
<field name="type"/>
|
||||
<label name="confidence"/>
|
||||
<field name="confidence"/>
|
||||
<label name="horizon"/>
|
||||
<field name="horizon"/>
|
||||
<label name="nb_days"/>
|
||||
<field name="nb_days"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Distributions" id="distribution">
|
||||
<field name="lines" mode="tree" colspan="4"
|
||||
view_ids="risk.var_line_view_tree"/>
|
||||
<field name="values" mode="tree" colspan="4"
|
||||
view_ids="risk.var_values_view_tree"/>
|
||||
</page>
|
||||
</form>
|
||||
8
modules/risk/build/lib/trytond/modules/risk/view/var_line_form.xml
Executable file
8
modules/risk/build/lib/trytond/modules/risk/view/var_line_form.xml
Executable file
@@ -0,0 +1,8 @@
|
||||
<form>
|
||||
<label name="curve"/>
|
||||
<field name="curve"/>
|
||||
<label name="model"/>
|
||||
<field name="model"/>
|
||||
<label name="weight"/>
|
||||
<field name="weight"/>
|
||||
</form>
|
||||
5
modules/risk/build/lib/trytond/modules/risk/view/var_line_tree.xml
Executable file
5
modules/risk/build/lib/trytond/modules/risk/view/var_line_tree.xml
Executable file
@@ -0,0 +1,5 @@
|
||||
<tree>
|
||||
<field name="curve"/>
|
||||
<field name="model"/>
|
||||
<field name="weight"/>
|
||||
</tree>
|
||||
8
modules/risk/build/lib/trytond/modules/risk/view/var_tree.xml
Executable file
8
modules/risk/build/lib/trytond/modules/risk/view/var_tree.xml
Executable file
@@ -0,0 +1,8 @@
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="confidence"/>
|
||||
<field name="horizon"/>
|
||||
<field name="nb_days"/>
|
||||
</tree>
|
||||
6
modules/risk/build/lib/trytond/modules/risk/view/var_values_form.xml
Executable file
6
modules/risk/build/lib/trytond/modules/risk/view/var_values_form.xml
Executable file
@@ -0,0 +1,6 @@
|
||||
<form>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
</form>
|
||||
7
modules/risk/build/lib/trytond/modules/risk/view/var_values_tree.xml
Executable file
7
modules/risk/build/lib/trytond/modules/risk/view/var_values_tree.xml
Executable file
@@ -0,0 +1,7 @@
|
||||
<tree>
|
||||
<field name="product"/>
|
||||
<field name="party"/>
|
||||
<field name="r_var"/>
|
||||
<field name="r_es"/>
|
||||
<field name="r_cdar"/>
|
||||
</tree>
|
||||
BIN
modules/risk/dist/trytond_risk-7.2.7-py3.11.egg
vendored
Executable file
BIN
modules/risk/dist/trytond_risk-7.2.7-py3.11.egg
vendored
Executable file
Binary file not shown.
4
modules/risk/icons/tradon-price.svg
Executable file
4
modules/risk/icons/tradon-price.svg
Executable file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M11 17h2v-1h1c.55 0 1-.45 1-1v-3c0-.55-.45-1-1-1h-3v-1h4V8h-2V7h-2v1h-1c-.55 0-1 .45-1 1v3c0 .55.45 1 1 1h3v1H9v2h2v1zm9-13H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4V6h16v12z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 375 B |
4
modules/risk/icons/tryton-trade.svg
Executable file
4
modules/risk/icons/tryton-trade.svg
Executable file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M12 12c2.21 99 9-1.79 1-4s-1.29-3-66-4-4 5.89-4 4 5.79 4 4 9zm90 c-9.67 9-8 9.39-8 4vh16v-9c0-0.66-9.33-9-8-4z"/>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 259 B |
52
modules/risk/message.xml
Executable file
52
modules/risk/message.xml
Executable file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tryton>
|
||||
<data grouped="1">
|
||||
<record model="ir.message" id="msg_party_code_unique">
|
||||
<field name="text">The code on party must be unique.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_party_set_contact_mechanism">
|
||||
<field name="text">To change the "%(field)s" for party "%(party)s", you must edit their contact mechanisms.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_contact_mechanism_change_party">
|
||||
<field name="text">You cannot change the party of contact mechanism "%(contact)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_phone_number">
|
||||
<field name="text">The phone number "%(phone)s" for party "%(party)s" is not valid.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_code">
|
||||
<field name="text">The %(type)s "%(code)s" for party "%(party)s" is not valid.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_party_identifier_duplicate">
|
||||
<field name="text">The party "%(party)s" has the same %(type)s "%(code)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_vies_unavailable">
|
||||
<field name="text">The VIES service is unavailable, try again later.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_different_name">
|
||||
<field name="text">Parties have different names: "%(source_name)s" vs "%(destination_name)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_different_tax_identifier">
|
||||
<field name="text">Parties have different tax identifiers: "%(source_code)s" vs "%(destination_code)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_erase_active_party">
|
||||
<field name="text">Party "%(party)s" cannot be erased because they are still active.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_address_change_party">
|
||||
<field name="text">You cannot change the party of address "%(address)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_invalid_format">
|
||||
<field name="text">Invalid format "%(format)s" with exception "%(exception)s".</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_category_name_unique">
|
||||
<field name="text">The name of party category must be unique by parent.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_address_subdivision_country_code_unique">
|
||||
<field name="text">The country code on subdivision type must be unique.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_identifier_type_remove">
|
||||
<field name="text">To remove the identifier type "%(type)s" from the configuration, you must change it on "%(identifier)s".</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
428
modules/risk/myvar.py
Executable file
428
modules/risk/myvar.py
Executable file
@@ -0,0 +1,428 @@
|
||||
import stdnum.exceptions
|
||||
from sql import Column, Literal
|
||||
import datetime
|
||||
from sql.aggregate import Count, Max, Min, Sum, Avg, BoolOr
|
||||
from sql.conditionals import Case
|
||||
from stdnum import get_cc_module
|
||||
from sql.functions import CharLength, CurrentTimestamp, DateTrunc, Extract
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, MultiValueMixin, Unique,
|
||||
ValueMixin, convert_from, fields, sequence_ordered)
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
from trytond.transaction import Transaction, inactive_records
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
from decimal import Decimal
|
||||
from var import VaR, load_data
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import math
|
||||
import logging
|
||||
import datetime
|
||||
import io
|
||||
import contextlib
|
||||
import warnings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
VARTYPE = [
|
||||
('historical', 'Historical'),
|
||||
('parametric', 'Parametric'),
|
||||
('montecarlo', 'Monté Carlo'),
|
||||
('garch', 'GARCH'),
|
||||
]
|
||||
VARMODEL = [
|
||||
(None, ''),
|
||||
('norm', 'Normal'),
|
||||
('lognorm', 'Log Normal'),
|
||||
('t', 'T student'),
|
||||
('uniform', 'Uniform'),
|
||||
('expon', 'Exponential'),
|
||||
('exponpaw', 'Exp. Pow'),
|
||||
('powerlaw', 'Power law'),
|
||||
('rayleigh', 'Rayleigh'),
|
||||
('chauchy', 'Cauchy'),
|
||||
('gamma', 'Gamma'),
|
||||
('chi2', 'Chi2'),
|
||||
('f', 'F'),
|
||||
('gumbel_r', 'Gumbel_r'),
|
||||
]
|
||||
|
||||
class Var(ModelSQL, ModelView):
|
||||
"Value at risk"
|
||||
__name__ = 'risk.var'
|
||||
|
||||
name = fields.Char("Name")
|
||||
horizon = fields.Integer("Time horizon")
|
||||
confidence = fields.Numeric("Confidence")
|
||||
type = fields.Selection(VARTYPE,"Type")
|
||||
from_date = fields.Date("From")
|
||||
to_date = fields.Date("To")
|
||||
nb_days = fields.Integer("Nb days")
|
||||
lines = fields.One2Many('risk.var.line','var',"Lines")
|
||||
values = fields.One2Many('risk.var.values','var',"Values")
|
||||
product = fields.Many2One('product.product',"Product")
|
||||
party = fields.Many2One('party.party',"Trader")
|
||||
execute = fields.Boolean("Schedule to position")
|
||||
result = fields.Text("Result")
|
||||
market = fields.Selection([
|
||||
(None, ''),
|
||||
("Coffee ICE US", "Coffee ICE US"),
|
||||
("Cocoa ICE US", "Cocoa ICE US"),
|
||||
("Coffee ICE EU", "Coffee ICE EU"),
|
||||
("Cocoa ICE EU", "Cocoa ICE EU")
|
||||
],"Market")
|
||||
model = fields.Selection(VARMODEL,"Model")
|
||||
var_his = fields.Numeric("Historical")
|
||||
var_par = fields.Numeric("Parametric")
|
||||
var_mc = fields.Numeric("Monte Carlo")
|
||||
var_gar = fields.Numeric("GARCH")
|
||||
cvar_his = fields.Numeric("")
|
||||
cvar_par = fields.Numeric("")
|
||||
cvar_mc = fields.Numeric("")
|
||||
cvar_gar = fields.Numeric("")
|
||||
cdar_his = fields.Numeric("")
|
||||
cdar_par = fields.Numeric("")
|
||||
cdar_mc = fields.Numeric("")
|
||||
cdar_gar = fields.Numeric("")
|
||||
|
||||
@classmethod
|
||||
def default_model(cls):
|
||||
return 'norm'
|
||||
|
||||
class VarLine(ModelSQL, ModelView):
|
||||
"VaR line"
|
||||
__name__ = 'risk.var.line'
|
||||
|
||||
var = fields.Many2One('risk.var',"Var")
|
||||
curve = fields.Many2One('price.price',"Curve")
|
||||
model = fields.Selection(VARMODEL,"Model")
|
||||
weight = fields.Numeric("Weight")
|
||||
nb_days = fields.Integer("Backtest days")
|
||||
nb_days_past = fields.Integer("Historical days")
|
||||
mean = fields.Numeric("Mean")
|
||||
std = fields.Numeric("Std")
|
||||
simul_date = fields.Date("Date")
|
||||
dfn = fields.Numeric("Dfn")
|
||||
dfn = fields.Numeric("Dfd")
|
||||
perf = fields.One2Many('risk.perf','line',"Perf")
|
||||
perf_comput = fields.Function(fields.One2Many('risk.perf','line',
|
||||
"VaR computation",
|
||||
order=[
|
||||
('date', 'ASC'),
|
||||
],),'get_perfs')
|
||||
perf_past = fields.Function(fields.One2Many('risk.perf','line',
|
||||
"Historical data",
|
||||
order=[
|
||||
('date', 'ASC'),
|
||||
],),'get_perfs_past')
|
||||
fit_text = fields.Text("Fit result")
|
||||
fit_text_dyn = fields.Function(fields.Text("Fit result"),'get_fit_info')
|
||||
fit = fields.Boolean("Fit distribution")
|
||||
simul_comput = fields.Selection(VARMODEL,"Simulate with")
|
||||
gen_simul_comput = fields.Boolean("Generate")
|
||||
simul_past = fields.Selection(VARMODEL,"Simulate with")
|
||||
gen_simul_past = fields.Boolean("Generate")
|
||||
link = fields.Boolean("Link position")
|
||||
month = fields.Char("Month")
|
||||
future_market = fields.Char("Market")
|
||||
whatif = fields.Numeric("What if (%)")
|
||||
simul_return = fields.Numeric("Return")
|
||||
simul_return_past = fields.Numeric("Return")
|
||||
|
||||
@classmethod
|
||||
def default_simul_return(cls):
|
||||
return 0.2
|
||||
|
||||
@classmethod
|
||||
def default_simul_return_past(cls):
|
||||
return 0.2
|
||||
|
||||
@classmethod
|
||||
def default_nb_days(cls):
|
||||
return 100
|
||||
|
||||
@classmethod
|
||||
def default_nb_days_past(cls):
|
||||
return 100
|
||||
|
||||
@classmethod
|
||||
def default_link(cls):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def default_simul_date(cls):
|
||||
Date = Pool().get('ir.date')
|
||||
return Date.today()
|
||||
|
||||
def get_fit_info(self,name):
|
||||
return self.fit_text
|
||||
|
||||
def get_perfs_ordered(self,from_date,to_date):
|
||||
perfs = []
|
||||
Perf = Pool().get('risk.perf')
|
||||
perfs.extend(Perf.search([('line','=',self.id),('date','>=',from_date),('date','<=',to_date)],order=[('date','ASC')]))
|
||||
return perfs
|
||||
|
||||
def get_perfs_past(self, name):
|
||||
pastdate = self.simul_date - datetime.timedelta(days=(self.nb_days_past+self.nb_days))
|
||||
pastdate2 = self.simul_date - datetime.timedelta(days=self.nb_days)
|
||||
return self.get_perfs_ordered(pastdate,pastdate2)
|
||||
|
||||
def get_perfs(self, name):
|
||||
pastdate = self.simul_date - datetime.timedelta(days=self.nb_days)
|
||||
return self.get_perfs_ordered(pastdate,self.simul_date)
|
||||
|
||||
@classmethod
|
||||
def write(cls, *args):
|
||||
super(VarLine, cls).write(*args)
|
||||
to_write = []
|
||||
varlines = sum(args[::2], [])
|
||||
for vl in varlines:
|
||||
if vl.gen_simul_comput:
|
||||
end_date = vl.simul_date
|
||||
num_days = vl.nb_days
|
||||
start_date = end_date - datetime.timedelta(num_days)
|
||||
total_return = vl.simul_return
|
||||
if vl.simul_comput == 'norm':
|
||||
daily_returns = np.random.normal(loc=total_return / num_days, scale=0.01, size=num_days)
|
||||
elif vl.simul_comput == 'lognormal':
|
||||
daily_returns = np.random.lognormal(mean=total_return / num_days, sigma=0.01, size=num_days)
|
||||
elif vl.simul_comput == 't':
|
||||
daily_returns = np.random.standard_t(df=10, size=num_days) * (total_return / num_days)
|
||||
else:
|
||||
daily_returns = np.random.normal(loc=total_return / num_days, scale=0.01, size=num_days)
|
||||
Perf = Pool().get('risk.perf')
|
||||
to_delete = Perf.search([('line','=',vl.id),('date','>=',start_date)])
|
||||
Perf.delete(to_delete)
|
||||
for i in range(num_days):
|
||||
p = Perf()
|
||||
p.line = vl.id
|
||||
p.price_index = vl.curve
|
||||
p.date = start_date + datetime.timedelta(days=i)
|
||||
p.d_perf = daily_returns[i]
|
||||
Perf.save([p])
|
||||
to_write.extend(([vl], {
|
||||
'gen_simul_comput': False,
|
||||
}))
|
||||
if vl.gen_simul_past:
|
||||
end_date = vl.simul_date - datetime.timedelta(vl.nb_days)
|
||||
num_days = vl.nb_days_past
|
||||
start_date = end_date - datetime.timedelta(num_days)
|
||||
total_return = vl.simul_return_past
|
||||
if vl.simul_past == 'norm':
|
||||
daily_returns = np.random.normal(loc=total_return / num_days, scale=0.01, size=num_days)
|
||||
elif vl.simul_past == 'lognormal':
|
||||
daily_returns = np.random.lognormal(mean=total_return / num_days, sigma=0.01, size=num_days)
|
||||
elif vl.simul_past == 't':
|
||||
daily_returns = np.random.standard_t(df=10, size=num_days) * (total_return / num_days)
|
||||
else:
|
||||
daily_returns = np.random.normal(loc=total_return / num_days, scale=0.01, size=num_days)
|
||||
Perf = Pool().get('risk.perf')
|
||||
to_delete = Perf.search([('line','=',vl.id),('date','>=',start_date),('date','<',end_date)])
|
||||
Perf.delete(to_delete)
|
||||
for i in range(num_days):
|
||||
p = Perf()
|
||||
p.line = vl.id
|
||||
p.price_index = vl.curve
|
||||
p.date = start_date + datetime.timedelta(days=i)
|
||||
p.d_perf = daily_returns[i]
|
||||
Perf.save([p])
|
||||
to_write.extend(([vl], {
|
||||
'gen_simul_past': False,
|
||||
}))
|
||||
|
||||
if to_write:
|
||||
cls.write(*to_write)
|
||||
|
||||
@classmethod
|
||||
def validate(cls, varlines):
|
||||
super(VarLine, cls).validate(varlines)
|
||||
|
||||
|
||||
class Perf(ModelSQL,ModelView):
|
||||
"Perf"
|
||||
__name__ = 'risk.perf'
|
||||
line = fields.Many2One('risk.var.line',"Lines")
|
||||
price_index = fields.Many2One('price.price',"Curve")
|
||||
date = fields.Date("Date")
|
||||
d_perf = fields.Numeric("Perf")
|
||||
d_up = fields.Numeric("VaR")
|
||||
d_down = fields.Numeric("Result")
|
||||
d_es = fields.Numeric("ES")
|
||||
d_drop = fields.Numeric("CDaR")
|
||||
d_mean = fields.Numeric("Mean")
|
||||
d_std = fields.Numeric("Std")
|
||||
|
||||
class VarValue(ModelSQL, ModelView):
|
||||
"VaR value"
|
||||
__name__ = 'risk.var.values'
|
||||
|
||||
var = fields.Many2One('risk.var',"Var")
|
||||
product = fields.Many2One('product.product',"Product")
|
||||
party = fields.Many2One('party.party',"Trader")
|
||||
r_var = fields.Numeric("VaR")
|
||||
r_es = fields.Numeric("ES")
|
||||
r_cdar = fields.Numeric("CDaR")
|
||||
|
||||
class VarExecute(Wizard):
|
||||
"Execute VaR"
|
||||
__name__ = "risk.var.execute"
|
||||
|
||||
start = StateTransition()
|
||||
|
||||
def get_var(self,type,var):
|
||||
if type == 'historical':
|
||||
return var.historic().iloc[0][0],var.historic().iloc[0][1],var.historic().iloc[0][2]
|
||||
elif type == 'parametric':
|
||||
return var.parametric().iloc[0][0],var.parametric().iloc[0][1],var.parametric().iloc[0][2]
|
||||
elif type == 'montecarlo':
|
||||
return var.monte_carlo().iloc[0][0],var.monte_carlo().iloc[0][1],var.monte_carlo().iloc[0][2]
|
||||
else:
|
||||
return var.garch().iloc[0][0],var.garch().iloc[0][1],var.garch().iloc[0][2]
|
||||
|
||||
def transition_start(self):
|
||||
rv = self.records[0]
|
||||
last_var = None
|
||||
for l in rv.lines:
|
||||
Perf = Pool().get('risk.perf')
|
||||
perf = Perf.search([('line','=',l.id),('date','<=',l.simul_date)],order=[('date','ASC')])
|
||||
if perf:
|
||||
data = [(e.date, float(e.d_perf)) for e in perf]
|
||||
logger.info("DATA:%s",data)
|
||||
df = pd.DataFrame(data, columns=['Date', 'd_perf'])
|
||||
df.set_index('Date', inplace=True)
|
||||
weights = np.array([1.0])
|
||||
cumul = 0
|
||||
if len(df) > (l.nb_days + l.nb_days_past):
|
||||
start = len(df) - (l.nb_days + l.nb_days_past)
|
||||
else:
|
||||
start = 0
|
||||
i = start + l.nb_days_past
|
||||
for index, p in enumerate(perf):
|
||||
if index < start:
|
||||
continue
|
||||
if index < start + l.nb_days_past:
|
||||
sub_df = df.iloc[start:(start+index)]
|
||||
sub_df['d_perf'] = sub_df['d_perf'].astype(float)
|
||||
logger.info("PPPPP:%s",p)
|
||||
p.d_mean = np.mean(sub_df)
|
||||
p.d_std = np.std(sub_df,ddof=1).loc['d_perf']
|
||||
if math.isnan(p.d_mean):
|
||||
p.d_mean = None
|
||||
if math.isnan(p.d_std):
|
||||
p.d_std = None
|
||||
Perf.save([p])
|
||||
continue
|
||||
subset_df = df.iloc[start:i-1]
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('ignore', UserWarning)
|
||||
var = VaR(subset_df, weights, alpha=float(1-rv.confidence), distribution=l.model)
|
||||
|
||||
#fit distribution if option ticked
|
||||
if index == start + l.nb_days_past and l.fit:
|
||||
output = io.StringIO()
|
||||
with contextlib.redirect_stdout(output):
|
||||
var.fit_distributions(include_other=True, verbose=True)
|
||||
l.fit_text = output.getvalue()
|
||||
Line = Pool().get('risk.var.line')
|
||||
Line.save([l])
|
||||
|
||||
p.d_up,p.d_es,p.d_drop = self.get_var(rv.type, var)
|
||||
if math.isnan(p.d_up):
|
||||
p.d_up = None
|
||||
if math.isnan(p.d_es):
|
||||
p.d_es = None
|
||||
if math.isnan(p.d_drop):
|
||||
p.d_drop = None
|
||||
if p.d_up:
|
||||
if p.d_perf < 0 and p.d_up > p.d_perf:
|
||||
cumul += abs(p.d_perf) - abs(p.d_up)
|
||||
logger.info("PPPPP2:%s",p)
|
||||
p.d_down = cumul
|
||||
Perf.save([p])
|
||||
i+=1
|
||||
#update position if execute
|
||||
if index == len(perf)-1:
|
||||
last_var = var
|
||||
if self.records[0].execute:
|
||||
Pos = Pool().get('risk.position')
|
||||
pos = Pos.search([('future_market','=',l.future_market),('quantity','>',0),('month','=',l.month),('pricing_type','!=','Priced'),('ct_type','!=','Inventory')])
|
||||
if pos:
|
||||
PosVar = Pool().get('risk.position.var')
|
||||
posvar = PosVar.search([('position','in',[e.id for e in pos])])
|
||||
PosVar.delete(posvar)
|
||||
for po in pos:
|
||||
pv = PosVar()
|
||||
pv.var = self.records[0].id
|
||||
pv.position = po.id
|
||||
pv.d_var = p.d_up
|
||||
pv.d_cvar = p.d_es
|
||||
pv.d_cdar = p.d_drop
|
||||
pv.whatif = (1 + l.whatif/100) if l.whatif else 1
|
||||
PosVar.save([pv])
|
||||
Var = Pool().get('risk.var')
|
||||
v = Var(rv)
|
||||
d_up,d_es,d_drop = self.get_var('historical', last_var)
|
||||
v.var_his = d_up
|
||||
v.cvar_his = d_es
|
||||
v.cdar_his = d_drop
|
||||
d_up,d_es,d_drop = self.get_var('parametric', last_var)
|
||||
v.var_par = d_up
|
||||
v.cvar_par = d_es
|
||||
v.cdar_par = d_drop
|
||||
d_up,d_es,d_drop = self.get_var('montecarlo', last_var)
|
||||
v.var_mc = d_up
|
||||
v.cvar_mc = d_es
|
||||
v.cdar_mc = d_drop
|
||||
d_up,d_es,d_drop = self.get_var('garch', last_var)
|
||||
v.var_gar = d_up
|
||||
v.cvar_gar = d_es
|
||||
v.cdar_gar = d_drop
|
||||
Var.save([v])
|
||||
return 'end'
|
||||
|
||||
class VarGetPos(Wizard):
|
||||
"Get position"
|
||||
__name__ = "risk.var.get"
|
||||
|
||||
start = StateTransition()
|
||||
|
||||
def get_curve(self,month,market):
|
||||
Price = Pool().get('price.price')
|
||||
PM = Pool().get('product.month')
|
||||
pm = PM.search([('month_name','=',month)])
|
||||
if pm:
|
||||
price = Price.search([('price_desc','=',market),('price_period','=',pm[0])])
|
||||
if price:
|
||||
return price[0].id
|
||||
|
||||
def transition_start(self):
|
||||
rv = self.records[0]
|
||||
Pos = Pool().get('risk.position.process')
|
||||
if rv.market:
|
||||
pos = Pos.search([('future_market','=',rv.market)])
|
||||
else:
|
||||
pos = Pos.search([])
|
||||
if pos:
|
||||
VarLine = Pool().get('risk.var.line')
|
||||
tot_quantity = sum([e.quantity for e in pos])
|
||||
logger.info("TOTQAUNTITY:%s",tot_quantity)
|
||||
for p in pos:
|
||||
vl = VarLine()
|
||||
vl.var = rv.id
|
||||
vl.month = p.month
|
||||
vl.future_market = p.future_market
|
||||
if rv.model:
|
||||
vl.model = rv.model
|
||||
else:
|
||||
vl.model = 'norm'
|
||||
vl.curve = self.get_curve(p.month,p.future_market)
|
||||
# if tot_quantity > 0:
|
||||
# vl.weight = p.quantity / tot_quantity
|
||||
VarLine.save([vl])
|
||||
|
||||
return 'end'
|
||||
128
modules/risk/myvar.xml
Executable file
128
modules/risk/myvar.xml
Executable file
@@ -0,0 +1,128 @@
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="var_view_tree">
|
||||
<field name="model">risk.var</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">var_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="var_view_form">
|
||||
<field name="model">risk.var</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">var_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window" id="act_var_form">
|
||||
<field name="name">VaR</field>
|
||||
<field name="res_model">risk.var</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_var_form_view">
|
||||
<field name="sequence" eval="35"/>
|
||||
<field name="view" ref="var_view_form"/>
|
||||
<field name="act_window" ref="act_var_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_var_form_view2">
|
||||
<field name="sequence" eval="25"/>
|
||||
<field name="view" ref="var_view_tree"/>
|
||||
<field name="act_window" ref="act_var_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="perf_view_tree">
|
||||
<field name="model">risk.perf</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">perf_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="perf_view_graph">
|
||||
<field name="model">risk.perf</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="name">perf_graph</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="perf_view_graph2">
|
||||
<field name="model">risk.perf</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="name">perf_graph2</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="var_line_view_tree">
|
||||
<field name="model">risk.var.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">var_line_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="var_line_view_form">
|
||||
<field name="model">risk.var.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">var_line_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_var_line_form">
|
||||
<field name="name">Line</field>
|
||||
<field name="res_model">risk.var.line</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_var_line_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="var_line_view_tree"/>
|
||||
<field name="act_window" ref="act_var_line_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_var_line_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="var_line_view_form"/>
|
||||
<field name="act_window" ref="act_var_line_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="var_values_view_tree">
|
||||
<field name="model">risk.var.values</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">var_values_tree</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.wizard" id="act_var">
|
||||
<field name="name">Execute VaR</field>
|
||||
<field name="wiz_name">risk.var.execute</field>
|
||||
<field name="model">risk.var</field>
|
||||
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="act_var_keyword">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">risk.var,-1</field>
|
||||
<field name="action" ref="act_var"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.wizard" id="act_get_position">
|
||||
<field name="name">Get position template</field>
|
||||
<field name="wiz_name">risk.var.get</field>
|
||||
<field name="model">risk.var</field>
|
||||
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="act_get_position_keyword">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">risk.var,-1</field>
|
||||
<field name="action" ref="act_get_position"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.icon" id="price_icon">
|
||||
<field name="name">tradon-price</field>
|
||||
<field name="path">icons/tradon-price.svg</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Risk"
|
||||
sequence="41"
|
||||
id="menu_risk_"
|
||||
icon="tradon-price"/>
|
||||
<menuitem
|
||||
parent="menu_risk_"
|
||||
sequence="91"
|
||||
action="act_var_form"
|
||||
id="menu_var_form"/>
|
||||
<!-- <menuitem
|
||||
parent="menu_risk"
|
||||
sequence="101"
|
||||
action="act_var"
|
||||
id="menu_var"/> -->
|
||||
<!-- <record model="ir.module.config_wizard.item" id="config_wizard_item_var">
|
||||
<field name="action" ref="act_var"/>
|
||||
</record> -->
|
||||
</data>
|
||||
</tryton>
|
||||
367
modules/risk/position.py
Normal file
367
modules/risk/position.py
Normal file
@@ -0,0 +1,367 @@
|
||||
import stdnum.exceptions
|
||||
from sql import Column, Literal
|
||||
import datetime
|
||||
from sql.aggregate import Count, Max, Min, Sum, Avg, BoolOr
|
||||
from sql.conditionals import Case
|
||||
from stdnum import get_cc_module
|
||||
from sql.functions import CharLength, CurrentTimestamp, DateTrunc, Extract
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, MultiValueMixin, Unique,
|
||||
ValueMixin, convert_from, fields, sequence_ordered)
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
from trytond.transaction import Transaction, inactive_records
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
from decimal import Decimal
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class PositionVar(ModelSQL, ModelView):
|
||||
"Position var"
|
||||
__name__ = 'risk.position.var'
|
||||
|
||||
var = fields.Many2One('risk.var',"Var")
|
||||
position = fields.Many2One('risk.position',"Position")
|
||||
d_var = fields.Numeric("VaR")
|
||||
d_cvar = fields.Numeric("CVaR")
|
||||
d_cdar = fields.Numeric("CDaR")
|
||||
whatif = fields.Numeric("Whatif")
|
||||
|
||||
@classmethod
|
||||
def default_whatif(cls):
|
||||
return 1
|
||||
|
||||
|
||||
class Position(ModelSQL, ModelView):
|
||||
"Position"
|
||||
__name__ = 'risk.position'
|
||||
|
||||
commodity = fields.Char("Commodity")
|
||||
type = fields.Char("Type")
|
||||
trader = fields.Char("Trader")
|
||||
reference = fields.Char("Reference")
|
||||
product = fields.Char("Product")
|
||||
origin = fields.Char("Origin")
|
||||
future_market = fields.Char("Future market")
|
||||
currency = fields.Char("Currency")
|
||||
month = fields.Char("Month")
|
||||
ct_type = fields.Char("Ct type")
|
||||
quantity = fields.Numeric("Quantity")
|
||||
basis = fields.Numeric("Basis")
|
||||
price = fields.Numeric("Price")
|
||||
pricing_type = fields.Char("Pricing type")
|
||||
var = fields.Numeric("VaR")
|
||||
cvar = fields.Numeric("CVaR")
|
||||
cdar = fields.Numeric("CDaR")
|
||||
whatif = fields.Numeric("Whatif")
|
||||
|
||||
@classmethod
|
||||
def default_whatif(cls):
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
_, operator, operand, *extra = clause
|
||||
if operator.startswith('!') or operator.startswith('not '):
|
||||
bool_op = 'AND'
|
||||
else:
|
||||
bool_op = 'OR'
|
||||
code_value = operand
|
||||
if operator.endswith('like') and is_full_text(operand):
|
||||
code_value = lstrip_wildcard(operand)
|
||||
return [bool_op,
|
||||
('commodity', operator, operand, *extra),
|
||||
('trader', operator, operand, *extra),
|
||||
('product', operator, operand, *extra),
|
||||
('origin', operator, operand, *extra),
|
||||
]
|
||||
|
||||
class PositionReport(ModelSQL, ModelView):
|
||||
"Position report"
|
||||
__name__ = 'risk.position.report'
|
||||
|
||||
commodity = fields.Char("Commodity")
|
||||
type = fields.Char("Type")
|
||||
trader = fields.Char("Trader")
|
||||
reference = fields.Char("Reference")
|
||||
product = fields.Char("Product")
|
||||
origin = fields.Char("Origin")
|
||||
future_market = fields.Char("Future market")
|
||||
currency = fields.Char("Currency")
|
||||
month = fields.Char("Month")
|
||||
ct_type = fields.Char("Ct type")
|
||||
quantity = fields.Numeric("Quantity")
|
||||
basis = fields.Numeric("Basis")
|
||||
price = fields.Numeric("Price")
|
||||
pricing_type = fields.Char("Pricing type")
|
||||
var = fields.Numeric("VaR")
|
||||
cvar = fields.Numeric("CVaR")
|
||||
cdar = fields.Numeric("CDaR")
|
||||
var_amount = fields.Numeric("VaR amt")
|
||||
cvar_amount = fields.Numeric("CVaR amt")
|
||||
cdar_amount = fields.Numeric("CDaR amt")
|
||||
whatif = fields.Numeric("Whatif")
|
||||
|
||||
@classmethod
|
||||
def table_query(cls):
|
||||
pool = Pool()
|
||||
Pos = pool.get('risk.position')
|
||||
pos = Pos.__table__()
|
||||
Pos_var = pool.get('risk.position.var')
|
||||
pos2 = Pos_var.__table__()
|
||||
context = Transaction().context
|
||||
trader = context.get('trader')
|
||||
product = context.get('product')
|
||||
month = context.get('month')
|
||||
market = context.get('market')
|
||||
asof = context.get('asof')
|
||||
todate = context.get('todate')
|
||||
var = context.get('var')
|
||||
groupby = context.get('groupby')
|
||||
wh = (((pos.quantity >= 0) & (pos.create_date >= asof) & ((pos.create_date-datetime.timedelta(1)) <= todate)))
|
||||
if trader:
|
||||
wh &= (pos.trader == trader)
|
||||
if product:
|
||||
wh &= (pos.product == product)
|
||||
if month:
|
||||
wh &= (pos.month == month)
|
||||
if market:
|
||||
wh &= (pos.future_market == market)
|
||||
if var:
|
||||
wh &= (pos2.var == var)
|
||||
|
||||
if groupby == None:
|
||||
query = pos.join(pos2,'LEFT',condition=pos.id == pos2.position).select(
|
||||
Literal(0).as_('create_uid'),
|
||||
CurrentTimestamp().as_('create_date'),
|
||||
Literal(None).as_('write_uid'),
|
||||
Literal(None).as_('write_date'),
|
||||
pos.id.as_('id'),
|
||||
pos.commodity.as_('commodity'),
|
||||
pos.type.as_('type'),
|
||||
pos.trader.as_('trader'),
|
||||
pos.reference.as_('reference'),
|
||||
pos.product.as_('product'),
|
||||
pos.origin.as_('origin'),
|
||||
pos.future_market.as_('future_market'),
|
||||
pos.currency.as_('currency'),
|
||||
pos.month.as_('month'),
|
||||
pos.ct_type.as_('ct_type'),
|
||||
pos.quantity.as_('quantity'),
|
||||
pos.basis.as_('basis'),
|
||||
pos.price.as_('price'),
|
||||
pos.pricing_type.as_('pricing_type'),
|
||||
pos2.d_var.as_('var'),
|
||||
pos2.d_cvar.as_('cvar'),
|
||||
pos2.d_cdar.as_('cdar'),
|
||||
(pos2.d_var * pos.quantity * pos.price * pos2.whatif).as_('var_amount'),
|
||||
(pos2.d_cvar * pos.quantity * pos.price).as_('cvar_amount'),
|
||||
(pos2.d_cdar * pos.quantity * pos.price).as_('cdar_amount'),
|
||||
(pos.whatif).as_('whatif'),
|
||||
where=wh)
|
||||
elif groupby == 'commo':
|
||||
query = pos.join(pos2,'LEFT',condition=pos.id == pos2.position).select(
|
||||
Literal(0).as_('create_uid'),
|
||||
CurrentTimestamp().as_('create_date'),
|
||||
Literal(None).as_('write_uid'),
|
||||
Literal(None).as_('write_date'),
|
||||
Max(pos.id).as_('id'),
|
||||
pos.commodity.as_('commodity'),
|
||||
Max(pos.type).as_('type'),
|
||||
Max(pos.trader).as_('trader'),
|
||||
Max(pos.reference).as_('reference'),
|
||||
Max(pos.product).as_('product'),
|
||||
Max(pos.origin).as_('origin'),
|
||||
Max(pos.future_market).as_('future_market'),
|
||||
Max(pos.currency).as_('currency'),
|
||||
Max(pos.month).as_('month'),
|
||||
Max(pos.ct_type).as_('ct_type'),
|
||||
Sum(pos.quantity).as_('quantity'),
|
||||
Avg(pos.basis).as_('basis'),
|
||||
Avg(pos.price).as_('price'),
|
||||
Max(pos.pricing_type).as_('pricing_type'),
|
||||
Avg(pos2.d_var).as_('var'),
|
||||
Avg(pos2.d_cvar).as_('cvar'),
|
||||
Avg(pos2.d_cdar).as_('cdar'),
|
||||
Sum(pos2.d_var * pos.quantity * pos.price * pos2.whatif).as_('var_amount'),
|
||||
Sum(pos2.d_cvar * pos.quantity * pos.price).as_('cvar_amount'),
|
||||
Sum(pos2.d_cdar * pos.quantity * pos.price).as_('cdar_amount'),
|
||||
Avg(pos.whatif).as_('whatif'),
|
||||
where=wh,
|
||||
group_by=[pos.commodity])
|
||||
elif groupby == 'market':
|
||||
query = pos.join(pos2,'LEFT',condition=pos.id == pos2.position).select(
|
||||
Literal(0).as_('create_uid'),
|
||||
CurrentTimestamp().as_('create_date'),
|
||||
Literal(None).as_('write_uid'),
|
||||
Literal(None).as_('write_date'),
|
||||
Max(pos.id).as_('id'),
|
||||
Max(pos.commodity).as_('commodity'),
|
||||
Max(pos.type).as_('type'),
|
||||
Max(pos.trader).as_('trader'),
|
||||
Max(pos.reference).as_('reference'),
|
||||
Max(pos.product).as_('product'),
|
||||
Max(pos.origin).as_('origin'),
|
||||
pos.future_market.as_('future_market'),
|
||||
Max(pos.currency).as_('currency'),
|
||||
Max(pos.month).as_('month'),
|
||||
Max(pos.ct_type).as_('ct_type'),
|
||||
Sum(pos.quantity).as_('quantity'),
|
||||
Avg(pos.basis).as_('basis'),
|
||||
Avg(pos.price).as_('price'),
|
||||
Max(pos.pricing_type).as_('pricing_type'),
|
||||
Avg(pos2.d_var).as_('var'),
|
||||
Avg(pos2.d_cvar).as_('cvar'),
|
||||
Avg(pos2.d_cdar).as_('cdar'),
|
||||
Sum(pos2.d_var * pos.quantity * pos.price * pos2.whatif).as_('var_amount'),
|
||||
Sum(pos2.d_cvar * pos.quantity * pos.price).as_('cvar_amount'),
|
||||
Sum(pos2.d_cdar * pos.quantity * pos.price).as_('cdar_amount'),
|
||||
Avg(pos.whatif).as_('whatif'),
|
||||
where=wh,
|
||||
group_by=[pos.future_market])
|
||||
elif groupby == 'month':
|
||||
query = pos.join(pos2,'LEFT',condition=pos.id == pos2.position).select(
|
||||
Literal(0).as_('create_uid'),
|
||||
CurrentTimestamp().as_('create_date'),
|
||||
Literal(None).as_('write_uid'),
|
||||
Literal(None).as_('write_date'),
|
||||
Max(pos.id).as_('id'),
|
||||
Max(pos.commodity).as_('commodity'),
|
||||
Max(pos.type).as_('type'),
|
||||
Max(pos.trader).as_('trader'),
|
||||
Max(pos.reference).as_('reference'),
|
||||
Max(pos.product).as_('product'),
|
||||
Max(pos.origin).as_('origin'),
|
||||
pos.future_market.as_('future_market'),
|
||||
Max(pos.currency).as_('currency'),
|
||||
pos.month.as_('month'),
|
||||
Max(pos.ct_type).as_('ct_type'),
|
||||
Sum(pos.quantity).as_('quantity'),
|
||||
Avg(pos.basis).as_('basis'),
|
||||
Avg(pos.price).as_('price'),
|
||||
Max(pos.pricing_type).as_('pricing_type'),
|
||||
Avg(pos2.d_var).as_('var'),
|
||||
Avg(pos2.d_cvar).as_('cvar'),
|
||||
Avg(pos2.d_cdar).as_('cdar'),
|
||||
Sum(pos2.d_var * pos.quantity * pos.price * pos2.whatif).as_('var_amount'),
|
||||
Sum(pos2.d_cvar * pos.quantity * pos.price).as_('cvar_amount'),
|
||||
Sum(pos2.d_cdar * pos.quantity * pos.price).as_('cdar_amount'),
|
||||
Avg(pos.whatif).as_('whatif'),
|
||||
where=wh,
|
||||
group_by=[pos.future_market,pos.month])
|
||||
return query
|
||||
|
||||
@classmethod
|
||||
def view_attributes(cls):
|
||||
return super().view_attributes() + [
|
||||
('/tree/field[@name="trader"]', 'tree_invisible',
|
||||
(Eval('groupby')!=None)),
|
||||
('/tree/field[@name="product"]', 'tree_invisible',
|
||||
(Eval('groupby')!=None)),
|
||||
('/tree/field[@name="future_market"]', 'tree_invisible',
|
||||
(Eval('groupby')=='commo')),
|
||||
('/tree/field[@name="month"]', 'tree_invisible',
|
||||
(Eval('groupby').in_(['market', 'commo']))),
|
||||
]
|
||||
|
||||
class PositionProcess(ModelSQL, ModelView):
|
||||
"Position process"
|
||||
__name__ = 'risk.position.process'
|
||||
|
||||
future_market = fields.Char("Future market")
|
||||
month = fields.Char("Month")
|
||||
quantity = fields.Numeric("Quantity")
|
||||
|
||||
@classmethod
|
||||
def table_query(cls):
|
||||
pool = Pool()
|
||||
Pos = pool.get('risk.position')
|
||||
pos = Pos.__table__()
|
||||
wh = ((pos.pricing_type != 'Priced') & (pos.ct_type != 'Inventory') & (pos.quantity > 0))
|
||||
query = pos.select(
|
||||
Literal(0).as_('create_uid'),
|
||||
CurrentTimestamp().as_('create_date'),
|
||||
Literal(None).as_('write_uid'),
|
||||
Literal(None).as_('write_date'),
|
||||
Max(pos.id).as_('id'),
|
||||
pos.future_market.as_('future_market'),
|
||||
pos.month.as_('month'),
|
||||
Sum(pos.quantity).as_('quantity'),
|
||||
where=wh,
|
||||
group_by=[pos.future_market,pos.month])
|
||||
return query
|
||||
|
||||
class PositionContext(ModelView):
|
||||
"Lot Context"
|
||||
__name__ = 'risk.position.context'
|
||||
|
||||
asof = fields.Date("As of")
|
||||
todate = fields.Date("To")
|
||||
trader = fields.Selection([
|
||||
(None, ''),
|
||||
("Simon Bourqui", "Simon Bourqui"),
|
||||
("Jean-Christophe Mani", "Jean-Christophe Mani"),
|
||||
("Gregoire Davidoff", "Gregoire Davidoff"),
|
||||
("Pablo Rapun","Pablo Rapun"),
|
||||
("Riccardo Zanin","Riccardo Zanin"),
|
||||
("Antoine Bonnot","Antoine Bonnot"),
|
||||
("Eric Bourgeois","Eric Bourgeois")
|
||||
],"Trader")
|
||||
product = fields.Selection([
|
||||
(None, ''),
|
||||
("Coffee", "Coffee"),
|
||||
("Cocoa", "Cocoa"),
|
||||
],"Product")
|
||||
month = fields.Selection([
|
||||
(None, ''),
|
||||
("Mar-24", "Mar-24"),
|
||||
("Jul-24", "Jul-24"),
|
||||
("Mar-26", "Mar-26"),
|
||||
("Dec-24","Dec-24"),
|
||||
("Dec-23","Dec-23"),
|
||||
("Nov-24","Nov-24"),
|
||||
("Dec-25","Dec-25"),
|
||||
("Sep-24", "Sep-24"),
|
||||
("Jul-25", "Jul-25"),
|
||||
("Mar-25", "Mar-25"),
|
||||
("May-25","May-25"),
|
||||
("May-24","May-24"),
|
||||
("Sep-25","Sep-25")
|
||||
],"Month")
|
||||
market = fields.Selection([
|
||||
(None, ''),
|
||||
("Coffee ICE US", "Coffee ICE US"),
|
||||
("Cocoa ICE US", "Cocoa ICE US"),
|
||||
("Coffee ICE EU", "Coffee ICE EU"),
|
||||
("Cocoa ICE EU", "Cocoa ICE EU")
|
||||
],"Market")
|
||||
var = fields.Many2One('risk.var',"VaR template",domain=[('execute','=',True)])
|
||||
groupby = fields.Selection([
|
||||
(None, ''),
|
||||
("commo", "Commodity"),
|
||||
("market", "Market"),
|
||||
("month", "Month"),
|
||||
],"Group by")
|
||||
|
||||
@classmethod
|
||||
def default_asof(cls):
|
||||
pool = Pool()
|
||||
Date = pool.get('ir.date')
|
||||
return Date.today().replace(day=1,month=1,year=1999)
|
||||
|
||||
@classmethod
|
||||
def default_todate(cls):
|
||||
pool = Pool()
|
||||
Date = pool.get('ir.date')
|
||||
return Date.today()
|
||||
|
||||
@classmethod
|
||||
def default_var(cls):
|
||||
Var = Pool().get('risk.var')
|
||||
var = Var.search([('execute','=',True)])
|
||||
if var:
|
||||
return var[0].id
|
||||
67
modules/risk/position.xml
Normal file
67
modules/risk/position.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="pos_view_tree">
|
||||
<field name="model">risk.position</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">pos_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="pos_view_form">
|
||||
<field name="model">risk.position</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">pos_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="pos_report_view_tree">
|
||||
<field name="model">risk.position.report</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">pos_report_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="pos_report_context_view_form">
|
||||
<field name="model">risk.position.context</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">pos_report_context_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_pos_report_form">
|
||||
<field name="name">Position report</field>
|
||||
<field name="res_model">risk.position.report</field>
|
||||
<field name="context_model">risk.position.context</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_pos_report_form_view">
|
||||
<field name="sequence" eval="35"/>
|
||||
<field name="view" ref="pos_report_view_tree"/>
|
||||
<field name="act_window" ref="act_pos_report_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window" id="act_pos_form">
|
||||
<field name="name">Position</field>
|
||||
<field name="res_model">risk.position</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_pos_form_view">
|
||||
<field name="sequence" eval="35"/>
|
||||
<field name="view" ref="pos_view_form"/>
|
||||
<field name="act_window" ref="act_pos_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_pos_form_view2">
|
||||
<field name="sequence" eval="25"/>
|
||||
<field name="view" ref="pos_view_tree"/>
|
||||
<field name="act_window" ref="act_pos_form"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_risk_"
|
||||
sequence="95"
|
||||
action="act_pos_form"
|
||||
id="menu_pos_form"/>
|
||||
<menuitem
|
||||
parent="menu_risk_"
|
||||
sequence="100"
|
||||
action="act_pos_report_form"
|
||||
id="menu_pos_report_form"/>
|
||||
</data>
|
||||
</tryton>
|
||||
133
modules/risk/risk.py
Executable file
133
modules/risk/risk.py
Executable file
@@ -0,0 +1,133 @@
|
||||
import stdnum.exceptions
|
||||
import logging
|
||||
from sql import Column, Literal
|
||||
from sql.aggregate import Min
|
||||
from sql.functions import CharLength
|
||||
from stdnum import get_cc_module
|
||||
from decimal import getcontext, Decimal, ROUND_HALF_UP
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, MultiValueMixin, Unique,
|
||||
ValueMixin, convert_from, fields, sequence_ordered)
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Bool, Eval
|
||||
from trytond.tools import is_full_text, lstrip_wildcard
|
||||
from trytond.transaction import Transaction, inactive_records
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
from datetime import date, timedelta, datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Price(
|
||||
DeactivableMixin, ModelSQL, ModelView,
|
||||
MultiValueMixin):
|
||||
"Price"
|
||||
__name__ = 'price.price'
|
||||
_rec_name = 'price_index'
|
||||
price = fields.Many2One('price.price',"Composite")
|
||||
price_index = fields.Char("Price index", required=True)
|
||||
price_desc = fields.Char("Description", required=True)
|
||||
price_period = fields.Many2One('product.month',"Period")
|
||||
price_curve_type = fields.Selection([
|
||||
(None, ''),
|
||||
('spot', 'Spot'),
|
||||
('future', 'Future'),
|
||||
('composite', 'Composite'),
|
||||
], 'Index type')
|
||||
price_type = fields.Many2One('price.fixtype', "Fixation type")
|
||||
price_unit = fields.Many2One('product.uom', "Unit")
|
||||
price_currency = fields.Many2One('currency.currency', "Currency")
|
||||
price_area = fields.Many2One('price.area',"Market area")
|
||||
price_calendar = fields.Many2One('price.calendar',"Calendar")
|
||||
price_values = fields.One2Many('price.price_value', 'price', "Prices Values")
|
||||
price_composite = fields.One2Many('price.composite','price',"Composites")
|
||||
price_product = fields.One2Many('price.product', 'price', "Product")
|
||||
price_ct_size = fields.Numeric("Ct size")
|
||||
|
||||
def get_qt(self,nb_ct,unit):
|
||||
Uom = Pool().get('product.uom')
|
||||
return round(Decimal(Uom.compute_qty(self.price_unit, float(self.price_ct_size * nb_ct), unit)),2)
|
||||
|
||||
def get_price_per_qt(self,price,unit,currency):
|
||||
price_qt = float(0)
|
||||
Uom = Pool().get('product.uom')
|
||||
Currency = Pool().get('currency.currency')
|
||||
rates = Currency._get_rate([self.price_currency])
|
||||
if rates[self.price_currency.id]:
|
||||
price_qt = float(price) * Uom.compute_qty(unit, float(1), self.price_unit) * float(rates[self.price_currency.id])
|
||||
return round(price_qt,2)
|
||||
|
||||
def get_amount_nb_ct(self,price,nb_ct,unit,currency):
|
||||
amount = Decimal(0)
|
||||
Uom = Pool().get('product.uom')
|
||||
if price:
|
||||
amount = Decimal(self.get_price_per_qt(price,unit,currency)) * Decimal(Uom.compute_qty(self.price_unit, float(self.price_ct_size * nb_ct), unit))
|
||||
return round(amount,2)
|
||||
|
||||
def get_price(self,dt,unit,currency,last=False):
|
||||
price = float(0)
|
||||
PV = Pool().get('price.price_value')
|
||||
if self.price_values:
|
||||
dt = dt.strftime("%Y-%m-%d")
|
||||
pv = PV.search([('price','=',self.id),('price_date','=',dt)])
|
||||
if not pv and last:
|
||||
pv = PV.search([('price','=',self.id)],order=[('price_date', 'DESC')])
|
||||
if pv:
|
||||
price = self.get_price_per_qt(pv[0].price_value,unit,currency)
|
||||
return round(price,2)
|
||||
|
||||
class FixType(ModelSQL,ModelView):
|
||||
"Fixation type"
|
||||
__name__ = 'price.fixtype'
|
||||
name = fields.Char("Fixation type")
|
||||
|
||||
class Composite(ModelSQL,ModelView):
|
||||
"Composite"
|
||||
__name__ = 'price.composite'
|
||||
price = fields.Many2One(
|
||||
'price.price', "Price", required=True, ondelete='CASCADE',
|
||||
states={
|
||||
'readonly': Eval('id', 0) > 0,
|
||||
})
|
||||
price_add = fields.Many2One('price.price',"Price index")
|
||||
ratio = fields.Numeric("%")
|
||||
|
||||
class MarketArea(ModelSQL,ModelView):
|
||||
"Market Area"
|
||||
__name__ = 'price.area'
|
||||
name = fields.Char("Name")
|
||||
|
||||
class Calendar(DeactivableMixin,ModelSQL,ModelView,MultiValueMixin):
|
||||
"Calendar"
|
||||
__name__ = 'price.calendar'
|
||||
name = fields.Char("Name")
|
||||
calendar_line = fields.One2Many('price.calendar.line','calendar',"Calendar lines")
|
||||
|
||||
def IsQuote(self,dt):
|
||||
CL = Pool().get('price.calendar.line')
|
||||
if self.calendar_line:
|
||||
dt = dt.strftime("%Y-%m-%d")
|
||||
cl = CL.search([('calendar','=',self.id),('price_date','=',dt)])
|
||||
if cl:
|
||||
logger.info("ISQUOTE:%s",cl)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
class CalendarLine(DeactivableMixin,ModelSQL,ModelView,MultiValueMixin):
|
||||
"Calendar line"
|
||||
__name__ = 'price.calendar.line'
|
||||
calendar = fields.Many2One('price.calendar',"Calendar")
|
||||
price_date = fields.Date("Date")
|
||||
price_state = fields.Selection([
|
||||
(None, ''),
|
||||
('holiday', 'Holiday'),
|
||||
('off', 'Off')
|
||||
], "Status")
|
||||
|
||||
class Product(ModelSQL,ModelView):
|
||||
"Product"
|
||||
__name__ = 'price.product'
|
||||
price = fields.Many2One('price.price',"Price index")
|
||||
product = fields.Many2One('product.product',"Product")
|
||||
220
modules/risk/risk.xml
Executable file
220
modules/risk/risk.xml
Executable file
@@ -0,0 +1,220 @@
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="res.group" id="group_price_admin">
|
||||
<field name="name">Price Administration</field>
|
||||
</record>
|
||||
<record model="res.user-res.group"
|
||||
id="user_admin_group_price_admin">
|
||||
<field name="user" ref="res.user_admin"/>
|
||||
<field name="group" ref="group_price_admin"/>
|
||||
</record>
|
||||
<record model="ir.ui.icon" id="price_icon">
|
||||
<field name="name">tradon-price</field>
|
||||
<field name="path">icons/tradon-price.svg</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Prices"
|
||||
sequence="40"
|
||||
id="menu_price"
|
||||
icon="tradon-price"/>
|
||||
<record model="ir.ui.view" id="price_view_tree">
|
||||
<field name="model">price.price</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">price_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="price_view_tree_sequence">
|
||||
<field name="model">price.price</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">price_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="price_view_form">
|
||||
<field name="model">price.price</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">price_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="composite_view_tree">
|
||||
<field name="model">price.composite</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">composite_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="composite_view_tree_sequence">
|
||||
<field name="model">price.composite</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">composite_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="composite_view_form">
|
||||
<field name="model">price.composite</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">composite_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_composite_form">
|
||||
<field name="name">Composite</field>
|
||||
<field name="res_model">price.composite</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_composite_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="composite_view_tree"/>
|
||||
<field name="act_window" ref="act_composite_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_composite_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="composite_view_form"/>
|
||||
<field name="act_window" ref="act_composite_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_composite_form_view3">
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="view" ref="composite_view_tree_sequence"/>
|
||||
<field name="act_window" ref="act_composite_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fixtype_view_tree">
|
||||
<field name="model">price.fixtype</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">fixtype_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="fixtype_view_tree_sequence">
|
||||
<field name="model">price.fixtype</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">fixtype_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="fixtype_view_form">
|
||||
<field name="model">price.fixtype</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">fixtype_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="area_view_tree">
|
||||
<field name="model">price.area</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">area_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="area_view_tree_sequence">
|
||||
<field name="model">price.area</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">area_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="area_view_form">
|
||||
<field name="model">price.area</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">area_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="calendar_view_tree">
|
||||
<field name="model">price.calendar</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">calendar_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calendar_view_tree_sequence">
|
||||
<field name="model">price.calendar</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">calendar_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calendar_view_form">
|
||||
<field name="model">price.calendar</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">calendar_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="calendar_line_view_calendar">
|
||||
<field name="model">price.calendar.line</field>
|
||||
<field name="type">calendar</field>
|
||||
<field name="priority" eval="40"/>
|
||||
<field name="name">calendar_line_calendar</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calendar_line_view_tree">
|
||||
<field name="model">price.calendar.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">calendar_line_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calendar_line_view_tree_sequence">
|
||||
<field name="model">price.calendar.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">calendar_line_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="calendar_line_view_form">
|
||||
<field name="model">price.calendar.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="30"/>
|
||||
<field name="name">calendar_line_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_view_tree">
|
||||
<field name="model">price.product</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">product_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_view_tree_sequence">
|
||||
<field name="model">price.product</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">product_tree_sequence</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_view_form">
|
||||
<field name="model">price.product</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">product_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window" id="act_price_form">
|
||||
<field name="name">Price</field>
|
||||
<field name="res_model">price.price</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_price_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="price_view_tree"/>
|
||||
<field name="act_window" ref="act_price_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_price_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="price_view_form"/>
|
||||
<field name="act_window" ref="act_price_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window" id="act_calendar_form">
|
||||
<field name="name">Calendar</field>
|
||||
<field name="res_model">price.calendar</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_calendar_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="calendar_view_tree"/>
|
||||
<field name="act_window" ref="act_calendar_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_calendar_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="calendar_view_form"/>
|
||||
<field name="act_window" ref="act_calendar_form"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_price"
|
||||
sequence="80"
|
||||
action="act_price_form"
|
||||
id="menu_price_form"/>
|
||||
<menuitem
|
||||
parent="menu_price"
|
||||
sequence="1500"
|
||||
action="act_calendar_form"
|
||||
id="menu_calendar_form"/>
|
||||
</data>
|
||||
</tryton>
|
||||
127
modules/risk/setup.py
Executable file
127
modules/risk/setup.py
Executable file
@@ -0,0 +1,127 @@
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
from configparser import ConfigParser
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
|
||||
def read(fname):
|
||||
content = io.open(
|
||||
os.path.join(os.path.dirname(__file__), fname),
|
||||
'r', encoding='utf-8').read()
|
||||
content = re.sub(
|
||||
r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
|
||||
return content
|
||||
|
||||
|
||||
def get_require_version(name):
|
||||
require = '%s >= %s.%s, < %s.%s'
|
||||
require %= (name, major_version, minor_version,
|
||||
major_version, minor_version + 1)
|
||||
return require
|
||||
|
||||
|
||||
config = ConfigParser()
|
||||
config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
|
||||
info = dict(config.items('tryton'))
|
||||
for key in ('depends', 'extras_depend', 'xml'):
|
||||
if key in info:
|
||||
info[key] = info[key].strip().splitlines()
|
||||
version = info.get('version', '0.0.1')
|
||||
major_version, minor_version, _ = version.split('.', 2)
|
||||
major_version = int(major_version)
|
||||
minor_version = int(minor_version)
|
||||
name = 'trytond_risk'
|
||||
|
||||
if minor_version % 2:
|
||||
download_url = ''
|
||||
else:
|
||||
download_url = 'http://downloads.tryton.org/%s.%s/' % (
|
||||
major_version, minor_version)
|
||||
|
||||
requires = ['python-sql >= 0.4', 'python-stdnum >= 1.15']
|
||||
for dep in info.get('depends', []):
|
||||
if not re.match(r'(ir|res)(\W|$)', dep):
|
||||
requires.append(get_require_version('trytond_%s' % dep))
|
||||
requires.append(get_require_version('trytond'))
|
||||
|
||||
tests_require = [get_require_version('proteus'), 'phonenumbers']
|
||||
|
||||
setup(name=name,
|
||||
version=version,
|
||||
description='Tryton module with parties and addresses',
|
||||
author='Tryton',
|
||||
author_email='foundation@tryton.org',
|
||||
url='http://www.tryton.org/',
|
||||
download_url=download_url,
|
||||
project_urls={
|
||||
"Bug Tracker": 'https://bugs.tryton.org/',
|
||||
"Forum": 'https://www.tryton.org/forum',
|
||||
"Source Code": 'https://code.tryton.org/tryton',
|
||||
},
|
||||
keywords='tryton risk',
|
||||
package_dir={'trytond.modules.risk': '.'},
|
||||
packages=(
|
||||
['trytond.modules.risk']
|
||||
+ ['trytond.modules.risk.%s' % p for p in find_packages()]
|
||||
),
|
||||
package_data={
|
||||
'trytond.modules.risk': (info.get('xml', [])
|
||||
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
|
||||
'icons/*.svg', 'tests/*.rst']),
|
||||
},
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
'Framework :: Tryton',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Financial and Insurance Industry',
|
||||
'Intended Audience :: Legal Industry',
|
||||
'Intended Audience :: Manufacturing',
|
||||
'License :: OSI Approved :: '
|
||||
'GNU General Public License v3 or later (GPLv3+)',
|
||||
'Natural Language :: Bulgarian',
|
||||
'Natural Language :: Catalan',
|
||||
'Natural Language :: Chinese (Simplified)',
|
||||
'Natural Language :: Czech',
|
||||
'Natural Language :: Dutch',
|
||||
'Natural Language :: English',
|
||||
'Natural Language :: Finnish',
|
||||
'Natural Language :: French',
|
||||
'Natural Language :: German',
|
||||
'Natural Language :: Hungarian',
|
||||
'Natural Language :: Indonesian',
|
||||
'Natural Language :: Italian',
|
||||
'Natural Language :: Persian',
|
||||
'Natural Language :: Polish',
|
||||
'Natural Language :: Portuguese (Brazilian)',
|
||||
'Natural Language :: Romanian',
|
||||
'Natural Language :: Russian',
|
||||
'Natural Language :: Slovenian',
|
||||
'Natural Language :: Spanish',
|
||||
'Natural Language :: Turkish',
|
||||
'Natural Language :: Ukrainian',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: 3.9',
|
||||
'Programming Language :: Python :: 3.10',
|
||||
'Programming Language :: Python :: 3.11',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Topic :: Office/Business',
|
||||
],
|
||||
license='GPL-3',
|
||||
python_requires='>=3.8',
|
||||
install_requires=requires,
|
||||
extras_require={
|
||||
'test': tests_require,
|
||||
'VIES': ['python-stdnum[SOAP]'],
|
||||
'phonenumbers': ['phonenumbers'],
|
||||
},
|
||||
zip_safe=False,
|
||||
entry_points="""
|
||||
[trytond.modules]
|
||||
risk = trytond.modules.risk
|
||||
""",
|
||||
)
|
||||
15
modules/risk/tryton.cfg
Executable file
15
modules/risk/tryton.cfg
Executable file
@@ -0,0 +1,15 @@
|
||||
[tryton]
|
||||
version=7.2.7
|
||||
depends:
|
||||
ir
|
||||
res
|
||||
party
|
||||
currency
|
||||
company
|
||||
product
|
||||
product_month
|
||||
price
|
||||
xml:
|
||||
myvar.xml
|
||||
position.xml
|
||||
message.xml
|
||||
54
modules/risk/trytond_risk.egg-info/PKG-INFO
Executable file
54
modules/risk/trytond_risk.egg-info/PKG-INFO
Executable file
@@ -0,0 +1,54 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: trytond-risk
|
||||
Version: 7.2.7
|
||||
Summary: Tryton module with parties and addresses
|
||||
Home-page: http://www.tryton.org/
|
||||
Download-URL: http://downloads.tryton.org/7.2/
|
||||
Author: Tryton
|
||||
Author-email: foundation@tryton.org
|
||||
License: GPL-3
|
||||
Project-URL: Bug Tracker, https://bugs.tryton.org/
|
||||
Project-URL: Forum, https://www.tryton.org/forum
|
||||
Project-URL: Source Code, https://code.tryton.org/tryton
|
||||
Keywords: tryton risk
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Plugins
|
||||
Classifier: Framework :: Tryton
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Intended Audience :: Financial and Insurance Industry
|
||||
Classifier: Intended Audience :: Legal Industry
|
||||
Classifier: Intended Audience :: Manufacturing
|
||||
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
||||
Classifier: Natural Language :: Bulgarian
|
||||
Classifier: Natural Language :: Catalan
|
||||
Classifier: Natural Language :: Chinese (Simplified)
|
||||
Classifier: Natural Language :: Czech
|
||||
Classifier: Natural Language :: Dutch
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Natural Language :: Finnish
|
||||
Classifier: Natural Language :: French
|
||||
Classifier: Natural Language :: German
|
||||
Classifier: Natural Language :: Hungarian
|
||||
Classifier: Natural Language :: Indonesian
|
||||
Classifier: Natural Language :: Italian
|
||||
Classifier: Natural Language :: Persian
|
||||
Classifier: Natural Language :: Polish
|
||||
Classifier: Natural Language :: Portuguese (Brazilian)
|
||||
Classifier: Natural Language :: Romanian
|
||||
Classifier: Natural Language :: Russian
|
||||
Classifier: Natural Language :: Slovenian
|
||||
Classifier: Natural Language :: Spanish
|
||||
Classifier: Natural Language :: Turkish
|
||||
Classifier: Natural Language :: Ukrainian
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Topic :: Office/Business
|
||||
Requires-Python: >=3.8
|
||||
Provides-Extra: VIES
|
||||
Provides-Extra: phonenumbers
|
||||
Provides-Extra: test
|
||||
23
modules/risk/trytond_risk.egg-info/SOURCES.txt
Executable file
23
modules/risk/trytond_risk.egg-info/SOURCES.txt
Executable file
@@ -0,0 +1,23 @@
|
||||
setup.py
|
||||
./__init__.py
|
||||
./ir.py
|
||||
./message.xml
|
||||
./risk.py
|
||||
./tryton.cfg
|
||||
./var.py
|
||||
./var.xml
|
||||
./icons/tradon-price.svg
|
||||
./icons/tryton-trade.svg
|
||||
./view/var_form.xml
|
||||
./view/var_line_form.xml
|
||||
./view/var_line_tree.xml
|
||||
./view/var_tree.xml
|
||||
./view/var_values_form.xml
|
||||
./view/var_values_tree.xml
|
||||
trytond_risk.egg-info/PKG-INFO
|
||||
trytond_risk.egg-info/SOURCES.txt
|
||||
trytond_risk.egg-info/dependency_links.txt
|
||||
trytond_risk.egg-info/entry_points.txt
|
||||
trytond_risk.egg-info/not-zip-safe
|
||||
trytond_risk.egg-info/requires.txt
|
||||
trytond_risk.egg-info/top_level.txt
|
||||
1
modules/risk/trytond_risk.egg-info/dependency_links.txt
Executable file
1
modules/risk/trytond_risk.egg-info/dependency_links.txt
Executable file
@@ -0,0 +1 @@
|
||||
|
||||
2
modules/risk/trytond_risk.egg-info/entry_points.txt
Executable file
2
modules/risk/trytond_risk.egg-info/entry_points.txt
Executable file
@@ -0,0 +1,2 @@
|
||||
[trytond.modules]
|
||||
risk = trytond.modules.risk
|
||||
1
modules/risk/trytond_risk.egg-info/not-zip-safe
Executable file
1
modules/risk/trytond_risk.egg-info/not-zip-safe
Executable file
@@ -0,0 +1 @@
|
||||
|
||||
19
modules/risk/trytond_risk.egg-info/requires.txt
Executable file
19
modules/risk/trytond_risk.egg-info/requires.txt
Executable file
@@ -0,0 +1,19 @@
|
||||
python-sql>=0.4
|
||||
python-stdnum>=1.15
|
||||
trytond<7.3,>=7.2
|
||||
trytond_company<7.3,>=7.2
|
||||
trytond_currency<7.3,>=7.2
|
||||
trytond_party<7.3,>=7.2
|
||||
trytond_price<7.3,>=7.2
|
||||
trytond_product<7.3,>=7.2
|
||||
trytond_product_month<7.3,>=7.2
|
||||
|
||||
[VIES]
|
||||
python-stdnum[soap]
|
||||
|
||||
[phonenumbers]
|
||||
phonenumbers
|
||||
|
||||
[test]
|
||||
phonenumbers
|
||||
proteus<7.3,>=7.2
|
||||
1
modules/risk/trytond_risk.egg-info/top_level.txt
Executable file
1
modules/risk/trytond_risk.egg-info/top_level.txt
Executable file
@@ -0,0 +1 @@
|
||||
trytond
|
||||
15
modules/risk/view/perf_graph.xml
Executable file
15
modules/risk/view/perf_graph.xml
Executable file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<graph type="line">
|
||||
<x>
|
||||
<field name="date"/>
|
||||
</x>
|
||||
<y>
|
||||
<field name="d_perf" fill="1" empty="0"/>
|
||||
<field name="d_up" fill="1" empty="0"/>
|
||||
<field name="d_down" fill="1" empty="0"/>
|
||||
<field name="d_es" fill="1" empty="0"/>
|
||||
<field name="d_drop" fill="1" empty="0"/>
|
||||
</y>
|
||||
</graph>
|
||||
13
modules/risk/view/perf_graph2.xml
Executable file
13
modules/risk/view/perf_graph2.xml
Executable file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<graph type="line">
|
||||
<x>
|
||||
<field name="date"/>
|
||||
</x>
|
||||
<y>
|
||||
<field name="d_perf" fill="1" empty="0"/>
|
||||
<field name="d_mean" fill="1" empty="0"/>
|
||||
<field name="d_std" fill="1" empty="0"/>
|
||||
</y>
|
||||
</graph>
|
||||
4
modules/risk/view/perf_tree.xml
Executable file
4
modules/risk/view/perf_tree.xml
Executable file
@@ -0,0 +1,4 @@
|
||||
<tree editable="0">
|
||||
<field name="date"/>
|
||||
<field name="d_perf"/>
|
||||
</tree>
|
||||
6
modules/risk/view/pos_form.xml
Normal file
6
modules/risk/view/pos_form.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<form>
|
||||
<label name="commodity"/>
|
||||
<field name="commodity"/>
|
||||
<label name="type"/>
|
||||
<field name="type"/>
|
||||
</form>
|
||||
21
modules/risk/view/pos_report_context_form.xml
Normal file
21
modules/risk/view/pos_report_context_form.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<form>
|
||||
<label name="asof"/>
|
||||
<field name="asof"/>
|
||||
<label name="todate"/>
|
||||
<field name="todate"/>
|
||||
<newline/>
|
||||
<label name="trader"/>
|
||||
<field name="trader"/>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<newline/>
|
||||
<label name="month"/>
|
||||
<field name="month"/>
|
||||
<label name="market"/>
|
||||
<field name="market"/>
|
||||
<newline/>
|
||||
<label name="var"/>
|
||||
<field name="var"/>
|
||||
<label name="groupby"/>
|
||||
<field name="groupby"/>
|
||||
</form>
|
||||
22
modules/risk/view/pos_report_tree.xml
Normal file
22
modules/risk/view/pos_report_tree.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<tree>
|
||||
<field name="commodity"/>
|
||||
<field name="type" optional="1"/>
|
||||
<field name="trader"/>
|
||||
<field name="reference" optional="1"/>
|
||||
<field name="product"/>
|
||||
<field name="origin" optional="1"/>
|
||||
<field name="future_market"/>
|
||||
<field name="currency" optional="1"/>
|
||||
<field name="month"/>
|
||||
<field name="ct_type" optional="1"/>
|
||||
<field name="quantity" sum="1"/>
|
||||
<field name="basis" optional="1"/>
|
||||
<field name="price"/>
|
||||
<field name="pricing_type" optional="1"/>
|
||||
<field name="var"/>
|
||||
<field name="var_amount" sum="1"/>
|
||||
<field name="cvar"/>
|
||||
<field name="cvar_amount" sum="1"/>
|
||||
<field name="cdar"/>
|
||||
<field name="cdar_amount" sum="1"/>
|
||||
</tree>
|
||||
19
modules/risk/view/pos_tree.xml
Normal file
19
modules/risk/view/pos_tree.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<tree>
|
||||
<field name="commodity"/>
|
||||
<field name="type"/>
|
||||
<field name="trader"/>
|
||||
<field name="reference"/>
|
||||
<field name="product"/>
|
||||
<field name="origin"/>
|
||||
<field name="future_market"/>
|
||||
<field name="currency"/>
|
||||
<field name="month"/>
|
||||
<field name="ct_type"/>
|
||||
<field name="quantity"/>
|
||||
<field name="basis"/>
|
||||
<field name="price"/>
|
||||
<field name="pricing_type"/>
|
||||
<field name="var" sum="1"/>
|
||||
<field name="cvar" sum="1"/>
|
||||
<field name="cdar" sum="1"/>
|
||||
</tree>
|
||||
43
modules/risk/view/var_form.xml
Executable file
43
modules/risk/view/var_form.xml
Executable file
@@ -0,0 +1,43 @@
|
||||
<form col="4">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="type"/>
|
||||
<field name="type"/>
|
||||
<label name="confidence"/>
|
||||
<field name="confidence"/>
|
||||
<label name="execute"/>
|
||||
<field name="execute"/>
|
||||
<label name="market"/>
|
||||
<field name="market"/>
|
||||
<label name="model"/>
|
||||
<field name="model"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Distributions" id="distribution">
|
||||
<field name="lines" mode="tree,form" colspan="4"
|
||||
view_ids="risk.var_line_view_tree,risk.var_line_view_form"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<notebook colspan="4">
|
||||
<page string="Results for: Var Cvar CDar" id="results">
|
||||
<label name="var_his"/>
|
||||
<field name="var_his"/>
|
||||
<field name="cvar_his"/>
|
||||
<field name="cdar_his"/>
|
||||
<newline/>
|
||||
<label name="var_par"/>
|
||||
<field name="var_par"/>
|
||||
<field name="cvar_par"/>
|
||||
<field name="cdar_par"/>
|
||||
<newline/>
|
||||
<label name="var_mc"/>
|
||||
<field name="var_mc"/>
|
||||
<field name="cvar_mc"/>
|
||||
<field name="cdar_mc"/>
|
||||
<newline/>
|
||||
<label name="var_gar"/>
|
||||
<field name="var_gar"/>
|
||||
<field name="cvar_gar"/>
|
||||
<field name="cdar_gar"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
46
modules/risk/view/var_line_form.xml
Executable file
46
modules/risk/view/var_line_form.xml
Executable file
@@ -0,0 +1,46 @@
|
||||
<form>
|
||||
<label name="curve"/>
|
||||
<field name="curve"/>
|
||||
<label name="model"/>
|
||||
<field name="model"/>
|
||||
<newline/>
|
||||
<label name="weight"/>
|
||||
<field name="weight"/>
|
||||
<label name="simul_date"/>
|
||||
<field name="simul_date"/>
|
||||
<newline/>
|
||||
<label name="fit"/>
|
||||
<field name="fit"/>
|
||||
<label name="link"/>
|
||||
<field name="link"/>
|
||||
<notebook colspan="4">
|
||||
<page string="Graphs" id="graphs">
|
||||
<field name="perf_comput" mode="graph" colspan="4"
|
||||
view_ids="risk.perf_view_graph"/>
|
||||
<field name="perf_past" mode="graph" colspan="4"
|
||||
view_ids="risk.perf_view_graph2"/>
|
||||
</page>
|
||||
<page string="Simulation parameters" id="params">
|
||||
<label name="nb_days"/>
|
||||
<field name="nb_days"/>
|
||||
<label name="simul_comput"/>
|
||||
<field name="simul_comput"/>
|
||||
<label name="gen_simul_comput"/>
|
||||
<field name="gen_simul_comput"/>
|
||||
<label name="simul_return"/>
|
||||
<field name="simul_return"/>
|
||||
<newline/>
|
||||
<label name="nb_days_past"/>
|
||||
<field name="nb_days_past"/>
|
||||
<label name="simul_past"/>
|
||||
<field name="simul_past"/>
|
||||
<label name="gen_simul_past"/>
|
||||
<field name="gen_simul_past"/>
|
||||
<label name="simul_return_past"/>
|
||||
<field name="simul_return_past"/>
|
||||
</page>
|
||||
<page string="Fit results" id="results">
|
||||
<field name="fit_text_dyn" height="400"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
8
modules/risk/view/var_line_tree.xml
Executable file
8
modules/risk/view/var_line_tree.xml
Executable file
@@ -0,0 +1,8 @@
|
||||
<tree editable="1">
|
||||
<field name="future_market"/>
|
||||
<field name="month"/>
|
||||
<field name="curve"/>
|
||||
<field name="model"/>
|
||||
<field name="whatif"/>
|
||||
<field name="weight"/>
|
||||
</tree>
|
||||
7
modules/risk/view/var_tree.xml
Executable file
7
modules/risk/view/var_tree.xml
Executable file
@@ -0,0 +1,7 @@
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
<field name="confidence"/>
|
||||
<field name="horizon"/>
|
||||
<field name="nb_days"/>
|
||||
</tree>
|
||||
6
modules/risk/view/var_values_form.xml
Executable file
6
modules/risk/view/var_values_form.xml
Executable file
@@ -0,0 +1,6 @@
|
||||
<form>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<label name="party"/>
|
||||
<field name="party"/>
|
||||
</form>
|
||||
7
modules/risk/view/var_values_tree.xml
Executable file
7
modules/risk/view/var_values_tree.xml
Executable file
@@ -0,0 +1,7 @@
|
||||
<tree editable="1">
|
||||
<field name="product"/>
|
||||
<field name="party"/>
|
||||
<field name="r_var"/>
|
||||
<field name="r_es"/>
|
||||
<field name="r_cdar"/>
|
||||
</tree>
|
||||
Reference in New Issue
Block a user