-
Notifications
You must be signed in to change notification settings - Fork 8
/
HistoricalDataDownloader.py
148 lines (127 loc) · 4.74 KB
/
HistoricalDataDownloader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# simple historical data downloader
# this script will download tick-by-tick data from SC and save it as SYMBOL.csv file
import DTCProtocol_pb2 as DTC
from DTCClient import DTCClient, DTCClientAsync
import socket
import json
import threading
from datetime import datetime
from termcolor import colored
import argparse
import colorama
import numpy as np
import asyncio as aio
import pandas as pd
from Raw2TickData import ConvertRaw2Tick
import aiofiles
'''
raw json format for incoming traffic:
{
"Type": 803,
"RequestID": 10,
"StartDateTime": "2019-10-03 10:58:23",
"OpenPrice": 0,
"HighPrice": 2865,
"LowPrice": 2859.5,
"LastPrice": 2865,
"Volume": 1,
"NumTrades": 1,
"BidVolume": 0,
"AskVolume": 1,
"IsFinalRecord": 0
}
'''
async def DownloadAsync(symbol,
exchange='CME',
userpass='userpass',
address='192.168.122.142',
port=11198,
sDateTime=0,
eDateTime=0,
recordInterval=DTC.INTERVAL_TICK):
async with aiofiles.open(userpass, 'r') as f:
username = (await f.readline()).strip('\n')
password = (await f.readline()).strip('\n')
client = DTCClientAsync()
await client.connect(address, port)
await client.logon(username, password)
# historical data request for symbol
await client.send_json_request({
'Type': DTC.HISTORICAL_PRICE_DATA_REQUEST,
'RequestID': 10,
'Symbol': symbol,
'Exchange': exchange,
'RecordInterval': recordInterval,
'StartDateTime': sDateTime,
'EndDateTime': eDateTime,
'MaxDaysToReturn': 0,
'UseZLibCompression': 0
})
data = []
done_msgs = 1
async for message in client.messages():
if message['Type'] != 803:
print(colored("Unprocess MSG: " + json.dumps(message), 'red'))
continue
if (message['IsFinalRecord'] == 1):
await client.close()
break
data.append(np.array(list(message.values())))
if done_msgs % 1000000 == 0:
print("Has processed %d messages to up %s" % (
done_msgs,
str(datetime.fromtimestamp(message['StartDateTime'])) if 'StartDateTime' in message.keys() else "unknown-datetime"))
done_msgs += 1
columns = [
"Type",
"RequestID",
"StartDateTime",
"OpenPrice",
"HighPrice",
"LowPrice",
"LastPrice",
"Volume",
"NumTrades",
"BidVolume",
"AskVolume",
"IsFinalRecord"
]
return pd.DataFrame(np.array(data), columns=columns) if len(data) > 0 else pd.DataFrame()
async def Main():
# parse arguments
parser = argparse.ArgumentParser()
parser.add_argument('--userpass', "-i", default="userpass", help="Username and Password file.")
parser.add_argument('--address', "-a", default="192.168.122.107", help="IP Address of Sierra Chart instance")
parser.add_argument('--port', "-p", type=int, default=11198, help="Port number of Sierra Chart instance")
parser.add_argument('--symbol', "-s", required=True, help="Symbol Name")
parser.add_argument('--exchange', "-e", default="CME", help="Exchange Name")
parser.add_argument('--sDateTime', default="0", help="Start DateTime")
parser.add_argument('--eDateTime', default="0", help="End DateTime")
parser.add_argument('--output', "-o", default=None, help="Output file name")
parser.add_argument('--raw', default=False, action='store_true', help="output raw file")
parser.add_argument('--record_interval', default='INTERVAL_TICK', help="Record interval")
args = parser.parse_args()
ADDR = args.address
PORT = args.port
SYMBOL = args.symbol
EXCHANGE = args.exchange
sDateTime = int(args.sDateTime)
eDateTime = int(args.eDateTime)
OUTPUT = "%s.csv" % symbol if args.output == None else args.output
try:
interval = eval('DTC.%s' % args.record_interval)
except:
print("Unknown interval: %s" % args.record_interval)
return
data = await DownloadAsync(SYMBOL, EXCHANGE, args.userpass, ADDR, PORT, sDateTime, eDateTime, interval)
if args.raw:
print("Download Finished. Saving to %s" % OUTPUT)
data.drop(['Type', 'RequestID', 'IsFinalRecord'], axis=1).to_csv(OUTPUT, index=False)
else:
print("Download Finished. Running convertion...")
data = ConvertRaw2Tick(data)
print("Convertion Finished. Saving to %s ..." % OUTPUT)
data.to_csv(OUTPUT, index=False)
if __name__ == "__main__":
print("Downloading historical data has been banned from June 3rd, 2021")
print('However, you can instead directly read SCID file.')