#!/usr/bin/env python # ------------------------------------------------------------------------------ # # Disclaimer: # # DTN grants you an nonexclusive copyright license to use this code and you can # use it to prepare similar functions tailored to your own needs. # # The code is provided for illustrative purposes only and has not been tested under # all conditions. For that reason, DTN provides this code to you "AS IS" without # any warranties of any kind. # # ------------------------------------------------------------------------------ # # Retrieve a daily history report and present result as a SVG chart. # # Imports import PXWeb # ------------------------------------------------------------------------------ # PXWeb access credentials USER = 'YOUR_USER' PSWD = 'YOUR_PASSWORD' # Search pattern to send to PXWeb PATTERN = '@C`## 20' # Max number of history entries to return for each symbol LIMIT = 500 # GetDailyHistory request string and CSV fields for response FIELDS = ( 'Date', 'Open', 'Close', 'High', 'Low', 'OI', 'Volume' ) # Name of output file OUT_FILE = 'result.svg' # ------------------------------------------------------------------------------ # Chart size WIDTH = 900 HEIGHT = 400 # Coordinates at origin X0 = 30 Y0 = 60 # Grid count and title on X axis GRID_COUNT = 10 X_TITLE = 'DAYS BEFORE {}' # SVG objects SVG_LINE = '\n' SVG_POLYLINE = '{0}\n' SVG_RECT = '\n' SVG_TEXT = '{}\n' SVG_TEXT_MAP = '{3}\n' # Start of SVG file SVG_HEAD = ''' ''' # ------------------------------------------------------------------------------ # Open output file and write header ofile = open( OUT_FILE, 'w' ) ofile.write( SVG_HEAD[ 1: ] ) # Get PXWeb client object pxWeb = PXWeb.PXServiceWebClient( USER, PSWD ) # Send GetDailyHistory request for current search pattern and get an XML tree xml = pxWeb.getDailyHistory( symbol=PATTERN, limit=LIMIT ) # Build a PXDailyHistoryData object from XML tree h = PXWeb.PXDailyHistoryData( xml ) # Calculate constants to adjust chart to fit daysFact = WIDTH / float( h.daysMax - h.daysMin ) priceFact = HEIGHT / float( h.priceMax - h.priceMin ) # Write rectangle and titles ofile.write( SVG_RECT.format( X0, Y0, WIDTH, HEIGHT ) ) title = X_TITLE.format(h.today.strftime( '%Y-%m-%d' )) ofile.write( SVG_TEXT.format( X0 + ( WIDTH - 6 * len( title ) ) / 2, Y0 + HEIGHT + 35, 12, title ) ) ofile.write( SVG_TEXT.format( X0, Y0 - 35, 16, 'GetDailyHistory: ' + PATTERN ) ) # Write vertical grid for x in range( X0, X0 + WIDTH, WIDTH // GRID_COUNT ): days = ( WIDTH - x + X0 ) / daysFact + h.daysMin ofile.write( SVG_TEXT.format( x - 5, Y0 + HEIGHT + 16, 10, f'days' ) ) ofile.write( SVG_LINE.format( x, Y0, x, Y0 + HEIGHT ) ) # Write horizontal grid for y in range( Y0, Y0 + HEIGHT + 1, HEIGHT // GRID_COUNT ): price = ( HEIGHT - y + Y0 ) / priceFact + h.priceMin ofile.write( SVG_TEXT.format( X0 + WIDTH + 5, y, 10, f'${price:.2f}' ) ) ofile.write( SVG_LINE.format( X0, y, X0 + WIDTH, y ) ) # Build a polyline for each symbol and write for symbol in h.symbols: # String of coordinates coords = '' # Populate string of coordinates for days, price in h.data[ symbol ]: x = WIDTH - int( ( days - h.daysMin ) * daysFact ) + X0 y = HEIGHT - int( ( price - h.priceMin ) * priceFact ) + Y0 coords += f'{x},{y} ' # Write final polyline ofile.write( SVG_POLYLINE.format( symbol, coords ) ) # Starting coordinates for symbol list x = 0 # Write symbol list for symbol in h.symbols: ofile.write( SVG_TEXT_MAP.format( x + X0, Y0 - 10, 10, symbol ) ) x = x + WIDTH / 20 # Write tail ofile.write( '' ) ofile.close() # Notify print(f'Result ready in file "{OUT_FILE}".')