Python自定义格式化程序

时间:2016-05-26 13:03:16

标签: python python-3.x

我正在编写一个程序来处理过期不同月份的合同。

例如,2016年12月到期的玉米期货合约将被称为:

CZ2016

其中C表示玉米',Z表示12月(它是自定义)。

在内部,我将所有内容表示为(year, month)

每种合约类型都有不同的格式,理想情况下我需要能够双向进行。

目前我已经写了一些精心设计的字符串处理来做到这一点,但这很麻烦。

最狡猾的方式是什么?

1 个答案:

答案 0 :(得分:3)

这里快速(ish):

#!python3
import collections
import time

class FuturesContract:
    Commodity = collections.namedtuple('Commodity',
            'symbol future exchange delivery_months')

    Commodities = [
        # Source: http://www.mrci.com/web/online-explanation-pages/symbols-a-codes.html
        # !IMPORTANT! Sorted by length of symbol!!!
        Commodity('ITCO', 'Brent Crude', 'ICE', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('AD', 'Australian Dollar', 'CME', 'H,M,U,Z'),
        Commodity('BP', 'British Pound', 'CME', 'H,M,U,Z'),
        Commodity('CD', 'Canadian Dollar', 'CME', 'H,M,U,Z'),
        Commodity('DX', 'US Dollar Index', 'ICE', 'H,M,U,Z'),
        Commodity('EU', 'EuroFx', 'CME', 'H,M,U,Z'),
        Commodity('JY', 'Japanese Yen', 'CME', 'H,M,U,Z'),
        Commodity('SF', 'Swiss Franc', 'CME', 'H,M,U,Z'),
        Commodity('CL', 'Crude Oil', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('HO', 'NY Harbor ULSD/Heating Oil', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('HU', 'Unleaded Gas', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('NG', 'Natural Gas', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('RB', 'RBOB Gasoline', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('BO', 'Soybean Oil', 'CBOT', 'F,H,K,N,Q,U,V,Z'),
        Commodity('KW', 'Kansas City Wheat', 'KCBT', 'H,K,N,U,Z'),
        Commodity('MW', 'Minneapolis Wheat', 'MGE', 'H,K,N,U,Z'),
        Commodity('SM', 'Soybean Meal', 'CBOT', 'F,H,K,N,Q,U,V,Z'),
        Commodity('DJ', 'Dow Jones Industrials', 'CBOT', 'H,M,U,Z'),
        Commodity('KV', 'Value Line (Discontinued)', 'KCBT', 'H,M,U,Z'),
        Commodity('MV', 'Value Line (Mini)', 'KCBT', 'H,M,U,Z'),
        Commodity('ND', 'Nasdaq-100', 'CME', 'H,M,U,Z'),
        Commodity('RL', 'Russell 2000 (Discontinued)', 'CME', 'H,M,U,Z'),
        Commodity('SP', 'S & P 500', 'CME', 'H,M,U,Z'),
        Commodity('YU', 'NYSE Composite (Discontinued)', 'NYFE', 'H,M,U,Z'),
        Commodity('ED', 'Eurodollars', 'CME', 'H,M,U,Z'),
        Commodity('FV', '5-Yr T-Notes', 'CBOT', 'H,M,U,Z'),
        Commodity('MB', 'Municipal Bonds', 'CBOT', 'H,M,U,Z'),
        Commodity('TU', '2-Yr T-Notes', 'CBOT', 'H,M,U,Z'),
        Commodity('TY', '10-Yr T-Notes', 'CBOT', 'H,M,U,Z'),
        Commodity('US', '30-Yr T-Bonds', 'CBOT', 'H,M,U,Z'),
        Commodity('FC', 'Feeder Cattle', 'CME', 'F,H,J,K,Q,U,V,X'),
        Commodity('LC', 'Live Cattle', 'CME', 'G,J,M,Q,V,Z'),
        Commodity('LH', 'Lean Hogs', 'CME', 'G,J,K,M,N,Q,V,Z'),
        Commodity('LE', 'Lean Hogs', 'CME', 'G,J,K,M,N,Q,V,Z'),
        Commodity('PB', 'Pork Bellies', 'CME', 'G,H,K,N,Q'),
        Commodity('DA', 'Milk Class III', 'CME', 'F,G,H,J,K,M,N,Q,U,V,X,Z'),
        Commodity('GC', 'Gold', 'CMX', 'G,J,M,Q,V,Z'),
        Commodity('HG', 'Copper', 'CMX', 'H,K,N,U,Z'),
        Commodity('PL', 'Platinum', 'NYM', 'F,J,N,V'),
        Commodity('SI', 'Silver', 'CMX', 'H,K,N,U,Z'),
        Commodity('RR', 'Rice', 'CBOT', 'F,H,K,N,U,X'),
        Commodity('CC', 'Cocoa', 'ICE', 'H,K,N,U,Z'),
        Commodity('CT', 'Cotton', 'ICE', 'H,K,N,V,Z'),
        Commodity('KC', 'Coffee', 'ICE', 'H,K,N,U,Z'),
        Commodity('LB', 'Lumber', 'CME', 'F,H,K,N,U,X'),
        Commodity('JO', 'Orange Juice', 'ICE', 'F,H,K,N,U,X'),
        Commodity('SB', 'Sugar #11', 'ICE', 'H,K,N,V'),
        Commodity('C', 'Corn', 'CBOT', 'F,H,K,N,U,X,Z'),
        Commodity('O', 'Oats', 'CBOT', 'H,K,N,U,Z'),
        Commodity('S', 'Soybeans', 'CBOT', 'F,H,K,N,Q,U,X'),
        Commodity('W', 'Wheat', 'CBOT', 'H,K,N,U,Z'),
    ]

    Months = {
        1: 'January',
        2: 'February',
        3: 'March',
        4: 'April',
        5: 'May',
        6: 'June',
        7: 'July',
        8: 'August',
        9: 'September',
        10: 'October',
        11: 'November',
        12: 'December',
        'F': 'January',
        'G': 'February',
        'H': 'March',
        'J': 'April',
        'K': 'May',
        'M': 'June',
        'N': 'July',
        'Q': 'August',
        'U': 'September',
        'V': 'October',
        'X': 'November',
        'Z': 'December',
    }

    MonthCodes = {
        'January': 'F',
        'February': 'G',
        'March': 'H',
        'April': 'J',
        'May': 'K',
        'June': 'M',
        'July': 'N',
        'August': 'Q',
        'September': 'U',
        'October': 'V',
        'November': 'X',
        'December': 'Z',
    }

    def __init__(self, details=None):
        if details is None:
            now = time.localtime()
            month = now.tm_mon
            year = now.tm_year
            self.commodity = None
        else:
            for c in self.Commodities:
                if details.startswith(c.symbol):
                    self.commodity = c
                    symlen = len(c.symbol)
                    month = details[symlen:symlen+1]
                    year = details[symlen+1:]
                    if len(year) == 2:
                        year = '20'+year
                    year = int(year)
                    break
            else:
                raise ValueError("Unparseable details given: "+details)

        month = self.Months[month]
        if self.commodity is not None:
            month_code = self.MonthCodes[month]
            if month_code not in self.commodity.delivery_months:
                raise ValueError('Invalid delivery month for commodity: '+month)

        self.month = month
        self.year = year

    def __str__(self):
        c = self.commodity
        return 'Unspecified' if c is None else c.symbol + self.MonthCodes[self.month] + str(self.year)


    def explain(self):
        c = self.commodity
        return [ 'A FuturesContract for:',
                '\t{}: {} (on the {} exchange)'.format(c.symbol, c.future, c.exchange),
                '\tDated: {} ({}), {}'.format(self.month, self.MonthCodes[self.month], self.year),
                ]

cz2016 = FuturesContract('CZ2016')

print('\n'.join(cz2016.explain()))
print('\n')
print('Commodity:', cz2016.commodity)
print('Month:', cz2016.month)
print('Year:', cz2016.year)

print("\nHas __str__:", cz2016)

print("\n\n")
print("Future LBQ2014: (should be invalid, because Q):")
fc = FuturesContract('LBQ2014')