def daily(universe=None): """Spreading Daily Run (send email once done)""" logger = logging.getLogger(__name__) day = (dt.datetime.today() + off.BDay(1)).strftime('%Y-%m-%d') logger.info('Daily mode (spreading) for: {}!'.format(day)) # Get spreading book oxe.init(books['spreading'].book) # Display traded list ldt = books['spreading'].daily_trade(universe, day) # Display additions/deletions adds, dels = oxu.daily_differences(universe, day) adds = 'Additions: {}'.format(adds) logger.info(adds) dels = 'Deletions: {}'.format(dels) logger.info(dels) # Any spreads within 10 days of LTD? ltd10 = ldt[ldt['DaysTo'] <= 10]['Ticker'].tolist() # Calculate indicators (roll yield, stddevs, etc...) books['spreading'].update_risk(universe, day) # Send email subject = '{} - Spreading Daily Run'.format( dt.datetime.today().strftime('%Y-%m-%d')) message = 'Run for: {}\n\n'.format(day) message += 'Daily trades:\n{}\n\n{}\n{}\n\n'.format(ldt, adds, dels) if len(ltd10) > 0: message += 'WARNING: Within 10 days of FND/LTD: {}'.format(ltd10) om.send_email(subject, message, '*****@*****.**', text_only=True)
def get_trades(): """Get a dictionary of the Curvature strategy active trades with the associated symbols and weights. :return: Dictionary of trades """ log = logging.getLogger(__name__) wbc = excel.init(book) log.debug('Get Curvature active trades') sheet = wbc.sheets['Trades'] df = sheet.range('A11:AC11').expand('down').value df = pd.DataFrame(df[1:], columns=df[0]) # Remove None rows as this is the top row for the trade df = df[df['Symbol'].notnull()] # Get Trades ts = set(df['Trade'].values) ts = sorted(ts, key=str.lower) # Dictionary of trades trades = dict() for t in ts: t_df = df[df['Trade'] == t] symbols = t_df['Symbol'].values.tolist() weights = t_df['W'].values.tolist() trades[t] = { 'Name': oxu.to_trade_name(t, symbols, weights), 'Symbols': symbols, 'Weights': weights } return trades
def snap_quotes(): """Function to be called at 4pm to save curve history. This is then used to playback the curve changes. """ log = logging.getLogger(__name__) wbc = excel.init(book) today = dt.datetime.today().strftime('%Y%m%d') path = '{}\{}-quotes.txt'.format(c.cfg['default']['quotes'], today) # Check if it's been done already today if excel.check_status(wbc, 'AA1'): log.info('Snap Quotes has already ran today!') return # Get quotes df = wbc.sheets['Quotes'].range('A1').expand().value df = pd.DataFrame(df[1:], columns=df[0]) df = df[(df['Generated'] != 'Manual') & df['Ticker'].str.contains('ED')][['Ticker', 'WP']] # Only spreads or butterflies! df = df[df['Ticker'].str.contains('S') | df['Ticker'].str.contains('B')] # Get list of maturities lm = wbc.sheets['Monitor'].range('B7').expand('down').value lm = [t[-2:] for t in lm] # Convert to constant maturities df['Constant'] = df['Ticker'].map(lambda x: i.to_constant_contract(x, lm)) df = df[['Constant', 'Ticker', 'WP']] df.to_csv(path, index=False, header=False, float_format='%.2f') # Change today's import status excel.update_status(wbc, 'AA1')
def update_json_database(): """Update JSON DB File Might need to be deprecated as not really used much, or will be part of a wider module to manage database """ log = logging.getLogger(__name__) wbs = excel.init(book) log.debug('Update JSON database') # Get Universe Dataframe universe = wbs.sheets['Universe'].range('A1').expand().value universe = pd.DataFrame(universe[1:], columns=universe[0]) universe.set_index('RIC', inplace=True) universe.index.names = [None] for index, row in universe.iterrows(): # Check if CTicker is in the database if row['CTicker'] not in i.json_db: i.json_db[row['CTicker']] = dict() # Add values to the database i.json_db[row['CTicker']]['Point'] = row['PointValue'] i.json_db[row['CTicker']]['Letters'] = [] i.json_db[row['CTicker']]['Stem'] = { 'T4': '', 'CMED': '', 'Reuters': index, 'IQFeed': row['IQFeed'] } # Save to JSON with open(c.cfg['default']['database'], 'w') as json_file: json.dump(json.loads(str(i.json_db).replace('\'', '"')), json_file)
def update_risk(): """Update risk, this will refresh all the VaR values and copy them directly to the sheet. See the relevant function if we need to amend the values to be calculated. """ log = logging.getLogger(__name__) wbc = excel.init(book) log.debug('Update risk on Book {}'.format(book)) excel.update_sheet(wbc, 'Analysis', 'A3:E28', r.calculate_vars(get_trades()))
def populate(provider='Reuters'): """Populate the sheet with current traded tickers :param provider: str - Data Provider """ log = logging.getLogger(__name__) wbc = excel.init(book) log.debug('Populate workbook {}'.format(book)) tickers = li.generate_curvature_list() excel.populate_workbook(wbc, tickers, provider)
def update_risk(universe=None, date=None): """Update risk, this will refresh all the std values and copy them directly to the sheet. See the relevant function if we need to amend the values to be calculated. :param universe: list: Not necessary, if not specified will use Excel. :param date: Set a date for the calculations """ log = logging.getLogger(__name__) wbs = excel.init(book) log.debug('Update risk on Book {}'.format(book)) df = r.calculate_stds(daily_trade(universe, date)) excel.update_sheet(wbs, 'Analysis', 'A3:E63', df)
def main(): """Main entry point of the program.""" # Initialization mode, opts = init() # Logger logger = logging.getLogger(__name__) try: if 'snap' in mode or 'populate' in mode or 'positions' in mode or 'risk' in mode: logger.info('Run macro: {}'.format(mode)) macros(mode, opts.book) elif 'eod' in mode: logger.info('End of day processing.') wbc = oxe.init(books['curvature'].book) if not oxe.check_status(wbc, 'AA2'): # Update Risk on Excel books['curvature'].update_risk() # Update Status oxe.update_status(wbc, 'AA2') # Save and quit oxe.save_and_quit(wbc) else: logger.warning( 'EoD has already ran for today, do not do anything!') elif 'dailydownload' in mode: # Run daily download mode getattr(sys.modules[__name__], mode)() elif 'daily' in mode: # Run daily mode symbols = None if opts.markets is None else opts.markets.split(',') getattr(sys.modules[__name__], mode)(symbols) elif 'icecot' in mode: # Get ICE COT latest data odi.get_last_data() elif 'live' in mode: symbols = opts.markets.split(',') strategies = opts.strategies.split(',') # TODO: Better way to load a strategy? getattr(sys.modules[__name__], mode)(symbols, float(opts.cash), [getattr(ah, s) for s in strategies]) else: logger.error('Mode is not defined, exiting!') sys.exit(1) except Exception as ex: logger.error(ex, exc_info=True)
def get_universe(subset='Trade'): """Get the commodities universe as described in the excel sheet (with various necessary fields). Possibility to bypass this function and provide the traded universe directly. :param subset: Traded subset (All, Trade, Research) - Look at sheet for selected universe :return: DataFrame with RIC as index """ log = logging.getLogger(__name__) wbs = excel.init(book) log.debug('Get Universe') # Get Universe Dataframe universe = wbs.sheets['Universe'].range('A1').expand().value universe = pd.DataFrame(universe[1:], columns=universe[0]) universe.set_index('RIC', inplace=True) universe.index.names = [None] # Traded subset return universe[universe[subset]] if subset != 'All' else universe
def populate(universe=None, provider='Reuters'): """Populate the sheet with current traded tickers :param universe: list: Not necessary, if not specified will use Excel. :param provider: Which data provider """ log = logging.getLogger(__name__) wbs = excel.init(book) log.debug('Populate workbook {}'.format(book)) tickers = daily_trade(universe)['Ticker'].tolist() # Add outrights outrights = [] for t in tickers: ticker = '{}{}'.format(t[0:2], t[-3:]) outrights.append(ticker) tickers = outrights + tickers # Populate Workbook excel.populate_workbook(wbs, tickers, provider)
def positions(symbol): """Refresh the positions in the Positions sheet, this is used to calculate our outright positions. :param symbol: Which symbol to refresh (only ED or FF) """ log = logging.getLogger(__name__) wbc = excel.init(book) log.debug('Transactions Sheet') sheet = wbc.sheets['Transactions'] if len(symbol) > 2: log.error('Symbol needs to be a stem!') sys.exit(1) if 'ED' in symbol: log.debug('Getting the range for ED') rng = 'F4:G29' cell = 'F4' elif 'FF' in symbol: log.debug('Getting the range for FF') rng = 'F35:G46' cell = 'F35' else: log.error('Symbol not defined!') sys.exit(1) log.debug('Get the data and transform it') df = sheet.range('A1').expand().value df = pd.DataFrame(df[1:], columns=df[0]) df['Position'] = df.apply(lambda x: x['Qty'] if x['Side'] == 'BUY' else -x['Qty'], axis=1) dfg = df[df['DateOut'].isnull() & df['Symbol'].notnull() & df['Symbol'].str.contains(symbol)] dfg = dfg.groupby(['Symbol'])['Position'].sum().reset_index() log.debug('Copy the data to the sheet') wbc.sheets['Positions'].range(rng).clear_contents() wbc.sheets['Positions'].range(cell).options(index=False, header=False).value = dfg