예제 #1
0
    def test_chain_handle_missing_data(self):
        assetindex = AssetIndexMongo(MONGO_CONNSTR, MONGO_EXO_DB)



        futures_limit = 3
        options_limit = 20

        datasource = DataSourceSQL(SQL_HOST, SQL_USER, SQL_PASS, assetindex, futures_limit, options_limit)

        base_date = datetime(2014, 2, 18, 11, 10, 0)
        instr = datasource.get("CL", base_date)
        rh = RolloverHelper(instr)
        fut, opt_chain = rh.get_active_chains()
        # opt_chain.get_by_delta(0.05) on the CL on this date is has absent data
        # opt_chain selects next available date
        self.assertEqual(opt_chain.get_by_delta(0.05), opt_chain.get_by_delta(0.04))

        base_date = datetime(2016, 2, 17, 11, 10, 0)
        instr = datasource.get("ZN", base_date)
        rh = RolloverHelper(instr)
        fut, opt_chain = rh.get_active_chains()
        # opt_chain[11] is an absent strike inside DB, if it absent opt_chain selects next available strike
        self.assertEqual(opt_chain[11], opt_chain[12])
        self.assertEqual(opt_chain[-11], opt_chain[-12])
    def process_day(self):
        """
        Main EXO's position management method
        :return: list of Transactions to process
        """

        if len(self.position) == 0:
            instr = self.datasource.get(self._symbol, self.date)
            rh = RolloverHelper(instr)
            fut, opt_chain = rh.get_active_chains()
            if fut is None or opt_chain is None:
                if self.debug_mode:
                    self.logger.write(
                        'Futures contract or option chain not found.\n\tFuture: {0}\tOption chain: {1}\n'
                        .format(fut, opt_chain))
                return []

            call = opt_chain[0].C

            trans_list = [
                Transaction(call,
                            self.date,
                            1.0,
                            call.price,
                            leg_name='opt_call'),
            ]
            return trans_list
    def test_active_chains_current(self):
        inst_dict = {
            'name':
            'TEST',
            'futures': [{
                'days':
                5,
                'name':
                'fut1',
                'expiration':
                datetime(2015, 1, 10),
                'options': [
                    {
                        'days': 3,
                        'expiration': datetime(2015, 1, 8),
                        'name': 'fut1_opt1'
                    },
                ]
            }]
        }

        dinst = DummyInstrument(inst_dict)
        rh = RolloverHelper(dinst)

        fut, opt = rh.get_active_chains()
        self.assertEqual(fut.name, 'fut1')
        self.assertEqual(opt.name, 'fut1_opt1')
    def test_active_chains_rollover_options_no_options_chains(self):
        inst_dict = {
            'name':
            'TEST',
            'futures': [{
                'days': 20,
                'name': 'fut1',
                'expiration': datetime(2015, 1, 10),
                'options': []
            }, {
                'days': 20,
                'name': 'fut2',
                'expiration': datetime(2015, 2, 10),
                'options': []
            }, {
                'days': 40,
                'name': 'fut3',
                'expiration': datetime(2015, 3, 10),
                'options': []
            }]
        }

        dinst = DummyInstrument(inst_dict)
        rh = RolloverHelper(dinst)
        rh.rollover_months = [1, 3]
        rh.days_before_expiration = 10

        fut, opt = rh.get_active_chains()
        self.assertEqual(fut.name, 'fut1')
        self.assertEqual(opt, None)
    def test_active_chains_rollover_options_no_futures(self):
        inst_dict = {'name': 'TEST', 'futures': []}

        dinst = DummyInstrument(inst_dict)
        rh = RolloverHelper(dinst)
        rh.rollover_months = [1, 3]
        rh.days_before_expiration = 10

        fut, opt = rh.get_active_chains()
        self.assertEqual(fut, None)
        self.assertEqual(opt, None)
예제 #6
0
    def process_day(self):
        """
        Main EXO's position management method
        :return: list of Transactions to process
        """

        if len(self.position) == 0:
            instr = self.datasource.get(self._symbol, self.date)
            rh = RolloverHelper(instr)
            fut, opt_chain = rh.get_active_chains()
            if fut is None or opt_chain is None:
                if self.debug_mode:
                    self.logger.write(
                        'Futures contract or option chain not found.\n\tFuture: {0}\tOption chain: {1}\n'
                        .format(fut, opt_chain))
                return []

            if self._direction == 1:
                itm_call = opt_chain[-2].C
                otm_call = opt_chain[10].C

                return [
                    Transaction(itm_call,
                                self.date,
                                1.0,
                                itm_call.price,
                                leg_name='opt_itm_leg'),
                    Transaction(otm_call,
                                self.date,
                                -1.0,
                                otm_call.price,
                                leg_name='opt_otm_leg'),
                ]
            if self._direction == -1:
                itm_put = opt_chain[2].P
                otm_put = opt_chain[-10].P

                return [
                    Transaction(itm_put,
                                self.date,
                                1.0,
                                itm_put.price,
                                leg_name='opt_itm_leg'),
                    Transaction(otm_put,
                                self.date,
                                -1.0,
                                otm_put.price,
                                leg_name='opt_otm_leg'),
                ]
예제 #7
0
    def plot_transactions_payoff(self, smart_exo_position_func, analysis_date,
                                 analysis_instrument, **whatif_kwargs):

        payoff = PayoffAnalyzer(self.datasource)
        instr = self.datasource.get(analysis_instrument, analysis_date)
        rh = RolloverHelper(instr)
        fut, opt_chain = rh.get_active_chains()

        strikes_on_graph = whatif_kwargs.get('strikes_on_graph', 30)
        whatif_iv_change = whatif_kwargs.get('whatif_iv_change', 0)
        whatif_days_to_expiration = whatif_kwargs.get(
            'whatif_days_to_expiration', int(opt_chain.to_expiration_days / 2))

        payoff.load_transactions(
            smart_exo_position_func(analysis_date, fut, opt_chain),
            analysis_date)
        payoff.plot(strikes_on_graph, whatif_iv_change,
                    whatif_days_to_expiration)
예제 #8
0
    def test_max_min_offset(self):
        assetindex = AssetIndexMongo(MONGO_CONNSTR, MONGO_EXO_DB)

        base_date = datetime(2015, 6, 13, 12, 45, 0)

        futures_limit = 3
        options_limit = 20

        datasource = DataSourceSQL(SQL_HOST, SQL_USER, SQL_PASS, assetindex, futures_limit, options_limit)

        instr = datasource.get("ES", base_date)
        rh = RolloverHelper(instr)
        fut, opt_chain = rh.get_active_chains()

        offset = opt_chain.maxoffset
        self.assertEqual(20, offset)

        offset = opt_chain.minoffset
        self.assertEqual(-20, offset)
    def process_day(self):
        """
        Main EXO's position management method
        :return: list of Transactions to process
        """

        # Get cont futures price for EXO
        exo_df, exo_info = self.datasource.exostorage.load_series(
            self._base_exo_name)

        regime = self.calculate_regime(self.date, exo_df)

        logging.debug("Regime {0}".format(regime))

        trans_list = []

        if regime is None and len(self.position) > 0:
            return self.position.close_all_translist()

        instr = self.datasource.get(self._symbol, self.date)
        rh = RolloverHelper(instr)
        fut, opt_chain = rh.get_active_chains()

        if regime == 1 and 'bullish' not in self.position.legs:
            # Close all
            trans_list += self.position.close_all_translist()
            tl = self.new_position_bullish_zone(self.date, fut, opt_chain)

            if len(tl) > 0:
                tl[0]._leg_name = 'bullish'
                trans_list += tl
            self._log_transactions(trans_list)
            return trans_list

        if regime == -1 and 'bearish' not in self.position.legs:
            # Close all
            trans_list += self.position.close_all_translist()
            tl = self.new_position_bearish_zone(self.date, fut, opt_chain)

            if len(tl) > 0:
                tl[0]._leg_name = 'bearish'
                trans_list += tl
            self._log_transactions(trans_list)
            return trans_list

        if regime == 0 and 'neutral' not in self.position.legs:
            # Close all
            trans_list += self.position.close_all_translist()
            tl = self.new_position_neutral_zone(self.date, fut, opt_chain)

            if len(tl) > 0:
                tl[0]._leg_name = 'neutral'
                trans_list += tl
            self._log_transactions(trans_list)
            return trans_list

        #
        # Writing custom values to store inside DB
        #
        self.custom_values = {
            'regime': regime if regime is not None else float('nan')
        }

        #
        # Manage opened position
        #
        return self.manage_opened_position(self.date, fut, opt_chain, regime,
                                           self.position)
예제 #10
0
    def test_chain_get_by_delta(self):
        assetindex = AssetIndexMongo(MONGO_CONNSTR, MONGO_EXO_DB)

        base_date = datetime(2015, 6, 13, 12, 45, 0)

        futures_limit = 3
        options_limit = 20

        datasource = DataSourceSQL(SQL_HOST, SQL_USER, SQL_PASS, assetindex, futures_limit, options_limit)

        instr = datasource.get("ES", base_date)
        rh = RolloverHelper(instr)
        fut, opt_chain = rh.get_active_chains()

        atm_strike = opt_chain.atmstrike

        opt = opt_chain.get_by_delta(0.5)
        self.assertEqual(opt.strike, atm_strike)
        self.assertEqual(opt.putorcall, 'C')

        opt = opt_chain.get_by_delta(-0.5)
        self.assertEqual(opt.strike, atm_strike)
        self.assertEqual(opt.putorcall, 'P')

        self.assertRaises(ValueError, opt_chain.get_by_delta, 0)
        self.assertRaises(ValueError, opt_chain.get_by_delta, float('nan'))
        self.assertRaises(ValueError, opt_chain.get_by_delta, 1)
        self.assertRaises(ValueError, opt_chain.get_by_delta, 2)
        self.assertRaises(ValueError, opt_chain.get_by_delta, -2)
        self.assertRaises(ValueError, opt_chain.get_by_delta, -1)

        # ITM Put
        opt = opt_chain.get_by_delta(-0.7)
        self.assertEqual(opt.strike, 2115)
        self.assertEqual(opt.putorcall, 'P')
        self.assertAlmostEqual(opt.delta, -0.75, 2)

        opt = opt_chain.get_by_delta(-0.999999)
        self.assertEqual(opt.strike, 2195.0)
        self.assertEqual(opt.putorcall, 'P')
        self.assertAlmostEqual(opt.delta, -0.989, 3)

        # OTM Put
        opt = opt_chain.get_by_delta(-0.3)
        self.assertEqual(opt.strike, 2070)
        self.assertEqual(opt.putorcall, 'P')
        self.assertAlmostEqual(opt.delta, -0.27, 2)

        opt = opt_chain.get_by_delta(-0.00001)
        self.assertEqual(opt, opt_chain[-20].P)

        # ITM Call
        opt = opt_chain.get_by_delta(0.7)
        self.assertEqual(opt.strike, 2070)
        self.assertEqual(opt.putorcall, 'C')
        self.assertAlmostEqual(opt.delta, 0.73, 2)

        opt = opt_chain.get_by_delta(0.9999999)
        self.assertEqual(opt, opt_chain[-20].C)

        # OTM Call
        opt = opt_chain.get_by_delta(0.3)
        self.assertEqual(opt.strike, 2115)
        self.assertEqual(opt.putorcall, 'C')
        self.assertAlmostEqual(opt.delta, 0.24, 2)

        opt = opt_chain.get_by_delta(0.000001)
        self.assertEqual(opt, opt_chain[20].C)
    def process_day(self):
        """
        Main EXO's position management method
        :return: list of Transactions to process
        """

        if len(self.position) == 0:
            instr = self.datasource.get(self._symbol, self.date)
            rh = RolloverHelper(instr)
            fut, opt_chain = rh.get_active_chains()
            if fut is None or opt_chain is None:
                if self.debug_mode:
                    self.logger.write(
                        'Futures contract or option chain not found.\n\tFuture: {0}\tOption chain: {1}\n'
                        .format(fut, opt_chain))
                return []

            if self._direction == 1:
                # the bullish broken wings are long the -5 put , long the future, short the  + 5 call and long the +9 call
                put_dn5 = opt_chain[-5].P
                call_up5 = opt_chain[5].C
                call_up9 = opt_chain[9].C

                return [
                    Transaction(put_dn5,
                                self.date,
                                1.0,
                                put_dn5.price,
                                leg_name='opt_otm_leg'),
                    Transaction(fut,
                                self.date,
                                1.0,
                                fut.price,
                                leg_name='fut_leg'),
                    Transaction(call_up5,
                                self.date,
                                -1.0,
                                call_up5.price,
                                leg_name='call_up5_short_leg'),
                    Transaction(call_up9,
                                self.date,
                                1.0,
                                call_up9.price,
                                leg_name='call_up9_long_leg'),
                ]
            if self._direction == -1:
                # the bearish BW  long the -9 put, short the -5 put , short the future, long the + 5 call
                call_up5 = opt_chain[5].C
                put_dn9 = opt_chain[-9].P
                put_dn5 = opt_chain[-5].P

                return [
                    Transaction(call_up5,
                                self.date,
                                1.0,
                                call_up5.price,
                                leg_name='opt_otm_leg'),
                    Transaction(fut,
                                self.date,
                                -1.0,
                                fut.price,
                                leg_name='fut_leg'),
                    Transaction(put_dn9,
                                self.date,
                                1.0,
                                put_dn9.price,
                                leg_name='put_dn9_long_leg'),
                    Transaction(put_dn5,
                                self.date,
                                -1.0,
                                put_dn5.price,
                                leg_name='put_dn5_short_leg'),
                ]
    def process_day(self):
        """
        Main EXO's position management method
        :return: list of Transactions to process
        """

        # Get cont futures price for EXO
        exo_df, exo_info = self.datasource.exostorage.load_series(
            "{0}_ContFut".format(self._symbol))

        regime = self.ichimoku_regimes(exo_df['exo'])

        trans_list = []

        if regime is None and len(self.position) > 0:
            return self.position.close_all_translist()

        if regime == 1 and 'bullish' not in self.position.legs:
            # Close all
            trans_list += self.position.close_all_translist()

            instr = self.datasource.get(self._symbol, self.date)
            rh = RolloverHelper(instr)
            fut, opt_chain = rh.get_active_chains()

            trans_list += [
                Transaction(fut,
                            self.date,
                            15.0,
                            fut.price,
                            leg_name='bullish'),
            ]
            return trans_list
        if regime == -1 and 'bearish' not in self.position.legs:
            # Close all
            trans_list += self.position.close_all_translist()

            instr = self.datasource.get(self._symbol, self.date)
            rh = RolloverHelper(instr)
            fut, opt_chain = rh.get_active_chains()

            trans_list += [
                Transaction(fut, self.date, 1.0, fut.price,
                            leg_name='bearish'),
            ]
            return trans_list

        if regime == 0 and 'neutral' not in self.position.legs:
            # Close all
            trans_list += self.position.close_all_translist()

            instr = self.datasource.get(self._symbol, self.date)
            rh = RolloverHelper(instr)
            fut, opt_chain = rh.get_active_chains()

            trans_list += [
                Transaction(fut, self.date, 5.0, fut.price,
                            leg_name='neutral'),
            ]
            return trans_list

        return []