用Python实现自定义计数系统

2024-04-25 22:08:43 发布

您现在位置:Python中文网/ 问答频道 /正文

在金融学中,期货合约通常以到期年和到期月来表示。例如,201212将是2012年12月。你知道吗

有些合约,例如玉米,只在几个月[3,5,7,9,12]进行交易,而有时,你可能只想交易[12]合约(尽管它在其他月份也进行交易,所以你要交易201212201312等等)。你知道吗

我目前正在使用int格式在系统中表示这些契约,并将其用作索引。你知道吗

棘手的是,给定一份合同,我经常需要得到下一份合同(在较小程度上,是上一份)。你知道吗

我写了一个生成器表达式,它的作用如下:

def contract_generator(self, recent=True, year=None, month=None, traded_only=False):
    if year is None:
        year = datetime.datetime.now().year - 1 if recent == True else self.first_contract

    if traded_only is True:
        months = self.trade_only
    else:
        months = self.months_traded

    months = deque(months)

    if month is not None:
        months.rotate(months.index(month)-1)
    while True:
        for month in months:
            yield {
                'year': year,
                'month': month,
                'contract': str(year)+str("%02d" % (month,)),
                'formatted_contract': self.contract_format(year, month),
                'expiration_date': self.expiration_date(year, month)
                }
        year+=1

def next_contract(self, contract):
    c = contract_to_tuple(contract)
    j = self.contract_generator(year = c[0], month = c[1], traded_only=False)
    return next(j)['contract']

def contract_to_tuple(contract):
    contract = str(contract)
    return (int(contract[0:4]),int(contract[4:6]))

(其中months_traded&;trade_only是我在第2段中提到的列表)。你知道吗

关键的是,它的四轮马车和上述工作不太正确。我可以解决它,但老实说,我真的不喜欢这种方法。一定有更好的办法。你知道吗

想法:

  • 以某种方式使用datetime实现
  • 创建某种自定义对象,实现算术运算符,这样我就可以201212 + 1获得下一个契约(但是使用pandas真的很容易吗?)你知道吗
  • 我不认为python有这样的功能,但是也许我可以定义一个自定义的数字基来映射这种行为。你知道吗

有没有一种简单/优雅的方法可以做到这一点?还是我真的需要从头开始?你知道吗

编辑:

我的最终结果:

def nc(self, contract, months=None):
    d = pd.to_datetime(str(contract), format='%Y%m')
    months_traded = deque(self.months_traded)
    months_traded.rotate(-1)
    output_month = months_traded[self.months_traded.index(d.month)]
    output_year = d.year + 1 * d.month==12
    return str(output_year)+str("%02d" % (output_month,))

Tags: selfnonetrueonlyoutputdatetimeifdef
1条回答
网友
1楼 · 发布于 2024-04-25 22:08:43

这应该做到:

def next_contract(contract, last=False):
    d = pd.to_datetime(str(contract), format='%Y%m')
    d += pd.offsets.MonthBegin(12 * (last * -2 + 1))
    return int(d.strftime('%Y%m'))

演示

next_contract(201212)

201312

next_contract(201212, last=True)

201112

说明

def next_contract(contract, last=False):
    # convert contract to datetime with assumed format of yyyymm
    d = pd.to_datetime(str(contract), format='%Y%m')
    # use pandas offsets.  I don't care that it's month begin
    # because I'm ditching the day anyway.
    # (last * -2 + 1) equals -1 when last is True and 1 when last is False
    d += pd.offsets.MonthBegin(12 * (last * -2 + 1))
    return int(d.strftime('%Y%m'))

值得一提的是,这里有一个类的存根。老实说,把其他几个月的所有处理都编码起来应该留给你做练习。你知道吗

class Corn(object):
    def __init__(self, contract):
        self.contract = contract

    def __add__(self, i):
        d = pd.to_datetime(str(self.contract), format='%Y%m')
        d += pd.offsets.MonthBegin(12 * i)
        self.contract = int(d.strftime('%Y%m'))
        return self

    def __sub__(self, i):
        return self.__add__(-i)

    def get_next(self):
        return self + 1

    def get_last(self):
        return self - 1

    def __repr__(self):
        return str(self.contract)

corn = Corn(201212)
print(corn + 1)
print(corn.get_next())

201312
201412

相关问题 更多 >