我有一个Deal类,它具有多个状态:新建,已购买,已完成,趋势和交叉属性。交易实例可以随时更改趋势和交叉交易-取决于市场情况。
取决于当前的“趋势”,“交叉”以及其他可能发生的情况,可以采用不同的方式处理
我尝试了战略和责任链模式,但是我的知识和经验不足以正确地做到这一点。我不确定做出正确的决定。
现在它可以工作了,但这真是个ifs的地狱
async def check_deal(deal):
if deal.is_new():
if deal.current_trend == UP_TREND and CROSSED_TOP_GREEN in deal.crossing:
return await deal.create_order(CROSSED_TOP_GREEN)
if deal.current_trend == FLAT_TREND and CROSSED_BOTTOM_ORANGE in deal.crossing:
return await deal.create_order(CROSSED_BOTTOM_ORANGE)
if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM in deal.crossing:
return await deal.create_order(CROSSED_BOTTOM)
if deal.is_bought() and not deal.candle_has_order:
if deal.current_trend == UP_TREND and CROSSED_BOTTOM_GREEN in deal.crossing:
return await deal.create_order(CROSSED_BOTTOM_GREEN)
else:
return await deal.update_deal()
if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM in deal.crossing:
return await deal.create_order(CROSSED_BOTTOM)
else:
return await deal.update_deal()
else:
return await deal.update_deal()
if deal.is_profitable() and len(deal.orders) == 1 :
if deal.current_trend == UP_TREND and CROSSED_TOP in deal.crossing:
return await deal.trailing_enable(CROSSED_TOP)
if deal.current_trend == FLAT_TREND and CROSSED_TOP_GREEN in deal.crossing:
return await deal.trailing_enable(CROSSED_TOP_GREEN)
if deal.current_trend == DOWN_TREND and CROSSED_BASIS in deal.crossing:
return await deal.trailing_enable(CROSSED_BASIS)
if deal.is_profitable() and len(deal.orders) > 1:
if deal.current_trend == UP_TREND and CROSSED_BASIS in deal.crossing:
return await deal.trailing_enable(CROSSED_BASIS)
if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM_GREEN in deal.crossing:
return await deal.trailing_enable(CROSSED_BOTTOM_GREEN)
规则
电流穿越是一个变量,可以随时不同 当前趋势是一个变量,随时都可能不同
我们在以下一种情况下开始交易:
在以下情况之一中,我们将资金添加到当前交易中:
在以下情况之一中,我们通过交易获利:
如果不满足deal.is_bought()和其他任何条件,我们只会更新交易
答案 0 :(得分:3)
这里的内容是:当满足条件时,需要执行动作 。
您可以定义一个接口(可以使用简单的基类或抽象基类)来捕获它。然后为各种 if -> action 添加添加实现此接口的类(从基类继承)。
这是一个例子:
class Rule:
def isMetBy(self, deal):
pass
def execute(self, deal):
pass
class Rule1(Rule):
def isMetBy(self, deal):
return deal.current_trend == FLAT_TREND and CROSSED_BOTTOM_ORANGE in deal.crossing
async def execute(self, deal):
return await deal.create_order(CROSSED_BOTTOM_ORANGE)
class Rule2(Rule):
def isMetBy(self, deal):
return deal.current_trend == DOWN_TREND and CROSSED_BOTTOM in deal.crossing
async def execute(self, deal):
return await deal.create_order(CROSSED_BOTTOM)
rules = [Rule1(), Rule2()]
async def check_deal(deal):
for rule in rules:
if(rule.isMetBy(deal)):
return await rule.execute(deal)
每个规则捕获一个if语句就是您的代码。这样,您可以定义所需的任意多个规则。添加新类仅是添加另一个类的问题。如果可以的话,可以使用好名字为规则命名,这样可以增加好处或命名您的规则。我使用Rule1和Rule2是因为我不知道您的规则是什么意思。例如,您可以有类似的内容(我只是出于说明目的而编造的) EnableTrailingForProfitableDealsRule 。
在您的情况下,您有一个 if ,其中有多个 subif's 。您可以将它们分离为不同的类,也可以使用Composite pattern创建具有 子规则 的 规则 >。
这是一个例子:
class CompositeRule(Rule):
subRules = []
def __init(self):
self.subRules = [Rule1(), Rule2()]
def isMetBy(self, deal):
if deal.is_profitable() and len(deal.orders) == 1 :
for rule in self.subRules:
if(rule.isMetBy(deal)):
return true;
return false
async def execute(self, deal);
for rule in self.subRules:
if(rule.isMetBy(deal)):
return await rule.execute(deal)
CompositeRules
可以使代码更容易理解。如果使用CompositeRules
很难理解代码,则可以改用简单的规则。如果其中有成文法,这些简单规则中的许多规则将具有相同的含义,但这通常不是问题。
这是CompositeRule
分解为两个简单的规则:
class Rule1(Rule):
def isMetBy(self, deal):
return if deal.is_profitable() and len(deal.orders) == 1 and deal.current_trend == UP_TREND and CROSSED_TOP in deal.crossing
async def execute(self, deal):
return await deal.trailing_enable(CROSSED_TOP)
class Rule2(Rule):
def isMetBy(self, deal):
return if deal.is_profitable() and len(deal.orders) == 1 and deal.current_trend == FLAT_TREND and CROSSED_TOP_GREEN in deal.crossing:
async def execute(self, deal):
return await deal.trailing_enable(CROSSED_TOP_GREEN)
您可以尝试并选择最适合自己的方法。
答案 1 :(得分:2)
代码复杂的一个原因是您以过程的方式处理对象:check_deal
正在检查交易的属性并基于决策在他们身上,然后调用交易的方法。这种逻辑属于Deal
类,例如Deal.check
方法。
将逻辑移到Deal
类中并不会使其变得那么复杂,但是它为选择不同的设计开辟了道路。
例如,可以检查Deal
,NewDeal
和BoughtDeal
的子类,而不用检查条件代码块中的FinishedDeal
是新的还是购买的或完成的子类。 {1}}方法仅与影响这些特定类型的决策有关。
如果在您的应用程序中没有必要使用类型子类化,则策略模式可能是实现此目的的另一种方法-一个check
类,但可以根据交易类型提供不同的检查策略。
另一种方法可能是将Deal
的生命周期中的事件建模为状态机。创建代表生命周期各个阶段的Deal
类,这些类知道要采取的适当操作以及如何决定下一个状态应该是什么(责任链在这里可能有用)。这可能需要仔细建模,以防止State
和Deal
之间的过度耦合。
简而言之,请尝试构建业务逻辑,以使您不必进行决策的类:它们只是做对了事,或者至少用最少的条件代码来做对事。
答案 2 :(得分:0)
现在它可以工作了,但这真是ifs的地狱。
您的if
-逻辑有缺陷-您的代码无法访问
if deal.is_bought() and not deal.candle_has_order:
if deal.current_trend == UP_TREND and CROSSED_BOTTOM_GREEN in deal.crossing:
return await deal.create_order(CROSSED_BOTTOM_GREEN)
else:
return await deal.update_deal()
# Neither of the following will EVER happen, you already
# left the function with the _else_ from above:
if deal.current_trend == DOWN_TREND and CROSSED_BOTTOM in deal.crossing:
return await deal.create_order(CROSSED_BOTTOM)
else:
return await deal.update_deal()
我尝试了战略和责任链模式,但是我的知识 并且经验不足以正确地做到这一点。我不确定 做出了正确的决定。
在不知道您的规则是什么的情况下,我们有点无法提供帮助。如果您放下所有规则,则可能变得太宽泛而无法在此处解决。
答案 3 :(得分:0)
如果使用“ elif”,则会使计算机工作变得容易一些,因为它会首先检查“ if”,如果为true,它将忽略与该“ if”相关的所有“ elif”和“ else”,但是如果您在每种情况下都使用“ if”(就像您一样),则计算机将遍历每个“ if”语句并进行检查。我希望这是有道理的。