1#!/usr/bin/env python
2# -*- coding: utf-8; py-indent-offset:4 -*-
3###############################################################################
4#
5# Copyright (C) 2015, 2016, 2017 Daniel Rodriguez
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19#
20###############################################################################
21from __future__ import (absolute_import, division, print_function,
22                        unicode_literals)
23
24from .utils.py3 import with_metaclass
25
26from .metabase import MetaParams
27
28
29class Sizer(with_metaclass(MetaParams, object)):
30    '''This is the base class for *Sizers*. Any *sizer* should subclass this
31    and override the ``_getsizing`` method
32
33    Member Attribs:
34
35      - ``strategy``: will be set by the strategy in which the sizer is working
36
37        Gives access to the entire api of the strategy, for example if the
38        actual data position would be needed in ``_getsizing``::
39
40           position = self.strategy.getposition(data)
41
42      - ``broker``: will be set by the strategy in which the sizer is working
43
44        Gives access to information some complex sizers may need like portfolio
45        value, ..
46    '''
47    strategy = None
48    broker = None
49
50    def getsizing(self, data, isbuy):
51        comminfo = self.broker.getcommissioninfo(data)
52        return self._getsizing(comminfo, self.broker.getcash(), data, isbuy)
53
54    def _getsizing(self, comminfo, cash, data, isbuy):
55        '''This method has to be overriden by subclasses of Sizer to provide
56        the sizing functionality
57
58        Params:
59          - ``comminfo``: The CommissionInfo instance that contains
60            information about the commission for the data and allows
61            calculation of position value, operation cost, commision for the
62            operation
63
64          - ``cash``: current available cash in the *broker*
65
66          - ``data``: target of the operation
67
68          - ``isbuy``: will be ``True`` for *buy* operations and ``False``
69            for *sell* operations
70
71        The method has to return the actual size (an int) to be executed. If
72        ``0`` is returned nothing will be executed.
73
74        The absolute value of the returned value will be used
75
76        '''
77        raise NotImplementedError
78
79    def set(self, strategy, broker):
80        self.strategy = strategy
81        self.broker = broker
82
83
84SizerBase = Sizer  # alias for old naming
85