スカルプチャー

昨日は静かに座っていました。いつものように誰も気にしません。ここでは、2つの異なる連絡先から、SQLからのJSONに関する悪名高いツイートへのリンクをほぼ同時に送信しています。メッセージの1つは次のようになりました。





それはすでに直接的な挑戦でした。私は彼を無視できなかった。それで、私はまだ私に曖昧な感情を呼び起こす話をすることに決めました。3年後。



その祝福された時間に、誰もが暗号を夢見て、ICOに従事し、暗号交換を彫刻しました。本当に新しいものでした。私は、古典的な資産管理(株式、債券など)のシステムを作成した経験があります。問題は、それが会計システムを中心に形成されたことでした。私は交換を作成することで自分自身を実現したかった。当然のことながら、私はこの沸騰する大釜に喜んで飛び込みました。



これが背景です。興味深いことがたくさんありましたが、今日は特定のケース、つまりマッチャーをどのように作成したかについてお話ししたいと思います。



マッチャー、これは交換の中核です。トランザクションが行われるのはその中にあります。古典的なステレオタイプでは、これは高性能サブシステムです。しかし、これは大規模な取引所にも当てはまります。そこでは、売買のためのオープンアプリケーションが数十万にあります。



“ ” . . — , . — .



.



Java . , , . , . “” . .



. , , “” . . , 270 . RabbitMQ. ….



. . 2 . , , . , , .



. . .. , … , .. . - :



! ()

, . . … . .



, . , . , . — .



, . , 100, 5. 100 7 . , .



SQL . , . MySQL . , MySQL . .. . :



SET depth_sell.`limit` = depth_sell.`limit` - IF(
                    ((@tofill := IF(
                            depth_sell.`limit` <= @limit,
                            depth_sell.`limit`,
                            @limit
                        ))
                        + (@limit := @limit - @tofill)),
                    @tofill,
                    @tofill
                ),
        depth_sell.`executed` = @tofill
WHERE @limit > 0;




@limit := @limit - @tofill


() .



IN MEMORY . .. . .



. — . . , , .



CREATE TABLE transactions
(
    id INT AUTO_INCREMENT PRIMARY KEY,
    moment TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
    side1 INT NOT NULL,
    side2 INT NOT NULL,
    price BIGINT NOT NULL,
    volume BIGINT NOT NULL
);

CREATE TABLE depth_buy
(
    id BIGINT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    order_id  BIGINT NOT NULL,
    type INT DEFAULT '0' NOT NULL,
    market INT DEFAULT '0' NOT NULL,
    account INT NOT NULL,
    price BIGINT DEFAULT '0' NOT NULL,
    `limit` BIGINT DEFAULT '0' NOT NULL,
    taker INT,
    rev_price BIGINT NOT NULL,
    executed BIGINT
) ENGINE = MEMORY;

CREATE TABLE depth_sell
(
    id BIGINT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    order_id  INT NOT NULL,
    type INT DEFAULT '0' NOT NULL,
    market INT DEFAULT '0' NOT NULL,
    account INT NOT NULL,
    price BIGINT DEFAULT '0' NOT NULL,
    `limit` BIGINT DEFAULT '0' NOT NULL,
    taker INT,
    rev_price BIGINT NOT NULL,
    executed  BIGINT
) ENGINE = MEMORY;


CREATE PROCEDURE `make_order_v2`(IN order_id INT,
                                 IN order_type INT,
                                 IN order_account INT,
                                 IN order_market INT,
                                 IN order_limit BIGINT,
                                 IN order_price BIGINT)
BEGIN
    START TRANSACTION;
    SET @limit := order_limit;
    IF order_type = 21 THEN
        UPDATE depth_sell
            INNER JOIN (
                SELECT id
                FROM depth_sell
                WHERE market = order_market
                  AND depth_sell.price <= order_price
                ORDER BY depth_sell.price + id ASC
            ) source ON depth_sell.id = source.id
        SET depth_sell.taker      = order_id,
            depth_sell.`limit`    = depth_sell.`limit` - IF(
                    ((@tofill := IF(
                            depth_sell.`limit` <= @limit,
                            depth_sell.`limit`,
                            @limit
                        ))
                        + (@limit := @limit - @tofill)),
                    @tofill,
                    @tofill
                ),
            depth_sell.`executed` = @tofill
        WHERE @limit > 0;

        INSERT INTO transactions (moment, side1, side2, price, volume)
        SELECT now(), depth_sell.id, order_id, depth_sell.price, depth_sell.executed
        FROM depth_sell
        WHERE depth_sell.`taker` = order_id;

        DELETE
        FROM depth_sell
        WHERE market = order_market
          AND depth_sell.`limit` = 0;

        IF @limit > 0 THEN
            INSERT INTO depth_buy (order_id, type, market, account, price, rev_price, `limit`)
            VALUES (order_id, order_type, order_market, order_account, order_price, -order_price, @limit);
        END IF;
    ELSE
        UPDATE depth_buy
            INNER JOIN (
                SELECT id
                FROM depth_buy
                WHERE market = order_market
                  AND depth_buy.price >= order_price
                ORDER BY depth_buy.rev_price - id ASC
            ) source ON depth_buy.id = source.id
        SET depth_buy.taker      = order_id,
            depth_buy.`limit`    = depth_buy.`limit` - IF(
                    ((@tofill := IF(
                            depth_buy.`limit` <= @limit,
                            depth_buy.`limit`,
                            @limit
                        ))
                        + (@limit := @limit - @tofill)),
                    @tofill,
                    @tofill
                ),
            depth_buy.`executed` = @tofill
        WHERE @limit > 0;

        INSERT INTO transactions (moment, side1, side2, price, volume)
        SELECT now(), depth_buy.id, order_id, depth_buy.price, depth_buy.executed
        FROM depth_buy
        WHERE depth_buy.`taker` = order_id;

        DELETE
        FROM depth_buy
        WHERE market = order_market
          AND depth_buy.`limit` = 0;
        IF @limit > 0 THEN
            INSERT INTO depth_sell (order_id, type, market, account, price, rev_price, `limit`)
            VALUES (order_id, order_type, order_market, order_account, order_price, -order_price, @limit);
        END IF;
    END IF;
    COMMIT;
END;


CREATE PROCEDURE do_load_matcher_v2(IN market INT)
BEGIN
    DECLARE count INT DEFAULT 100000;
    WHILE count > 0 DO
            call make_order_v2(
                    count,
                    IF(count % 2 = 0, 21, 22),
                    1,
                    market,
                    FLOOR(1 + (RAND() * 1000)),
                    FLOOR(1 + (RAND() * 1000))
                );
            SET count = count - 1;
        END WHILE;
END;


, .. . :



  1. depth_buy — ;
  2. depth_sell — ;
  3. transaction — = .


make_order_v2 :



  1. order_id — .
  2. order_type — . 21 — , 22 — .
  3. order_account — ( ).
  4. order_market — . .
  5. order_limit — . . , 100. .. 1.15btc 115.
  6. order_price — . .


, . — . , . .



, .



, . . 100 . 95 . 1.46 . 570 . .



, . . , . . .. .



, ? :



  • . .
  • , , . .


:



  • . , . .
  • . . .


もちろん、すべてがDBMSを介して実行できるという元の投稿の作成者の楽観的な見方は共有していませんが、経験上、すべてがDBMSを介して実行できることが示されています。あなたがしたい場合は。したがって、あなたは自分の欲望に注意する必要があります。そうでなければ、あなたは何年もの間精神的な痛みを経験しなければならないでしょう。



すべて良いです!



元のツイート




All Articles