cjm*_*671 5 python numpy pandas
在金融中,期货合约通常以其到期年和月来表示.例如,201212将是2012年 - 12月.
有些合同,例如玉米,只成交了几个月[3,5,7,9,12],而有时,你可能只想要交易的[12]合同(尽管其交易其他月份也一样,所以你交易201212,201312等等).
我目前正在使用该int格式在我的系统中表示这些合同,并将其用作Pandas索引.
棘手的是,根据合同,我经常需要获得下一份合同(在较小程度上,前一份合同).
我写了一个生成器表达式,它做了这样的事情:
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]))
Run Code Online (Sandbox Code Playgroud)
(其中,months_traded&trade_only是我在第2段中提到的列表).
至关重要的是,它的马车和上面的工作不太正常.我可以解决它,但说实话,我真的不喜欢这种方法.肯定有更好的办法.
思路:
201212 + 1可以获得下一个合同(但是这对pandas来说真的很容易吗?)是否有一种简单/优雅的方式来做到这一点已经存在?或者我真的需要从头开始吗?
编辑:
我的最终结果:
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,))
Run Code Online (Sandbox Code Playgroud)
这应该可以做到:
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'))
Run Code Online (Sandbox Code Playgroud)
next_contract(201212)
201312
next_contract(201212, last=True)
201112
Run Code Online (Sandbox Code Playgroud)
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'))
Run Code Online (Sandbox Code Playgroud)
不管怎样,这里有一个类的存根。老实说,对其他月份的所有处理进行编码应该留给您作为练习。
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)
Run Code Online (Sandbox Code Playgroud)
corn = Corn(201212)
print(corn + 1)
print(corn.get_next())
201312
201412
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |