#!/bin/bash set -x IFS=$'\0' . helpers.sh ./getNewAccessToken.sh daysOutMin=90 daysOutMax=95 deltaMin=0.35 deltaMax=0.40 marketOpen=$([[ $(./getMarketHours.sh | jq '.option[].isOpen' | grep true | wc -l) -ne 0 ]] && echo true || echo false) if [[ ${marketOpen} == false ]]; then throw "The market is closed, exiting." info 2 fi inputFile="$1" if [[ "" == "$inputFile" ]]; then latestFile="$(ls data/`date +%Y-%m-%d`/*SPY* | sort | tail -n 1)" log "Latest File: _${latestFile}_" debug inputFile=temp/orderInputFile.json bzip2 -dc < "${latestFile}" > "${inputFile}" fi if [[ ! -f "${inputFile}" ]]; then throw "ERROR: Input file _${inputFile}_ does not exist." err 1 fi dateKey=$(jq -r '.callExpDateMap | keys | .[]' "${inputFile}" | sort -r -t ":" +2 | awk -F ":" -e '{theDay=$2; if (theDay < '${daysOutMin}') { print lastDay; exit; } else { lastDay=$0; } }') log "Date-Key: _${dateKey}_" debug daysOut=$(cut -d : -f 2 <<< ${dateKey}) if [[ ${daysOut} -gt ${daysOutMax} ]]; then throw "This option is too far in the future. _${daysOut}_ is bigger than the max days in the future is _${daysOutMax}_. Exiting." info fi #Looking for leg, between the specified deltas # JTR - the "floor" is to only find the prices at the integer strikes, but I changed my mind about that... #jq '.callExpDateMap."'${dateKey}'"[]|map({symbol, delta, strikePrice,bid,ask}) | .[] | select(.delta >= '${deltaMin}' and .delta <= '${deltaMax}') | select( (.strikePrice | floor) == .strikePrice)' "${inputFile}" | tail -n 7 > temp/longLeg.json jq '.callExpDateMap."'${dateKey}'"[]|map({symbol, delta, strikePrice,bid,ask}) | .[] | select(.delta >= '${deltaMin}' and .delta <= '${deltaMax}')' "${inputFile}" | tail -n 7 > temp/longLeg.json numLinesInLeg=$(wc -l temp/longLeg.json | cut -c1) if [[ 7 -ne ${numLinesInLeg} ]]; then throw "No suitable long leg found - exiting." warning 1 fi longStrike=$(jq -r '.strikePrice' < temp/longLeg.json) longBid=$(jq -r '.bid' < temp/longLeg.json) longAsk=$(jq -r '.ask' < temp/longLeg.json) longSymbol=$(jq -r '.symbol' < temp/longLeg.json) log "Long Symbol: _${longSymbol}_ Strike: _${longStrike}_ Bid: _${longBid}_ Ask: _${longAsk}_" info #Check if this order has already been submitted. ./getOrders.sh | grep '\(WORKING\|FILLED\),'${longSymbol} > temp/existingOrders.$$ if [[ $(wc -l < temp/existingOrders.$$) -eq 0 ]];then log "Not Yet traded, continuing" info else throw "Already traded, exiting" info fi priceOffset=0.0 # Get the Middle price... price=$(echo "scale=2; ((${longBid}+${longAsk})/2) + ${priceOffset}" | bc) orderJson=$(jq -c <<-EOM { "orderType": "LIMIT", "session": "NORMAL", "price": ${price}, "duration": "DAY", "orderStrategyType": "SINGLE", "quantity": 1, "orderLegCollection": [ { "instruction": "BUY_TO_OPEN", "quantity": 1, "instrument": { "symbol": "${longSymbol}", "assetType": "OPTION" } } ] } EOM ) log "Order: _${orderJson}_" debug if [[ "${noconfirm}" != "true" ]]; then echo Enter to continue, Ctrl+C to cancel _${noconfirm}_ read fi echo curl -s -X POST \ "https://api.schwabapi.com/trader/v1/accounts/$(./getAccountNumbers.sh Roth)/orders" \ -H "Authorization: Bearer $(