Блог им. happyseller

ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)

Просто посмотрите картинки.
Это личное наблюдение. Не претендую на объективность.
ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)
ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)
ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)
ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)
ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)


ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)
ВСЕ ЗАВИСИТ ОТ ГЛУБИНЫ НАЛИТОГО СТАКАНА)
8 комментариев
И что? Времени не видно. Там за несколько секунд может всё сильно поменяться при высокой волатильности. Надо выгружать стаканы, например через quik.OnQuote или через tinkoff api и сравнивать по серверному времени, а не вот это вот всё. Позавчера по газпрому были покупки и продажи по маркету  вообще на 60+ миллионов, понятно что стакан шатало.
Михаил Михалёв, я пометил, что не претендую на объективность. Запись экрана мне не давал сделать запрет от одного из брокеров. Но никто никого не догонял. То есть сбер и альфа в унисон, т по своему, не догоняя и не опережая. Спасибо за совет, но я не умею пока делать выгрузки.
avatar
Happyseller, Код для сохранения стакана из quik.

function formatdate(dt)
       return string.format("%04d-%02d-%02d", dt.year, dt.month, dt.day)
end

function formatdatetime(dt)
       return string.format("%04d-%02d-%02d %02d:%02d:%02d.%03d", dt.year, dt.month, dt.day, dt.hour, dt.min, dt.sec, dt.ms)
end

function formattime(dt)
       return string.format("%02d:%02d:%02d.%03d", dt.hour, dt.min, dt.sec, dt.ms)
end

function log_filename(dt)
       return «c:\\Program Files\\QUIK_AD\\Quik\\scripts\\»… formatdate(dt)… "_all_quote.csv"
end

function print_table(name, tbl)
       message(«table: »… name)
       for key in pairs(tbl) do
               local val = tbl[key]
               if type(val) == «table» then
                       print_table(".."… key, val)
               else
                       message("  "… key… ": "… val)
               end
       end
       message(«end table: »… name)
end

function format_cup(cup)
       --message(t)
       local s = ""

       if cup == nil then
               return s
       end

       if type(cup) == «table» then
               for n in pairs(cup) do
                       local bar = cup[n]
                       s = s… bar[«price»]… ":"… bar[«quantity»]… ","
               end
       end

       return s
end

codes = {}
codes[«FESH»] = 1
codes[«VTBR»] = 1
codes[«YNDX»] = 1
codes[«MTLRP»] = 1
codes[«MAGN»] = 1
codes[«CHMF»] = 1

last_dt = nil

function OnAllTrade(tbl)
       --message(«OnAllTrade»)
       last_dt = tbl.datetime
end

function OnQuote(cls, code)
       if codes[code] ~= nil and last_dt ~= nil then
               --message(«OnQuote »… code)
               local tm = formattime(last_dt)

               local quote = getQuoteLevel2(cls, code)

                — bids
               local csv_line = tm… ";"… code… ";"
               if quote.bid_count ~= «0» then
                       --print_table(«bid», quote.bid)
                       csv_line = csv_line… format_cup(quote.bid)
               end
               csv_line = csv_line… ";"

                — offers
               if quote.offer_count ~= «0» then
                       csv_line = csv_line… format_cup(quote.offer)
               end
               csv_line = csv_line… "\n"


               local file = io.open(log_filename(last_dt), «a»)
               file:write(csv_line)
               io.close(file)
       end
end

stopped = false

function OnStop(s)
       stopped = true
end

function main()
       for code in pairs(codes) do
               Subscribe_Level_II_Quotes(«TQBR», code)
       end

       while not stopped do  
               sleep(1000)
       end

       for code in pairs(codes) do
               Unsubscribe_Level_II_Quotes(«TQBR», code)
       end
end
Happyseller, Код для выгрузки стакана для тинькова (не проверял, сгенерил только что):

import csv
import datetime
from tinkoff.invest import Client, MarketDataRequest, SubscribeOrderBookRequest, OrderBookInstrument
from tinkoff.invest.services import MarketDataStreamManager
from tinkoff.invest.utils import quotation_to_decimal

TOKEN = "ваш_токен_доступа"  # Замените на ваш реальный токен Tinkoff Invest API
CSV_FILE = "orderbook_data.csv"
INSTRUMENTS = [
    {"figi": "BBG004730N88", "sec_code": "SBER"},  # Пример для Сбера
    {"figi": "BBG0047315Y7", "sec_code": "GAZP"},  # Пример для Газпрома
    # Добавьте другие инструменты по аналогии
]

def save_orderbook_to_csv(timestamp, sec_code, bids, offers):
    with open(CSV_FILE, mode='a', newline='') as file:
        writer = csv.writer(file, delimiter=';')
        
        # Форматируем bids и offers в строки
        bids_str = ",".join([f"{price}:{quantity}" for price, quantity in bids])
        offers_str = ",".join([f"{price}:{quantity}" for price, quantity in offers])
        
        writer.writerow([timestamp, sec_code, bids_str, offers_str])

def process_orderbook(orderbook, sec_code):
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
    
    # Получаем биды (покупка)
    bids = []
    for bid in orderbook.bids:
        price = float(quotation_to_decimal(bid.price))
        quantity = bid.quantity
        bids.append((price, quantity))
    
    # Получаем оферы (продажа)
    offers = []
    for offer in orderbook.asks:
        price = float(quotation_to_decimal(offer.price))
        quantity = offer.quantity
        offers.append((price, quantity))
    
    # Сохраняем в CSV
    save_orderbook_to_csv(timestamp, sec_code, bids, offers)
    print(f"Saved orderbook for {sec_code} at {timestamp}")

def main():
    # Инициализируем CSV файл с заголовками
    with open(CSV_FILE, mode='w', newline='') as file:
        writer = csv.writer(file, delimiter=';')
        writer.writerow(["tm", "sec_code", "bids", "offers"])
    
    with Client(TOKEN) as client:
        market_data_stream: MarketDataStreamManager = client.create_market_data_stream()
        
        # Подписываемся на стаканы для всех инструментов
        for instrument in INSTRUMENTS:
            market_data_stream.order_book.subscribe(
                SubscribeOrderBookRequest(
                    instruments=[
                        OrderBookInstrument(
                            figi=instrument["figi"],
                            depth=10  # Глубина стакана
                        )
                    ]
                )
            )
        
        # Обрабатываем входящие сообщения
        for market_data in market_data_stream:
            if market_data.orderbook:
                # Находим sec_code для этого figi
                sec_code = next(
                    (item["sec_code"] for item in INSTRUMENTS 
                     if item["figi"] == market_data.orderbook.figi),
                    None
                )
                if sec_code:
                    process_orderbook(market_data.orderbook, sec_code)

if __name__ == "__main__":
    main()
Михаил Михалёв, к сожалению в режиме 2 окон телефон не показывает время. Если вам интересно, могу написать время любого скриншота. Сделаны они в чт, 15 мая с 8.10 до 8.40
avatar
Happyseller, Мне пока не интересно. Когда будет интересно, я выгружу и напишу скрипт для сравнения:)  Я тиньков api использую только для датамайнига, а не для торговли — с такими комиссиями на фьючерсы пусть сами торгуют.
Михаил Михалёв, спасибо
avatar

теги блога Happyseller

....все тэги



UPDONW
Новый дизайн