0

偽の株式市場プログラムの買い手と売り手を照合するストアド プロシージャを作成しようとしています。最終的には、これを使用してトランザクション テーブルにデータを入力し、人々の注文を確定したいと考えています。これは、SQL Server エージェント ジョブにも含まれます。ここに私が持っているテーブルがあります:

Id    UserId    Type    QtyRemaining    Price   CreatedOn
1      3        BUY     50              1.00    2012-09-09 05:25:48.4470000
2      6        BUY     50              1.00    2012-09-09 19:25:34.4300000
3      5        SELL    30              1.00    2012-09-09 19:22:59.5900000
4      3        SELL    50              0.90    2012-09-09 06:39:34.9100000
5      2        SELLALL 50              1.00    2012-09-09 04:10:01.8400000

これらの一致を行うには、いくつかの条件を満たす必要があります。

  1. 買い手は、「売り」注文の場合、買い手が希望する株式数以上の売り手を探す必要があります。「SELLALL」注文の場合、買い手が株式を購入するには数量が同じでなければなりません。例: 売り手は 50 株を売却する必要があり、買い手は同じ価格またはそれ以下の価格で 50 株を購入する必要があります。
  2. 買い手は、株式の最低価格を求めています。
  3. 上記の条件の売り手が複数いる場合、買い手は最低価格の後に最も古い売り株を最初に取得します。

したがって、トレーダーのペアは #1 と #4、#2 と #5 になります。したがって、#3 はまだ保留中です。

これは私が遊んでいたコードですが、最低価格と最も古いものを最初に適切に一致させることができません:

select o.*, oa.*, r.* from [Order] o
join OrderActivity oa on o.Id = oa.OrderId
join (
    select o2.Id, o2.VideoId, o2.UserId, oa2.Price, oa2.QtyRemaining, o2.[Type] from [Order] o2
    join OrderActivity oa2 on o2.Id = oa2.OrderId
    where o2.Type = 'buy' and oa2.Status = 'open'
) as r on (o.VideoId = r.VideoId and oa.Price <= r.Price and r.QtyRemaining = oa.QtyRemaining and o.UserId != r.UserId)
where (o.Type = 'sell' or o.Type = 'sellall') and oa.Status = 'open'
4

2 に答える 2

2

これを試して

簡単に言えば、

1.createddateに基づいて買い手をランク付けします(以下のクエリで株式として名前を付けます)
2。価格に基づいて売り手をランク付けします、createddate(lowNoldstockとして名前を付けます)
3。一致するランクを取得します

select stocks.*,lowNoldStock.* 
from    (select *,row_number() over(order by createdon) as buyerrank
         from stocktable(nolock)  where c='buy' ) stocks 
inner join 
       (select  *,row_number() over(order by price,createdon) as sellerrank
        from stocktable(nolock) where [type]='sell' or [type]='sellall' ) lowNoldstock
on      (stocks.qty<=lowNoldStock.qty and lowNoldStock.type='sell') 
       or (lowNoldStock.type='sellall' and stocks.qty=lowNoldStock.qty and stocks.price>=lowNoldStock.price)
where  lowNoldStock.sellerrank=stocks.buyerrank

SQLフィドルのテストスクリプト、何らかの理由でSQLフィドルの部分的な結果が表示されていますこれは私のローカルデータベースで機能します

于 2012-09-10T10:37:06.667 に答える
0

あなたはこれで遊ぶことを歓迎します:

declare @Transactions as Table
  ( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
insert into @Transactions ( Id, UserId, Type, QtyRemaining, Price, CreatedOn ) values
  ( 1, 3, 'BUY',     50, 1.00, '2012-09-09 05:25:48.447' ),
  ( 2, 6, 'BUY',     50, 1.00, '2012-09-09 19:25:34.430' ),
  ( 3, 5, 'SELL',    30, 1.00, '2012-09-09 19:22:59.590' ),
  ( 4, 3, 'SELL',    50, 0.90, '2012-09-09 06:39:34.910' ),
  ( 5, 2, 'SELLALL', 50, 1.00, '2012-09-09 04:10:01.840' )

-- Split the transactions into temporary working tables.
declare @Buyers as Table
  ( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
declare @Sellers as Table
  ( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
insert into @Buyers
  select Id, UserId, Type, QtyRemaining, Price, CreatedOn
    from @Transactions
    where Type = 'BUY'
insert into @Sellers
  select Id, UserId, Type, QtyRemaining, Price, CreatedOn
    from @Transactions
    where Type like 'SELL%'

-- Process the buy orders in the order in which they were created.
declare @BuyerId as Int = ( select top 1 Id from @Buyers order by CreatedOn )
declare @SellerId as Int
declare @Balance as Int

while @BuyerId is not NULL
  begin
  -- Pair a seller, if possible, with the current buyer.
  ; with Willard as (
  select Row_Number() over ( order by S.Price, S.CreatedOn ) as Priority,
    S.Id as S_Id, S.QtyRemaining as S_QtyRemaining,
    B.QtyRemaining as B_QtyRemaining
    from @Sellers as S inner join
      @Buyers as B on B.Id = @BuyerId and
        case 
          when S.Type = 'SELL' and B.QtyRemaining <= S.QtyRemaining then 1
          when S.Type = 'SELLALL' and B.QtyRemaining = S.QtyRemaining then 1
          else 0
          end = 1
    ) 
  select @SellerId = S_Id, @Balance = S_QtyRemaining - B_QtyRemaining
    from Willard
    where Priority = 1
  -- Display the result.
  select @BuyerId as BuyerId, @SellerId as SellerId, @Balance as RemainingShares
  -- Update the working tables.
  if @Balance = 0
    delete from @Sellers
      where Id = @SellerId
  else
    update @Sellers
      set QtyRemaining = @Balance
      where Id = @SellerId
  delete from @Buyers
    where Id = @BuyerId
  -- Find the next buy order.
  set @BuyerId = ( select top 1 Id from @Buyers order by CreatedOn )
  end

-- Display any unfilled orders.
select 'Unmatched Buy', *
  from @Buyers
select 'Unmatched Sell', *
  from @Sellers
于 2012-09-10T00:56:05.627 に答える