Esempio n. 1
0
class TradeJSON(object):
    """trade JSON interface."""

    def __init__(self, container_tasks, types):
        self.subjects = {}
        self.occurrences = []
        self.containers = {}
        self.container_tasks = container_tasks
        self.types = types
        self.portfolio = None

        # TODO can't be hardcoded
        self.totals = {
            'total_operations': 0,
            'sale_operations': 0,
            'purchase_operations': 0,
            'sale_volume': 0,
            'purchase_volume': 0,
            'total_daytrades': 0
        }

    def create_subjects(self, data):
        """creates a subject object for all subjects in the json."""
        for subject, details in data['subjects'].items():
            self.subjects[subject] = {
                'object': self.types[details['type']](
                    name=details['name'],
                    symbol=subject,
                    expiration_date=details.get('expiration_date', None),
                    underlying_assets=details.get('underlying_assets', {})
                ),
                'sales': 0,
                'purchases': 0,
                'daytrades': 0,
                'operations': 0
            }

        for subject, obj in self.subjects.items():
            if obj['object'].underlying_assets:
                original_underlying = obj['object'].underlying_assets
                underlying_assets = {}
                for underlying, ratio in original_underlying.items():
                    underlying_assets\
                        [self.subjects[underlying]['object']] = ratio
                obj['object'].underlying_assets = underlying_assets

    def create_occurrences(self, data):
        """Creates all the occurrences described in the json."""
        self.occurrences = []
        for occurrence in data['occurrences']:
            self.occurrences.append(
                self.types[occurrence['type']](
                    quantity=occurrence['quantity'],
                    price=occurrence['price'],
                    date=occurrence['date'],
                    subject=self.subjects[occurrence['subject']]['object']
                )
            )
            self.totals['total_operations'] += 1
            self.subjects[occurrence['subject']]['operations'] += 1
            volume = abs(occurrence['quantity'] * occurrence['price'])
            if occurrence['quantity'] > 0:
                self.totals['purchase_operations'] += 1
                self.totals['purchase_volume'] += volume
                self.subjects[occurrence['subject']]['purchases'] += 1
            else:
                self.totals['sale_operations'] += 1
                self.totals['sale_volume'] += volume
                self.subjects[occurrence['subject']]['sales'] += 1

    def create_containers(self):
        """Creates a container for each operation date.

        The containers are then filled with the respective operations.
        """
        for occurrence in self.occurrences:
            if occurrence.date not in self.containers:
                self.containers[occurrence.date] = OperationContainer(
                    operations=[],
                    tasks=self.container_tasks
                )
            self.containers[occurrence.date].operations.append(occurrence)

    def create_portfolio(self, data):
        """Create a portfolio to store the positions."""
        initial_state = {}
        for asset_name, asset_state in data['initial state'].items():
            initial_state[self.subjects[asset_name]['object']] = asset_state
        self.portfolio = Portfolio(state=initial_state)

    def accumulate_positions(self):
        """Accumulate each container position on the portoflio."""
        for key in sorted(self.containers.keys()):
            self.containers[key].fetch_positions()
            if 'positions' in self.containers[key].context:
                for position_type, position_asset in \
                    self.containers[key].context['positions'].items():
                    for asset_symbol, position in position_asset.items():
                        self.portfolio.accumulate(position)
                        if position_type == 'daytrades':
                            self.totals['total_daytrades'] += 1
                            self.subjects[asset_symbol]['daytrades'] += 1

    def get_base_log(self):
        """Get the structure of the return json."""
        return {
            'totals': {
                "sales": {
                    "volume": self.totals['sale_volume'],
                    "operations": self.totals['sale_operations']
                },
                "purchases": {
                    "volume": self.totals['purchase_volume'],
                    "operations": self.totals['purchase_operations']
                },
                "operations": self.totals['total_operations'],
                "daytrades": self.totals['total_daytrades'],
                'results' : {}
            },
            'assets': {}
        }

    def get_states(self):
        """Fill the return json with the log of each accumulator."""
        logs = self.get_base_log()
        for accumulator in self.portfolio.subjects.values():
            if accumulator.subject.symbol not in logs['assets']:
                logs['assets'][accumulator.subject.symbol] = {
                    'totals': {
                        "sales": self.subjects\
                            [accumulator.subject.symbol]['sales'],
                        "purchases": self.subjects\
                            [accumulator.subject.symbol]['purchases'],
                        "operations": self.subjects\
                            [accumulator.subject.symbol]['operations'],
                        "daytrades": self.subjects\
                            [accumulator.subject.symbol]['daytrades'],
                        "results": accumulator.state['results']
                    },
                    'states': {}
                }
            logs['assets'][accumulator.subject.symbol]['states'] = \
                accumulator.log
            for key in accumulator.state['results'].keys():
                if key not in logs['totals']['results']:
                    logs['totals']['results'][key] = 0
                logs['totals']['results'][key] += accumulator.state['results']\
                    [key]
        return logs

    def get_trade_results(self, data):
        """json in, json out"""
        data = json.loads(data)

        # creates an object for all subjects in the json
        self.create_subjects(data)

        # Get all the occurrences described in the json
        self.create_occurrences(data)

        # create a Portfolio with the initial state
        self.create_portfolio(data)

        # Put the operations in containers
        self.create_containers()

        # Fetch the positions on each container
        # and accumulates the positions
        self.accumulate_positions()

        # get the current log and current state of
        # all accumulators
        json_output = json.dumps(self.get_states())

        return json_output
Esempio n. 2
0
 def create_portfolio(self, data):
     """Create a portfolio to store the positions."""
     initial_state = {}
     for asset_name, asset_state in data['initial state'].items():
         initial_state[self.subjects[asset_name]['object']] = asset_state
     self.portfolio = Portfolio(state=initial_state)