Initial import from Docker volume

This commit is contained in:
root
2025-12-26 13:11:43 +00:00
commit 4998dc066a
13336 changed files with 1767801 additions and 0 deletions

22
modules/risk/__init__.py Executable file
View 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')

Binary file not shown.

View 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')

View 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

View 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

View 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"))

View 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>

View 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")

View 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

View 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")

View 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>

View 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>

View 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>

View File

@@ -0,0 +1,5 @@
<tree>
<field name="curve"/>
<field name="model"/>
<field name="weight"/>
</tree>

View 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>

View File

@@ -0,0 +1,6 @@
<form>
<label name="product"/>
<field name="product"/>
<label name="party"/>
<field name="party"/>
</form>

View 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>

Binary file not shown.

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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

View 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

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,2 @@
[trytond.modules]
risk = trytond.modules.risk

View File

@@ -0,0 +1 @@

View 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

View File

@@ -0,0 +1 @@
trytond

View 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>

View 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>

View File

@@ -0,0 +1,4 @@
<tree editable="0">
<field name="date"/>
<field name="d_perf"/>
</tree>

View File

@@ -0,0 +1,6 @@
<form>
<label name="commodity"/>
<field name="commodity"/>
<label name="type"/>
<field name="type"/>
</form>

View 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>

View 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>

View 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
View 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>

View 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>

View 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
View File

@@ -0,0 +1,7 @@
<tree>
<field name="name"/>
<field name="type"/>
<field name="confidence"/>
<field name="horizon"/>
<field name="nb_days"/>
</tree>

View File

@@ -0,0 +1,6 @@
<form>
<label name="product"/>
<field name="product"/>
<label name="party"/>
<field name="party"/>
</form>

View 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>