Skip to content

Commit

Permalink
描述你的更改
Browse files Browse the repository at this point in the history
  • Loading branch information
zr7goat committed Oct 5, 2023
1 parent 68c2e56 commit 61751da
Show file tree
Hide file tree
Showing 18 changed files with 1,453 additions and 9 deletions.
342 changes: 342 additions & 0 deletions Jerry's tests/ASQ_Backtest_Jerry.ipynb

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions Jerry's tests/CSV_Reader_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pandas as pd
from nautilus_trader.core.datetime import dt_to_unix_nanos

# timestamp_ns = pd.Timestamp("2022-01-01").value
# print(timestamp_ns)
# start = dt_to_unix_nanos(pd.Timestamp('2022-01-01', tz='UTC'))
# print(start)
# end_time=pd.Timestamp("2022-01-01 23:00:00").value
# print(end_time)
# 设置显示选项
pd.set_option('display.max_columns', None) # 显示所有列
pd.set_option('display.width', None) # 确保每一列都能完全显示
pd.set_option('display.max_rows', None) # 显示所有行
pd.set_option('display.max_colwidth', None) # 显示每一列的完整内容

# filename = r"D:\下载\DAT_ASCII_EURUSD_T_202308.csv"
# filename = r"D:\下载\BTC-USDT-220107.OK.csv"
# filename = r"D:\下载\LDOBUSD-bookTicker-2023-06\LDOBUSD-bookTicker-2023-06.csv"
filename = r"D:\下载\BTCUSDT-bookTicker-2023-09-17\BTCUSDT-bookTicker-2023-09-17.csv"
data = pd.read_csv(filename, nrows=10000)
data['spread'] = data['best_ask_price'] - data['best_bid_price']
data['midprice'] = (data['best_ask_price'] + data['best_bid_price']) / 2
data['midprice_change'] = data['midprice'].diff()
data['imbalance_-1to1'] = -data['best_ask_qty'] + data['best_bid_qty'] / data['best_ask_qty'] + data['best_bid_qty'] # 取值是-1到1之间,-1表示完全由卖单构成,1表示完全由买单构成
data['imbalance_0to1'] = data['best_ask_qty'] / data['best_ask_qty'] + data['best_bid_qty'] # 取值是0到1之间,0表示完全由卖单构成,1表示完全由买单构成
data['wmp'] = data['midprice'] + data['spread'] * data['imbalance_-1to1']/2
data['wmp_change'] = data['wmp'].diff()
data['dmp'] = data['midprice'] + data['spread'] * data['imbalance_-1to1'] * (data['imbalance_-1to1'] * data['imbalance_-1to1'] + 1) / 2 # 尚未完成,需要结合DMP公式考虑fee

print(data)
print(data.dtypes) # 查看每一列的数据类型
print(data.head()) # 查看head
print(data.columns) # 查看列名
#
# # pd.reset_option('display.max_columns')

72 changes: 72 additions & 0 deletions Jerry's tests/External_Data_Loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os, shutil
from datetime import date
import pandas as pd
from decimal import Decimal
from nautilus_trader.model.data.tick import QuoteTick
from nautilus_trader.model.objects import Price, Quantity
from nautilus_trader.core.datetime import dt_to_unix_nanos
from nautilus_trader.persistence.catalog import ParquetDataCatalog
from nautilus_trader.persistence.external.core import process_files, write_objects
from nautilus_trader.persistence.external.readers import CSVReader
from nautilus_trader.test_kit.providers import TestInstrumentProvider
from nautilus_trader.backtest.node import BacktestNode, BacktestVenueConfig, BacktestDataConfig, BacktestRunConfig, BacktestEngineConfig
from nautilus_trader.config import ImportableStrategyConfig


def parser(data, instrument_id):
"""
Parser function for OKX Tick data, for use with CSV Reader
Should check
1) the data structure of the file
2) “as_dataframe” true or false and
use from_str for string data and from_int for int data and return a QuoteTick object
"""
dt = pd.Timestamp(data['exchTimeMs'], unit='ms', tz='UTC')
yield QuoteTick(
instrument_id=instrument_id,
bid=Price.from_str(str(data['bidPx1'])),
ask=Price.from_str(str(data['askPx1'])),
bid_size=Quantity.from_int(data['bidCnt1']),
ask_size=Quantity.from_int(data['askCnt1']),
ts_event=dt_to_unix_nanos(dt),
ts_init=dt_to_unix_nanos(dt),
)

input_files = "D:\下载\BTC-USDT-220107.OK.csv" # "your_path_to_file"
CATALOG_PATH = "D:/backtest/backtest1/catalog02" # "your_path_to_catalog"
# Clear if it already exists, then create fresh
if os.path.exists(CATALOG_PATH):
shutil.rmtree(CATALOG_PATH)
os.mkdir(CATALOG_PATH)
catalog = ParquetDataCatalog(CATALOG_PATH) # Create a new ParquetDataCatalog instance

# Use nautilus test helpers to create a BTC/USDT Crypto instrument for our purposes
maker1 = Decimal(-0.000001)
taker1 = Decimal(0.0000143)
instrument = TestInstrumentProvider.btcusdt_future_OKX(expiry=date(2022, 1, 7), maker=maker1, taker=taker1)

# Add our new instrument to the ParquetDataCatalog and check its existence
write_objects(catalog, [instrument])
catalog.instruments()

# Loading the files (the header can be customized)
process_files(
glob_path=input_files,
reader=CSVReader(
block_parser=lambda x: parser(x, instrument_id=instrument.id),
header=None,
chunked=False,
as_dataframe=True,
),
catalog=catalog,
)

# Also manually write the instrument to the catalog
write_objects(catalog, [instrument])

# Using the data Catalog
start = dt_to_unix_nanos(pd.Timestamp('2022-01-01', tz='UTC'))
end = dt_to_unix_nanos(pd.Timestamp('2022-01-01 23:00:00', tz='UTC'))

catalog.quote_ticks(start=start, end=end)
74 changes: 74 additions & 0 deletions Jerry's tests/External_Data_Loader_OKX.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import os, shutil
import pandas as pd
from decimal import Decimal
from nautilus_trader.model.data.tick import QuoteTick
from nautilus_trader.model.objects import Price, Quantity
from nautilus_trader.core.datetime import dt_to_unix_nanos
from nautilus_trader.persistence.catalog import ParquetDataCatalog
from nautilus_trader.persistence.external.core import process_files, write_objects
from nautilus_trader.persistence.external.readers import CSVReader
from nautilus_trader.test_kit.providers import TestInstrumentProvider



def parser(data, instrument_id):
"""
Parser function for OKX Tick data, for use with CSV Reader
Should check
1) the data structure of the file
2) “as_dataframe” true or false and
use from_str for string data and from_int for int data and return a QuoteTick object
"""
dt = pd.Timestamp(data['exchTimeMs'], unit='ms', tz='UTC')
yield QuoteTick(
instrument_id=instrument_id,
bid=Price.from_str(str(data['bidPx1'])),
ask=Price.from_str(str(data['askPx1'])),
bid_size=Quantity.from_str(str(data['bidSz1'])),
ask_size=Quantity.from_str(str(data['askSz1'])),
ts_event=dt_to_unix_nanos(dt),
ts_init=dt_to_unix_nanos(dt),
)

input_files = r"D:\下载\BTC-USDT-220107.OK.csv" # "your_path_to_file"
CATALOG_PATH = r"D:/backtest/backtest1/catalog_Sz_01" # "your_path_to_catalog"
# Clear if it already exists, then create fresh
if os.path.exists(CATALOG_PATH):
shutil.rmtree(CATALOG_PATH)
os.mkdir(CATALOG_PATH)
catalog = ParquetDataCatalog(CATALOG_PATH) # Create a new ParquetDataCatalog instance

# # For DEFAULT nautilus-trader with default function btcusdt_future_binance in TestInstrumentProvider
# instrument = TestInstrumentProvider.btcusdt_future_binance()

# For EDITABLE nautilus-trader with customized function btcusdt_future_OKX in TestInstrumentProvider
# Use nautilus test helpers to create a BTC/USDT Crypto instrument for our purposes
maker1 = Decimal(-0.000001)
taker1 = Decimal(0.0000143)
instrument = TestInstrumentProvider.btcusdt_future_OKX(maker=maker1, taker=taker1)

# Add our new instrument to the ParquetDataCatalog and check its existence
write_objects(catalog, [instrument])
catalog.instruments()

# Loading the files (the header can be customized)
process_files(
glob_path=input_files,
reader=CSVReader(
block_parser=lambda x: parser(x, instrument_id=instrument.id),
header=None,
chunked=False,
as_dataframe=True,
),
catalog=catalog,
)

# Also manually write the instrument to the catalog
write_objects(catalog, [instrument])

# Using the data Catalog
start = dt_to_unix_nanos(pd.Timestamp('2022-01-01', tz='UTC'))
end = dt_to_unix_nanos(pd.Timestamp('2022-01-01 23:00:00', tz='UTC'))

catalog.quote_ticks(start=start, end=end)
92 changes: 92 additions & 0 deletions Jerry's tests/OKX_BTCUSDT_Level2_Test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python3
# -------------------------------------------------------------------------------------------------
# This file is a backtest file with imported catalog quote tick data of OKX
# This file is using BacktestNode to run the backtest
# Customized by Jerry based on exmaples\notebooks\external_data_backtest.ipynb
# -------------------------------------------------------------------------------------------------

import time
from decimal import Decimal

import pandas as pd

from nautilus_trader.backtest.node import BacktestNode
from nautilus_trader.core.datetime import dt_to_unix_nanos
from nautilus_trader.config import BacktestRunConfig, BacktestVenueConfig, BacktestDataConfig, BacktestEngineConfig
from nautilus_trader.config import ImportableStrategyConfig
from nautilus_trader.config import LoggingConfig
from nautilus_trader.config.common import ImportableStrategyConfig
from nautilus_trader.model.data.tick import QuoteTick
from nautilus_trader.persistence.catalog import ParquetDataCatalog


if __name__ == "__main__":

# Using the data Catalog
# catalog = ParquetDataCatalog.from_env() # Create a new ParquetDataCatalog instance from the environment
# ran on 08/28/23 Mon 14:50:00 but failed with no [Nautilus_Path]
CATALOG_PATH = "D:/backtest/backtest1/catalog_Sz_01" # "your_path_to_catalog"
catalog = ParquetDataCatalog(CATALOG_PATH) # Create a new ParquetDataCatalog instance
catalog.instruments() # List all instruments in the catalog

start = dt_to_unix_nanos(pd.Timestamp('2022-01-01', tz='UTC'))
end = dt_to_unix_nanos(pd.Timestamp('2022-01-01 23:00:00', tz='UTC'))

catalog.quote_ticks(start=start, end=end)

# Add instruments
instrument = catalog.instruments(as_nautilus=True)[0]

# Add a trading venue (multiple venues possible)
venues_config = [
BacktestVenueConfig(
name="OKX",
oms_type="HEDGING",
account_type="MARGIN",
base_currency="USDT",
starting_balances=["1000000 USDT"],
)
]

# Add data
data_config = [
BacktestDataConfig(
catalog_path=str(catalog.path),
data_cls=QuoteTick,
instrument_id=instrument.id.value,
start_time=pd.Timestamp("2022-01-01").value,
end_time=pd.Timestamp("2022-01-01 00:00:30").value,
)
]

# Configure your strategy
strategies = [
ImportableStrategyConfig(
strategy_path="nautilus_trader.examples.strategies.orderbook_imbalance:OrderBookImbalance",
config_path="nautilus_trader.examples.strategies.orderbook_imbalance:OrderBookImbalanceConfig",
config=dict(
instrument_id=instrument.id.value,
max_trade_size=Decimal(1000),
use_quote_ticks=True,
trigger_min_size=0.5,
trigger_imbalance_ratio=0.4,
book_type="L1_TBBO",
# order_id_tag=instrument.selection_id,
# AttributeError: 'nautilus_trader.model.instruments.crypto_future.Cr' object has no attribute 'selection_id'
),
),
]

config = BacktestRunConfig(
engine=BacktestEngineConfig(
strategies=strategies,
logging=LoggingConfig(log_level="ERROR"),
),
data=data_config,
venues=venues_config,
)

node = BacktestNode(configs=[config]) # successfully ran but no reports

results = node.run()
print(results)
Loading

0 comments on commit 61751da

Please sign in to comment.