#!/bin/bash

#####################################################
## Command Line FIX Log Parser
##
## Written By: Bob Weaver <code@woodenpickle.com>
##
## Created: 20NOV2009
##
#####################################################

if [ "$#" -eq 0 ]; then
	echo
	echo "Usage: $0 <options>"
	echo
	echo "Options:"
	echo -e "\t-f <log_file>"
	echo -e "\t-s <search_pattern>"
	echo
	exit 1
fi

if [ "$#" -lt 4 ]; then
	echo "Process entire log [y/N]?"
	read full
	case "$full" in
	"y" | "Y" )
		echo "Your call, here we go.." ;;
	* )
		echo "Probably a safe bet.."
		exit 1 ;;
	esac
fi

# Get the log file name & search term from the command line
while [ "$#" -gt 1 ]; do
	case $1 in
	-f ) file="$2"; shift 2 ;;
	-s ) search="$2"; shift 2 ;;
	* ) exit 1 ;;
	esac
done

# Define the fix tags array so things make more sense
# This one is for FIX 4.4 (will add others later)
fixtags=(
[1]="Account\t\t\t"	[6]="AvgPx\t\t\t"		[8]="Version\t\t\t"	[9]="BodyLength\t\t"	[10]="CheckSum\t\t"		[11]="ClOrdID\t\t\t"
[14]="CumQty\t\t\t"	[15]="Currency\t\t"		[17]="ExecID\t\t\t"	[21]="HandlInst\t\t"	[31]="LastPx\t\t\t"		[32]="LastQty\t\t\t"
[34]="MsgSeqNum\t\t"	[35]="MessageType\t\t"		[37]="OrderID\t\t\t"	[38]="OrderQty\t\t"	[39]="OrdStatus\t\t"		[40]="OrdType\t\t\t"
[43]="PossDupFlag\t\t"	[44]="Price\t\t\t"		[49]="SenderCompID\t\t"	[50]="SenderSubID\t\t"	[52]="SendingTime\t\t"		[54]="Side\t\t\t"
[55]="Symbol\t\t\t"	[56]="TargetCompID\t\t"		[57]="TargetSubID\t\t"	[59]="TimeInForce\t\t"	[60]="TransactTime\t\t"		[64]="SettlDate\t\t"
[75]="TradeDate\t\t"	[122]="OrigSendingTime\t\t"	[150]="ExecType\t\t"	[151]="LeavesQty\t\t"	[167]="SecurityType\t\t"	[447]="PartyIDSource\t\t"
[448]="PartyID\t\t\t"	[452]="PartyRole\t\t"		[453]="NoPartyIDs\t\t"	[460]="Product\t\t\t"
)

# These are some functions for the FIX tags that need them
function MessageType() {
	case "$val" in
		"0" ) val='Heartbeat';;
		"1" ) val='Test Request';;
		"2" ) val='Resend Request';;
		"3" ) val='Reject';;
		"4" ) val='Sequence Reset';;
		"5" ) val='Logout' [6]='Indication of Interest';;
		"7" ) val='Advertisement';;
		"8" ) val='Execution Report';;
		"9" ) val='Order Cancel Reject';;
		"A" ) val='Logon';;
		"B" ) val='News';;
		"C" ) val='Email';;
		"D" ) val='New Order - Single';;
		"E" ) val='New Order - List';;
		"F" ) val='Order Cancel Request';;
		"G" ) val='Order Cancel/Replace Request';;
		"H" ) val='Order Status Request';;
		"J" ) val='Allocation Instruction';;
		"K" ) val='List Cancel Request';;
		"L" ) val='List Execute';;
		"M" ) val='List Status Request';;
		"N" ) val='List Status';;
		"P" ) val='Allocation Instruction Ack';;
		"Q" ) val='Dont Know Trade';;
		"R" ) val='Quote Request';;
		"S" ) val='Quote';;
		"T" ) val='Settlement Instructions';;
		"V" ) val='Market Data Request';;
		"W" ) val='doh';;
		"X" ) val='doh';;
		"Y" ) val='doh';;
		* ) val=$val;;
	esac
}

function HandlInst() {
	case "$val" in
		"1" ) val='Automated execution order, private, no Broker intervention';;
		"2" ) val='Automated execution order, public, Broker intervention OK';;
		"3" ) val='Manual order, best execution';;
		* ) val=$val;;
	esac
}

function OrdStatus() {
	case "$val" in
		"0" ) val='New';;
		"1" ) val='Partially filled';;
		"2" ) val='Filled';;
		"3" ) val='Done for day';;
		"4" ) val='Canceled';;
		"6" ) val='Pending Cancel (e.g. result of Order Cancel Request)';;
		"7" ) val='Stopped';;
		"8" ) val='Rejected';;
		"9" ) val='Suspended';;
		"A" ) val='Pending New';;
		"B" ) val='Calculated';;
		"C" ) val='Expired';;
		"D" ) val='Accepted for bidding';;
		"E" ) val='Pending Replace (e.g. result of Order Cancel/Replace Request)';;
		* ) val=$val;;
	esac
}

function OrdType() {
	case "$val" in
		"1" ) val='Market';;
		"2" ) val='Limit';;
		"3" ) val='Stop';;
		"4" ) val='Stop limit';;
		"6" ) val='With or without';;
		"7" ) val='Limit or better (Deprecated)';;
		"8" ) val='Limit with or without';;
		"9" ) val='On basis';;
		"D" ) val='Previously quoted';;
		"E" ) val='Previously indicated';;
		"G" ) val='Forex - Swap';;
		* ) val=$val;;
	esac
}

Side=(
[1]='Buy' [2]='Sell' [3]='Buy minus' [4]='Buy plus' [5]='Sell short' [6]='Sell short exempt'
)

TimeInForce=(
[0]='Day (or session)' [1]='Good Till Cancel (GTC)' [2]='At the Opening (OPG)' [3]='Immediate or Cancel (IOC)' [4]='Fill or Kill (FOK)'
[5]='Good Till Crossing (GTX)' [6]='Good Till Date (GTD)' [7]='At the Close'
)

function ExecType() {
	case "$val" in
		"0" ) val='New';;
		"3" ) val='Done for day';;
		"4" ) val='Canceled';;
		"5" ) val='Replace';;
		"6" ) val='Pending Cancel (e.g. result of Order Cancel Request)';;
		"7" ) val='Stopped';;
		"8" ) val='Rejected';;
		"9" ) val='Suspended';;
		"A" ) val='Pending New';;
		"B" ) val='Calculated';;
		"C" ) val='Expired';;
		* ) val=$val;;
	esac
}

function PartyIDSource() {
	case "$val" in
		"D" ) val='Proprietary/Custom code';;
		* ) val=$val;;
	esac
}

PartyRole=(
[1]='Executing Firm' [3]='Client ID' [35]='Liquidity provider'
)

Product=(
[4]='CURRENCY'
)

# Grab the lines from the log file that match the search term
# or process all lines if no search term was specified..
case "$full" in
	"y" | "Y" ) found=( `cat $file | awk '{print $2}'` ) ;;
	* ) found=( `grep $search $file | awk '{print $2}'` ) ;;
esac
for x in $(seq 0 $((${#found[@]} - 1)))
	do
	# Split the log entry into separate FIX fields and arrayize them
	logarray=( `echo ${found[$x]} | tr '' ' '` )
	echo -en '\E[31m'"\033[1m"
	echo -e "Tag\tTag Name\t\tValue"
	tput sgr0
	# Loop through 'logarray' & split the tags & values then print them :)
	for ((i=0;i<${#logarray[@]};i++)); do
		tag=`echo ${logarray[$i]} | awk -F"=" '{print $1}'`
		val=`echo ${logarray[$i]} | awk -F"=" '{print $2}'`
		if [ "$tag" != "" ]; then
		# Some of these have sub-tags so we catch them here
			case "$tag" in
				"35" ) MessageType;;
				"21" ) HandlInst;;
				"39" ) OrdStatus;;
				"40" ) OrdType;;
				"54" ) val=${Side[$val]=$val} ;;
				"59" ) val=${TimeInForce[$val]=$val} ;;
				"150" ) ExecType;;
				"447" ) val=${PartyIDSource[$val]=$val} ;;
				"452" ) val=${PartyRole[$val]=$val} ;;
				"460" ) val=${Product[$val]=$val} ;;
			esac
		echo -e "$tag\t${fixtags[$tag]=$tag\t\t\t}$val"
		fi
	done
	echo "------------------------------------------------------"
done
