如何组织类的结构?
How to organize the structure of classes?
我正在为外汇市场(二元期权)交易编写一个顾问程序。使用福汇 API。对于那些有趣的人。我有 5 个货币对。每一个都包含五个不同时间范围内的报价历史。例如,假设从一分钟到五分钟。每个历史必须有三个变量。 (最大,最小,最后)
报价历史在等于一分钟的时间范围内从 FXCM 加载一次,然后针对所有其他时间范围进行计算。我还有一个方法(或者我可以将它们组合成一个方法)用于实际数据,分别每分钟、每两分钟等执行一次,以在相应的历史记录中记录新形成的蜡烛。
我将附上一个我看到但不喜欢的 class 结构。
class Pair:
def __init__(self, name):
self.name = name
class Periods:
def __init__(self, name):
self.name = name
self.one = pd.DataFrame()
self.two = pd.DataFrame()
self.three = pd.DataFrame()
self.four = pd.DataFrame()
self.five = pd.DataFrame()
def get_historical_data(self): # Executed once
self.one = historical_data_one_minute
self.two = historical_data_two_minute
self.three = historical_data_three_minute
self.four = historical_data_four_minute
self.five = historical_data_five_minute
def set_actual_data(self, period): #Executed ones per minute
if period == '1min':
one_minute_candle = calculated_one_minute_candle
self.one = self.one.append(one_minute_candle)
if period == '2min':
two_minute_candle = calculated_two_minute_candle
self.two = self.two.append(two_minute_candle)
...
if period == '5min':
five_minute_candle = calculated_five_minute_candle
self.five = self.five.append(five_minute_candle)
如您所见,没有最大、最小和最后一个变量。这是因为我不知道如何把它们绑起来。我应该把 'Periods' 分成 class 吗,比如 One_minute、Two_minute 等等
添加变量还是有另一种方法?这个的 class 会不会太多了?
class One_minute:
def __init__(self):
self.largest = 0
self.smallest = 0
self.last = 0
def get_historical_data(self):
self.history = historical_data_one_minute
self.largest = calculated_largest_from_historical_data_one_minute
self.smallest = calculated_smallest_from_historical_data_one_minute
self.last = calculated_last_from_historical_data_one_minute
总的来说,结构如下
(currency pair) - one_minute_history ---- largest
| |___ smallest
| |___ last
|_two_minute_history ---- largest
| |___ smallest
| |___ last
|_and so on
或者
(currency pair) ------ one_minute_history
| |_ largest
| |_ smallest
| |_ last
|____ two_minute_history
| |_ largest
| |_ smallest
| |_ last
|____ three_minute_history
...
如果这样访问就方便了
eurusd.history[1] #gets one minute history
eurusd.history[1].largest or eurusd.largest.history[1] #gets largest price of one minute history
或者可能更好。
总的来说,我将有 25 个不同的历史数据框,每个货币对 5 个。而且对于每个历史数据框,我将有三个变量
我希望我能解释一下我需要得到什么。提前致谢!
编辑:
我认为无论历史数据如何计算但回答你的问题 - 这是这个方法
def get_historical_data(self, con): # Once
dtn = datetime.now()
hours = dtn.hour + 3
minutes = dtn.minute
data = con.get_candles(instrument, period = 'm1', start=dtn - timedelta(hours=hours, minutes=minutes), end=dtn)
self.one['open'] = (data['bidopen'] + data['askopen']) / 2
self.one['high'] = (data['bidhigh'] + data['askhigh']) / 2
self.one['low'] = (data['bidlow'] + data['asklow']) / 2
self.one['close'] = (data['bidclose'] + data['askclose']) / 2
self.one['direction'] = 'flat'
self.one.loc[self.one['close'] - self.one['open'] >= 0.00002, "direction"] = "up"
self.one.loc[self.one['close'] - self.one['open'] <= -0.00002, "direction"] = "down"
s = (self.one['direction'] != self.one['direction'].shift()).cumsum()
self.one['series'] = self.one.groupby(s).cumcount() + 1
self.one.loc[self.one['direction'] == 'flat', 'series'] = self.one['series'].subtract(1)
self.one = self.one.tz_localize(pytz.timezone('UTC'))
self.one = self.one.tz_convert(pytz.timezone('Europe/Moscow'))
self.one.to_csv('history.csv', index=True)
dct = {'date': 'first', 'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last'}
self.two = self.one.reset_index().groupby(np.arange(len(self.one)) // 2).agg(dct).set_index('date')
self.three = self.one.reset_index().groupby(np.arange(len(self.one)) // 3).agg(dct).set_index('date')
self.four = self.one.reset_index().groupby(np.arange(len(self.one)) // 4).agg(dct).set_index('date')
self.five = self.one.reset_index().groupby(np.arange(len(self.one)) // 5).agg(dct).set_index('date')
循环调用该函数。
con = fxcmpy.fxcmpy(config_file = 'fxcm.cfg') # Connection
periods = Periods("EUR/USD")
cycle_just_launched = True
while True:
time.sleep(60)
if cycle_just_launched:
periods.get_historical_data(con)
else:
periods.set_actual_data(con, "1min")
cycle_just_launched = False
似乎您需要封装“single-period 历史”的概念,然后您可以在此基础上构建其余部分。类似于:
class PeriodHistory:
def __init__(self, name, period):
self.name = name
self.period = period # e.g. 1min, 2min, etc.
self.data = pd.DataFrame()
self.largest = 0
self.smallest = 0
self.latest = 0
def load(self, historic_data):
# initialize data, largest, smallest, latest from historical
def update(self, new_data):
# update variables based on new data and self.period
然后 class 将 multi-period 个历史合并为一个:
class MultiPeriodHistory:
def __init__(self, name):
self.name = name
self.period = {}
for i in range(1, 6):
self.period[i] = PeriodHistory(self.name, i)
self.period[i].load(history_data_for_period[i])
def update(self):
new_data = get_data_from_api(self.name)
for i in range(1, 6):
self.period[i].update(new_data)
然后您可以使用字典为每个货币对存储 multi-history:
currencies = ('eur', 'usd', 'jpy', 'gbp', 'chf')
history = {}
for c1 in currencies:
for c2 in currencies:
if c1 != c2:
history[c1 + c2] = MultiPeriodHistory(c1 + c2)
现在,例如history['eurgbp'].period[3].smallest
给你想要的。
您可能需要修改您的数据获取并稍微更新以适应这种模式,我 hand-waved 很多,因为我没有完整的图片。
我正在为外汇市场(二元期权)交易编写一个顾问程序。使用福汇 API。对于那些有趣的人。我有 5 个货币对。每一个都包含五个不同时间范围内的报价历史。例如,假设从一分钟到五分钟。每个历史必须有三个变量。 (最大,最小,最后) 报价历史在等于一分钟的时间范围内从 FXCM 加载一次,然后针对所有其他时间范围进行计算。我还有一个方法(或者我可以将它们组合成一个方法)用于实际数据,分别每分钟、每两分钟等执行一次,以在相应的历史记录中记录新形成的蜡烛。 我将附上一个我看到但不喜欢的 class 结构。
class Pair:
def __init__(self, name):
self.name = name
class Periods:
def __init__(self, name):
self.name = name
self.one = pd.DataFrame()
self.two = pd.DataFrame()
self.three = pd.DataFrame()
self.four = pd.DataFrame()
self.five = pd.DataFrame()
def get_historical_data(self): # Executed once
self.one = historical_data_one_minute
self.two = historical_data_two_minute
self.three = historical_data_three_minute
self.four = historical_data_four_minute
self.five = historical_data_five_minute
def set_actual_data(self, period): #Executed ones per minute
if period == '1min':
one_minute_candle = calculated_one_minute_candle
self.one = self.one.append(one_minute_candle)
if period == '2min':
two_minute_candle = calculated_two_minute_candle
self.two = self.two.append(two_minute_candle)
...
if period == '5min':
five_minute_candle = calculated_five_minute_candle
self.five = self.five.append(five_minute_candle)
如您所见,没有最大、最小和最后一个变量。这是因为我不知道如何把它们绑起来。我应该把 'Periods' 分成 class 吗,比如 One_minute、Two_minute 等等 添加变量还是有另一种方法?这个的 class 会不会太多了?
class One_minute:
def __init__(self):
self.largest = 0
self.smallest = 0
self.last = 0
def get_historical_data(self):
self.history = historical_data_one_minute
self.largest = calculated_largest_from_historical_data_one_minute
self.smallest = calculated_smallest_from_historical_data_one_minute
self.last = calculated_last_from_historical_data_one_minute
总的来说,结构如下
(currency pair) - one_minute_history ---- largest
| |___ smallest
| |___ last
|_two_minute_history ---- largest
| |___ smallest
| |___ last
|_and so on
或者
(currency pair) ------ one_minute_history
| |_ largest
| |_ smallest
| |_ last
|____ two_minute_history
| |_ largest
| |_ smallest
| |_ last
|____ three_minute_history
...
如果这样访问就方便了
eurusd.history[1] #gets one minute history
eurusd.history[1].largest or eurusd.largest.history[1] #gets largest price of one minute history
或者可能更好。
总的来说,我将有 25 个不同的历史数据框,每个货币对 5 个。而且对于每个历史数据框,我将有三个变量
我希望我能解释一下我需要得到什么。提前致谢!
编辑: 我认为无论历史数据如何计算但回答你的问题 - 这是这个方法
def get_historical_data(self, con): # Once
dtn = datetime.now()
hours = dtn.hour + 3
minutes = dtn.minute
data = con.get_candles(instrument, period = 'm1', start=dtn - timedelta(hours=hours, minutes=minutes), end=dtn)
self.one['open'] = (data['bidopen'] + data['askopen']) / 2
self.one['high'] = (data['bidhigh'] + data['askhigh']) / 2
self.one['low'] = (data['bidlow'] + data['asklow']) / 2
self.one['close'] = (data['bidclose'] + data['askclose']) / 2
self.one['direction'] = 'flat'
self.one.loc[self.one['close'] - self.one['open'] >= 0.00002, "direction"] = "up"
self.one.loc[self.one['close'] - self.one['open'] <= -0.00002, "direction"] = "down"
s = (self.one['direction'] != self.one['direction'].shift()).cumsum()
self.one['series'] = self.one.groupby(s).cumcount() + 1
self.one.loc[self.one['direction'] == 'flat', 'series'] = self.one['series'].subtract(1)
self.one = self.one.tz_localize(pytz.timezone('UTC'))
self.one = self.one.tz_convert(pytz.timezone('Europe/Moscow'))
self.one.to_csv('history.csv', index=True)
dct = {'date': 'first', 'open': 'first', 'high': 'max', 'low': 'min', 'close': 'last'}
self.two = self.one.reset_index().groupby(np.arange(len(self.one)) // 2).agg(dct).set_index('date')
self.three = self.one.reset_index().groupby(np.arange(len(self.one)) // 3).agg(dct).set_index('date')
self.four = self.one.reset_index().groupby(np.arange(len(self.one)) // 4).agg(dct).set_index('date')
self.five = self.one.reset_index().groupby(np.arange(len(self.one)) // 5).agg(dct).set_index('date')
循环调用该函数。
con = fxcmpy.fxcmpy(config_file = 'fxcm.cfg') # Connection
periods = Periods("EUR/USD")
cycle_just_launched = True
while True:
time.sleep(60)
if cycle_just_launched:
periods.get_historical_data(con)
else:
periods.set_actual_data(con, "1min")
cycle_just_launched = False
似乎您需要封装“single-period 历史”的概念,然后您可以在此基础上构建其余部分。类似于:
class PeriodHistory:
def __init__(self, name, period):
self.name = name
self.period = period # e.g. 1min, 2min, etc.
self.data = pd.DataFrame()
self.largest = 0
self.smallest = 0
self.latest = 0
def load(self, historic_data):
# initialize data, largest, smallest, latest from historical
def update(self, new_data):
# update variables based on new data and self.period
然后 class 将 multi-period 个历史合并为一个:
class MultiPeriodHistory:
def __init__(self, name):
self.name = name
self.period = {}
for i in range(1, 6):
self.period[i] = PeriodHistory(self.name, i)
self.period[i].load(history_data_for_period[i])
def update(self):
new_data = get_data_from_api(self.name)
for i in range(1, 6):
self.period[i].update(new_data)
然后您可以使用字典为每个货币对存储 multi-history:
currencies = ('eur', 'usd', 'jpy', 'gbp', 'chf')
history = {}
for c1 in currencies:
for c2 in currencies:
if c1 != c2:
history[c1 + c2] = MultiPeriodHistory(c1 + c2)
现在,例如history['eurgbp'].period[3].smallest
给你想要的。
您可能需要修改您的数据获取并稍微更新以适应这种模式,我 hand-waved 很多,因为我没有完整的图片。