commit
1d626e3675
3 changed files with 264 additions and 0 deletions
@ -0,0 +1,115 @@
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
import sys |
||||
import argparse |
||||
import zmq |
||||
import io |
||||
import json |
||||
import csv |
||||
import datetime |
||||
import struct |
||||
|
||||
|
||||
def sec_from_period(period): |
||||
if period == "M1": |
||||
return 60 |
||||
elif period == "M5": |
||||
return 60 * 5 |
||||
elif period == "M15": |
||||
return 60 * 15 |
||||
elif period == "M30": |
||||
return 60 * 30 |
||||
elif period == "H1": |
||||
return 60 * 60 |
||||
elif period == "D": |
||||
return 86400 |
||||
|
||||
def main(): |
||||
parser = argparse.ArgumentParser(description='Finam quote downloader') |
||||
parser.add_argument('-i', '--input-file', action='store', dest='input_file', help='Input filename', required=True) |
||||
parser.add_argument('-p', '--timeframe', action='store', dest='timeframe', help='Data timeframe', required=True) |
||||
parser.add_argument('-o', '--hap', action='store', dest='hap', help='HAP endpoint', required=True) |
||||
parser.add_argument('-y', '--hap-symbol', action='store', dest='hap_symbol', help='HAP symbol', required=True) |
||||
parser.add_argument('-d', '--time-delta', action='store', dest='time_delta', help='Time delta (hours)') |
||||
parser.add_argument('-f', '--force-from', action='store', dest='force_from', help='Force period start') |
||||
parser.add_argument('-t', '--force-to', action='store', dest='force_to', help='Force period end') |
||||
|
||||
|
||||
args = parser.parse_args() |
||||
|
||||
period = args.timeframe |
||||
|
||||
out_symbol = args.hap_symbol |
||||
|
||||
ctx = zmq.Context.instance() |
||||
s = ctx.socket(zmq.REQ) |
||||
s.connect(args.hap) |
||||
serialized_bars = io.BytesIO() |
||||
min_dt = None |
||||
max_dt = None |
||||
time_delta = datetime.timedelta(hours=0) |
||||
if args.time_delta is not None: |
||||
time_delta = datetime.timedelta(hours=int(args.time_delta)) |
||||
print('Applying delta:', time_delta) |
||||
line_count = 0 |
||||
with open(args.input_file, 'r') as f: |
||||
reader = csv.reader(f, delimiter=';') |
||||
next(reader) |
||||
for line in reader: |
||||
line_count += 1 |
||||
date = line[2] |
||||
time = line[3] |
||||
open_ = line[4] |
||||
high = line[5] |
||||
low = line[6] |
||||
close = line[7] |
||||
volume = line[8] |
||||
|
||||
year = int(date[0:4]) |
||||
month = int(date[4:6]) |
||||
day = int(date[6:8]) |
||||
hour = int(time[0:2]) |
||||
minute = int(time[2:4]) |
||||
second = int(time[4:6]) |
||||
|
||||
dt = datetime.datetime(year, month, day, hour, minute, second, 0, datetime.timezone.utc) - time_delta |
||||
|
||||
serialized_bars.write(struct.pack("<qddddQ", int(dt.timestamp()), float(open_), float(high), float(low), float(close), int(volume))) |
||||
|
||||
if min_dt is None: |
||||
min_dt = dt |
||||
else: |
||||
if dt < min_dt: |
||||
min_dt = dt |
||||
|
||||
if max_dt is None: |
||||
max_dt = dt |
||||
else: |
||||
if dt > max_dt: |
||||
max_dt = dt |
||||
|
||||
if args.force_from is not None: |
||||
min_dt = datetime.datetime.strptime(args.force_from, "%Y%m%d") |
||||
|
||||
if args.force_to is not None: |
||||
max_dt = datetime.datetime.strptime(args.force_to, "%Y%m%d") |
||||
|
||||
rq = { |
||||
"ticker" : out_symbol, |
||||
"start_time" : min_dt.strftime("%Y-%m-%dT%H:%M:%S"), |
||||
"end_time" : max_dt.strftime("%Y-%m-%dT%H:%M:%S"), |
||||
"timeframe_sec" : sec_from_period(period) |
||||
} |
||||
|
||||
print("Read {} lines".format(line_count)) |
||||
raw_data = serialized_bars.getvalue() |
||||
print("Sending {} bytes".format(len(raw_data))) |
||||
|
||||
s.send_multipart([bytes(json.dumps(rq), "utf-8"), raw_data]) |
||||
parts = s.recv_multipart() |
||||
print("Response:", parts) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
||||
|
||||
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
import sys |
||||
import argparse |
||||
import zmq |
||||
import io |
||||
import json |
||||
import csv |
||||
import datetime |
||||
import struct |
||||
|
||||
|
||||
def sec_from_period(period): |
||||
if period == "1min": |
||||
return 60 |
||||
elif period == "5min": |
||||
return 60 * 5 |
||||
elif period == "15min": |
||||
return 60 * 15 |
||||
elif period == "30min": |
||||
return 60 * 30 |
||||
elif period == "hour": |
||||
return 60 * 60 |
||||
elif period == "daily": |
||||
return 86400 |
||||
|
||||
def main(): |
||||
parser = argparse.ArgumentParser(description='Finam quote downloader') |
||||
parser.add_argument('-o', '--hap', action='store', dest='hap', help='HAP endpoint') |
||||
parser.add_argument('-y', '--hap-symbol', action='store', dest='hap_symbol', help='HAP symbol') |
||||
|
||||
period = "15min" |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
out_symbol = args.hap_symbol |
||||
|
||||
ctx = zmq.Context.instance() |
||||
s = ctx.socket(zmq.REQ) |
||||
s.connect(args.hap) |
||||
serialized_bars = io.BytesIO() |
||||
min_dt = None |
||||
max_dt = None |
||||
for i in range(0, 10): |
||||
date = "2020418" |
||||
time = "10{:02d}00".format(i) |
||||
open_ = 1 |
||||
high = 2 |
||||
low = 3 |
||||
close = 4 |
||||
volume = 1200 |
||||
dt = datetime.datetime.strptime(date + "_" + time, "%Y%m%d_%H%M%S") - datetime.timedelta(hours=3) # Convert to UTC |
||||
|
||||
serialized_bars.write(struct.pack("<qddddQ", int(dt.timestamp()), float(open_), float(high), float(low), float(close), int(volume))) |
||||
|
||||
if min_dt is None: |
||||
min_dt = dt |
||||
else: |
||||
if dt < min_dt: |
||||
min_dt = dt |
||||
|
||||
if max_dt is None: |
||||
max_dt = dt |
||||
else: |
||||
if dt > max_dt: |
||||
max_dt = dt |
||||
|
||||
rq = { |
||||
"ticker" : out_symbol, |
||||
"start_time" : min_dt.strftime("%Y-%m-%dT%H:%M:%S"), |
||||
"end_time" : max_dt.strftime("%Y-%m-%dT%H:%M:%S"), |
||||
"timeframe_sec" : sec_from_period(period) |
||||
} |
||||
|
||||
s.send_multipart([bytes(json.dumps(rq), "utf-8"), serialized_bars.getvalue()]) |
||||
parts = s.recv_multipart() |
||||
print(parts) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
||||
|
||||
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
import sys |
||||
import argparse |
||||
import zmq |
||||
import io |
||||
import json |
||||
import csv |
||||
import datetime |
||||
import struct |
||||
|
||||
|
||||
def main(): |
||||
parser = argparse.ArgumentParser(description='QHP client') |
||||
parser.add_argument('-o', '--output-file', action='store', dest='output_file', help='Output filename', required=True) |
||||
parser.add_argument('-p', '--timeframe', action='store', dest='timeframe', help='Data timeframe', required=True) |
||||
parser.add_argument('-q', '--qhp', action='store', dest='qhp', help='QHP endpoint', required=True) |
||||
parser.add_argument('-y', '--symbol', action='store', dest='symbol', help='Symbol to download', required=True) |
||||
parser.add_argument('-f', '--from', action='store', dest='from_', help='Starting date', required=True) |
||||
parser.add_argument('-t', '--to', action='store', dest='to', help='Ending date', required=True) |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
period = args.timeframe |
||||
symbol = args.symbol |
||||
filename = args.output_file |
||||
|
||||
ctx = zmq.Context.instance() |
||||
s = ctx.socket(zmq.REQ) |
||||
s.connect(args.qhp) |
||||
|
||||
start_time = datetime.datetime.strptime(args.from_, "%Y%m%d") |
||||
end_time = datetime.datetime.strptime(args.to, "%Y%m%d") |
||||
|
||||
rq = { |
||||
"ticker" : symbol, |
||||
"from" : start_time.strftime("%Y-%m-%dT%H:%M:%S"), |
||||
"to" : end_time.strftime("%Y-%m-%dT%H:%M:%S"), |
||||
"timeframe" : period |
||||
} |
||||
|
||||
s.send_multipart([bytes(json.dumps(rq), "utf-8")]) |
||||
parts = s.recv_multipart() |
||||
|
||||
line_count = 0 |
||||
with open(args.output_file, 'w') as f: |
||||
writer = csv.writer(f) |
||||
writer.writerow(['<TICKER>', '<PER>', '<DATE>', '<TIME>', '<OPEN>', '<HIGH>', '<LOW>', '<CLOSE>', '<VOLUME>']) |
||||
for line in struct.iter_unpack("<qddddQ", parts[0]): |
||||
line_count += 1 |
||||
|
||||
timestamp = int(line[0]) |
||||
open_ = float(line[1]) |
||||
high = float(line[2]) |
||||
low = float(line[3]) |
||||
close = float(line[4]) |
||||
volume = int(line[5]) |
||||
dt = datetime.datetime.utcfromtimestamp(timestamp) |
||||
|
||||
writer.writerow([symbol, period, dt.strftime('%Y%m%d'), dt.strftime('%H%M%S'), str(open_), str(high), str(low), str(close), str(volume)]) |
||||
|
||||
|
||||
print("Written {} lines".format(line_count)) |
||||
|
||||
if __name__ == '__main__': |
||||
main() |
||||
|
||||
Loading…
Reference in new issue