我正在建立一个交易应用程序,以匹配拥有订阅的买家/卖家。订阅在特定持续时间内具有一定数量的金额。有8种订单类型:
填写
的每个用户假设此示例中的所有订单可以在数量和时间方面得到部分填充,我们可以说用户A在2014年1月1日至2014年1月3日期间发出要求100股的买单(dd / mm / yyyy) 。
目前订单簿中有4个卖单
看起来像
User A |--------------100-----------|
User B |----------------------------25-----------------------|
User C |-------------------50---|
User D |--------------70------------------|
User E |--5--|
匹配完成后,订单簿中的每个用户订单都会显示为
User A |-25--| |----5-----|
User B |------25----| |----25-----|
User C |------50----|
User D |----70-----|
User E has no open orders
毕竟说完了,订单看起来像是:
此示例完全相同,除非用户B销售所有数量和时间订阅类型。换句话说,用户B想要出售他/她的整个职位。
匹配完成后,订单簿中的每个用户订单都会显示为
User A |-50--| |--25-|----30----|
User B |----------------------------25-----------------------|
User C |------50----|
User D |-20--| |----70-----|
User E has no open orders
毕竟说完了,订单看起来像是:
另一个要求是我需要能够跟踪数据库中订单的填写方式。当用户A的购买订单进入时,它将首先与用户B匹配,这将导致:
User A |--------------75------------|
User B |------25----| |----25-----|
这两个状态都需要保存到数据库中。完成后,用户C的订单会匹配,如下所示:
User A |-----25----|------75--------|
User B |------25----| |----25-----|
User C |------50----|
继续前进:
User A |--25-| |-------5--------|
User B |------25----| |----25-----|
User C |------50----|
User D |----70-----|
当前流程
如果我在订单簿中有多个订单时没有正常工作,那就已经成功了。问题可能在于,对于每个卖单而言,我总是将其与原始买单进行比较,而实际上买单随着卖单的重复而被填满。也许我需要另一个嵌套循环?我不确定。
有没有现成的算法可以做我要问的事情?
编辑:经过一些搜索后,它似乎就像我在一个间隔树或一个分段树之后,在那里我可以总结一下给定时间内树中的内容范围。但是,我需要能够使用start和dates将修改存储在数据库中。 LINQ或SQL是否有任何实现?
编辑2:在我的第一次编辑中,我认为它是间隔树,但现在看起来更像bin packing algorithm
编辑3 好的,所以我似乎没有在这里正确地传达我的问题。我没有真正的编码问题,但更多的是如何正确实现这一目标的思考问题。我需要一个流程图或执行步骤,以便能够通过根据顶部概述的条件拆分订阅来处理买方和卖方。
我发布了同样的问题@ https://softwareengineering.stackexchange.com/,以防这是发布此问题的错误网站。
答案 0 :(得分:2)
显然,每个买/卖订单都需要自行处理,基础应该相对简单。填写你可以做的,提交部分(如果部分允许),然后继续直到订单完成。
显然,这个查询是一个样本,因为没有真正的结构,也没有实际引用的SQL数据库,但原则应该是相同的。
SELECT
buy.OrderID BuyOrderID,
buy.qty BuyQty,
buy.price BuyPrice,
sell.OrderID SellOrderID,
sell.qty SellQty,
sell.price SellPrice
from
pendingOrders buy
JOIN pendingOrders sell
ON buy.stock = sell.stock
AND sell.orderType = 'sell'
AND ( sell.beginDate between buy.beginDate and buy.endDate
OR sell.endDate between buy.beginDate and buy.endDate )
AND (( buy.qty = sell.qty )
OR ( buy.qty > sell.qty AND buy.AllowPartial )
OR ( buy.qty < sell.qty AND sell.AllowPartial ))
where
buy.OrderID = SampleParmBuyOrderIDTryingToBeFilled
order by
ABS( buy.price - sell.price ) DESC
因此,对于此示例中的单个购买订单,您只需要传递您要填写的订单。您甚至可能希望对其进行限制,因此它不会尝试返回您实际上永远无法获得的100多个条目。
现在让我们看看这个查询的逻辑,它几乎可以满足您的所有需求。首先,该示例以特定ID的已知“购买”顺序开始。所以我们从你的桌子的“PendingOrders”开始,并给它别名“买”。然后我们用别名“Sell”将它加入到同一个表中。
加入条件显然是针对相同的股票,并且“卖出”版本必须是“卖出”类型才能填写您想要的“买入”订单。此外,您只关心卖家提供的那些股票在买家寻求履行的时间范围内某个地点的开始或结束日期。这预先评定了主要目标。
现在,基于部分买入或卖出的唯一稍微更难的。如果买方和卖方都考虑到相同的数量,那么任何一方是否有部分时间/数量或全部或全部订单都无关紧要。它们具有相同的数量,并且在时间范围内,无论如何都是双方的。
下一个OR正在检查买方是否想要卖方提供的更多且买方允许部分填写订单。卖家,谁在乎,他们想要摆脱他们的股份,你会把它们全部拿走,所以卖方要点的全部或部分是没有考虑的。
最后一个OR是买方希望的价格低于卖方提供的,但如果买方允许部分填写订单,那么买方是全部还是部分,卖方的数量无关紧要将填写他们的订单...只有确认是卖方允许部分出售他们的股票。
现在,您将获得所有可能合格交易的清单,但现在是价格。作为贸易经纪人,您基本上保持买方和卖方商定价格之间的差异。所以你想要两者之间最大的差距。如果有人想以每股100美元的价格购买,而有人提出以90美元的价格出售,另有人以95美元的价格出售,那么您可能希望首先卖出90美元的股票,以获得10美元的保证金分割与5美元的保证金分割。
也就是说,ORDER BY子句将获得DESCENDING订单中买入/卖出价格之间的绝对值差异,因此最大的保证金位于工作列表的顶部。
现在,您可以获得结果,并由您自己尝试从一个交易中进行交易,从另一个交易以完成交易。如果在获得提交之前使用了结果集中的第一条记录,则显然需要滚动到下一个可用事务,直到完成为止。然后,继续前进,直到完成订单的所有数量都被提交。
如果您正在测试SELL交易并寻找给定股票的买家,则会应用REVERSE查询,但这应该满足您的需求。这只是一个交易承诺的问题,取决于实际上有多少进程实际上自动填充订单并与处理相同订单的多次尝试相冲突。
答案 1 :(得分:0)
您不能每天处理订单吗?也就是说,如果出现多日订单,请分别处理每一天?这会简化事情。此外,对于多日订单的每一天,您将存储当天仍有多少订单。
哪个订单获得满意的确切规则取决于您/您的老板决定(最老的匹配价格?最便宜?无论如何?)。
不确定性能要求是什么,但每天处理很可能符合要求。如果没有,这是一个很好的第一步。
答案 2 :(得分:0)
对我来说听起来像背包问题,其目标是尽量减少成本而不是重量。认为购买订单是您每天必须填写的麻烦。有一个动态编程解决方案,它优雅,需要更少的内存。但是我怀疑你能得到它是如何填充的历史数据。
我从互联网获得的随机资源: http://www.programminglogic.com/knapsack-problem-dynamic-programming-algorithm/
如果您想进一步学习,我建议您阅读[Steven Skienna的算法设计手册]中的解释(http://www.amazon.com/Algorithm-Design-Manual-Steven-Skiena/dp/1848000693)
希望这有帮助。