- Separate getting option chains from recording
- Add checking for market open - Remove SPX from recording - Hopefully precent the refresh token from being overwritten sometimes
This commit is contained in:
@@ -86,9 +86,6 @@
|
||||
{
|
||||
"Symbol": "SLV"
|
||||
},
|
||||
{
|
||||
"Symbol": "$SPX"
|
||||
},
|
||||
{
|
||||
"Symbol": "SPY"
|
||||
},
|
||||
|
||||
@@ -89,8 +89,11 @@ EOM
|
||||
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Order: _${orderJson}_"
|
||||
|
||||
echo Enter to continue, Ctrl+C to cancel
|
||||
read
|
||||
if [[ "${noconfirm}" != "true" ]]; then
|
||||
echo Enter to continue, Ctrl+C to cancel _${noconfirm}_
|
||||
read
|
||||
fi
|
||||
|
||||
./getNewAccessToken.sh
|
||||
|
||||
curl -s -X POST \
|
||||
|
||||
@@ -4,12 +4,19 @@ set -e
|
||||
IFS=$'\0'
|
||||
myPID=$$
|
||||
|
||||
|
||||
marketOpen=$([[ $(./getMarketHours.sh | jq '.option[].isOpen' | grep true | wc -l) -ne 0 ]] && echo true || echo false)
|
||||
if [[ ${marketOpen} == false ]]; then
|
||||
errMsg="The market is closed, exiting."
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${errMsg}
|
||||
>&2 echo "${errMsg}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
inputFile="$1"
|
||||
if [[ "" == "$inputFile" ]]; then
|
||||
latestFile="$(ls data/`date +%Y-%m-%d`/*\$SPX* | sort | tail -n 1)"
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Latest File: _${latestFile}_"
|
||||
inputFile=temp/orderInputFile.json
|
||||
bzip2 -dc < "${latestFile}" > "${inputFile}"
|
||||
inputFile=temp/orderInputFile.$$.json
|
||||
./getOptionChain.sh '$SPX' fromDate $(date "+%Y-%m-%d" -d "+40 days") toDate $(date "+%Y-%m-%d" -d "+46 days") > "${inputFile}"
|
||||
fi
|
||||
if [[ ! -f "${inputFile}" ]]; then
|
||||
errMsg="ERROR: Input file _${inputFile}_ does not exist."
|
||||
@@ -20,6 +27,7 @@ fi
|
||||
|
||||
dateKey=$(jq -r '.putExpDateMap | keys | .[]' "${inputFile}" | head -n 1)
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Date-Key: _${dateKey}_"
|
||||
echo "Date-Key: _${dateKey}_"
|
||||
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) |.[] | select(.delta >= -0.30 and .delta <= -0.25) ' "${inputFile}" | tail -n 8 > temp/shortLeg.json
|
||||
shortStrike=$(jq -r '.strikePrice' < temp/shortLeg.json)
|
||||
@@ -31,7 +39,7 @@ msg="Short Symbol: _${shortSymbol}_ Strike: _${shortStrike}_ Bid: _${shortBid}_
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) | .[] | select(.optionRoot == "'${shortOptionRoot}'" and .strikePrice >= '${shortStrike}'-50 and .strikePrice < '${shortStrike}')' temp/orderInputFile.json | head -n 8 > temp/longLeg.json
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) | .[] | select(.optionRoot == "'${shortOptionRoot}'" and .strikePrice >= '${shortStrike}'-50 and .strikePrice < '${shortStrike}')' "${inputFile}" | head -n 8 > temp/longLeg.json
|
||||
longStrike=$(jq -r '.strikePrice' < temp/longLeg.json)
|
||||
longBid=$(jq -r '.bid' < temp/longLeg.json)
|
||||
longAsk=$(jq -r '.ask' < temp/longLeg.json)
|
||||
@@ -89,8 +97,11 @@ EOM
|
||||
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Order: _${orderJson}_"
|
||||
|
||||
#echo Enter to continue, Ctrl+C to cancel
|
||||
#read
|
||||
if [[ "${noconfirm}" != "true" ]]; then
|
||||
echo Enter to continue, Ctrl+C to cancel _${noconfirm}_
|
||||
read
|
||||
fi
|
||||
|
||||
./getNewAccessToken.sh
|
||||
|
||||
curl -s -X POST \
|
||||
|
||||
205
autoTradeSPX_IB_0DTE_25pctProfitTaker.sh
Executable file
205
autoTradeSPX_IB_0DTE_25pctProfitTaker.sh
Executable file
@@ -0,0 +1,205 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
set -e
|
||||
IFS=$'\0'
|
||||
myPID=$$
|
||||
|
||||
marketOpen=$([[ $(./getMarketHours.sh | jq '.option[].isOpen' | grep true | wc -l) -ne 0 ]] && echo true || echo false)
|
||||
if [[ ${marketOpen} == false ]]; then
|
||||
errMsg="The market is closed, exiting."
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${errMsg}
|
||||
>&2 echo "${errMsg}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
inputFile="$1"
|
||||
if [[ "" == "$inputFile" ]]; then
|
||||
inputFile=temp/orderInputFile.$$.json
|
||||
./getOptionChain.sh '$SPX' fromDate $(date "+%Y-%m-%d") toDate $(date "+%Y-%m-%d") > "${inputFile}"
|
||||
fi
|
||||
if [[ ! -f "${inputFile}" ]]; then
|
||||
errMsg="ERROR: Input file _${inputFile}_ does not exist."
|
||||
systemd-cat -t "`basename $0` $1" -p err <<< ${errMsg}
|
||||
>&2 echo "${errMsg}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dateKey=$(jq -r '.putExpDateMap | keys | .[]' "${inputFile}" | head -n 1)
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Date-Key: _${dateKey}_"
|
||||
echo "Date-Key: _${dateKey}_"
|
||||
|
||||
underlyingPrice=$(jq ".underlyingPrice" "${inputFile}")
|
||||
atmStrike=$(jq -r '.callExpDateMap[]|keys[]' "${inputFile}" | sort -n | awk -e '{lastStrike=$1; if ($1 > '${underlyingPrice}') {print $1; exit } }')
|
||||
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) |.[] | select(.strikePrice=='${atmStrike}') ' "${inputFile}" | tail -n 8 > temp/shortLegP.json
|
||||
shortStrikeP=$(jq -r '.strikePrice' < temp/shortLegP.json)
|
||||
shortBidP=$(jq -r '.bid' < temp/shortLegP.json)
|
||||
shortAskP=$(jq -r '.ask' < temp/shortLegP.json)
|
||||
shortSymbolP=$(jq -r '.symbol' < temp/shortLegP.json)
|
||||
optionRoot=$(jq -r '.optionRoot' < temp/shortLegP.json)
|
||||
msg="Short Put Symbol: _${shortSymbolP}_ Strike: _${shortStrikeP}_ Bid: _${shortBidP}_ Ask: _${shortAskP}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
jq '.callExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) |.[] | select(.strikePrice=='${atmStrike}') ' "${inputFile}" | tail -n 8 > temp/shortLegC.json
|
||||
shortStrikeC=$(jq -r '.strikePrice' < temp/shortLegC.json)
|
||||
shortBidC=$(jq -r '.bid' < temp/shortLegC.json)
|
||||
shortAskC=$(jq -r '.ask' < temp/shortLegC.json)
|
||||
shortSymbolC=$(jq -r '.symbol' < temp/shortLegC.json)
|
||||
msg="Short Call Symbol: _${shortSymbolC}_ Strike: _${shortStrikeC}_ Bid: _${shortBidC}_ Ask: _${shortAskC}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) | .[] | select(.optionRoot == "'${optionRoot}'" and .strikePrice >= '${shortStrikeP}'-10 and .strikePrice < '${shortStrikeP}')' "${inputFile}" | head -n 8 > temp/longLegP.json
|
||||
longStrikeP=$(jq -r '.strikePrice' < temp/longLegP.json)
|
||||
longBidP=$(jq -r '.bid' < temp/longLegP.json)
|
||||
longAskP=$(jq -r '.ask' < temp/longLegP.json)
|
||||
longSymbolP=$(jq -r '.symbol' < temp/longLegP.json)
|
||||
msg="Long Symbol: _${longSymbolP}_ Strike: _${longStrikeP}_ Bid: _${longBidP}_ Ask: _${longAskP}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
#Check if this order has already been submitted.
|
||||
jq '.callExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) | .[] | select(.optionRoot == "'${optionRoot}'" and .strikePrice >= '${shortStrikeC}'+10 and .strikePrice > '${shortStrikeP}')' "${inputFile}" | head -n 8 > temp/longLegC.json
|
||||
longStrikeC=$(jq -r '.strikePrice' < temp/longLegC.json)
|
||||
longBidC=$(jq -r '.bid' < temp/longLegC.json)
|
||||
longAskC=$(jq -r '.ask' < temp/longLegC.json)
|
||||
longSymbolC=$(jq -r '.symbol' < temp/longLegC.json)
|
||||
msg="Long Symbol: _${longSymbolC}_ Strike: _${longStrikeC}_ Bid: _${longBidC}_ Ask: _${longAskC}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
#Check if this order has already been submitted.
|
||||
./getOrders.sh | (grep '\(WORKING\|FILLED\),'${longSymbolC:0:12} || true) > temp/existingOrders.${myPID}
|
||||
|
||||
if [[ $(wc -l < temp/existingOrders.${myPID}) -eq 0 ]];then
|
||||
msg="Not Yet traded, continuing"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo ${msg}
|
||||
else
|
||||
msg="Already traded, exiting"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo ${msg}
|
||||
# exit 0
|
||||
fi
|
||||
|
||||
priceOffset=1.1 # try to get $10 more in premium...
|
||||
profitTargetPct=25 # cash in at 25% gains
|
||||
|
||||
#For SPX we need to submit orders at the closest 5cent price
|
||||
#To find the closest 5cent price the mathematical solution is
|
||||
# 1) Multiply by 20
|
||||
# 2) Round to the Coloses full number
|
||||
# 3) Divide by 20
|
||||
priceOpen=$(echo "scale=2; exact=((${shortBidC}+${shortAskC})/2) + ((${shortBidP}+${shortAskP})/2) - ((${longBidC}+${longAskC})/2) - ((${longBidP}+${longAskP})/2) + ${priceOffset}; scale=0; round5=exact*20/1; scale=2; round5/20" | bc)
|
||||
priceClose=$(echo "scale=2; exact=${priceOpen} * (100-${profitTargetPct}) /100; scale=0; round5=exact*20/1; scale=2; round5/20" | bc) # Profit target 25%
|
||||
|
||||
orderJson=$(jq -c <<-EOM
|
||||
{
|
||||
"orderType": "NET_CREDIT",
|
||||
"session": "NORMAL",
|
||||
"price": ${priceOpen},
|
||||
"duration": "DAY",
|
||||
"orderStrategyType": "SINGLE",
|
||||
"quantity": 1,
|
||||
"orderLegCollection": [
|
||||
{
|
||||
"instruction": "SELL_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${shortSymbolP}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "SELL_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${shortSymbolC}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "BUY_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${longSymbolP}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "BUY_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${longSymbolC}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
}
|
||||
],
|
||||
"orderStrategyType": "TRIGGER",
|
||||
"childOrderStrategies": [
|
||||
{
|
||||
"orderType": "NET_DEBIT",
|
||||
"session": "NORMAL",
|
||||
"price": ${priceClose},
|
||||
"duration": "DAY",
|
||||
"orderStrategyType": "SINGLE",
|
||||
"quantity": 1,
|
||||
"orderLegCollection": [
|
||||
{
|
||||
"instruction": "BUY_TO_CLOSE",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${shortSymbolP}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "BUY_TO_CLOSE",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${shortSymbolC}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "SELL_TO_CLOSE",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${longSymbolP}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "SELL_TO_CLOSE",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${longSymbolC}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOM
|
||||
)
|
||||
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Order: _${orderJson}_"
|
||||
|
||||
if [[ "${noconfirm}" != "true" ]]; then
|
||||
echo ${orderJSON} | jq
|
||||
echo Enter to continue, Ctrl+C to cancel _${noconfirm}_
|
||||
read
|
||||
fi
|
||||
|
||||
./getNewAccessToken.sh
|
||||
|
||||
|
||||
curl -s -X POST \
|
||||
'https://api.schwabapi.com/trader/v1/accounts/C819AC820A502BA92E55D775B22BDF0E1BC91D86C62685714347734A5827CCB3/orders' \
|
||||
-H "Authorization: Bearer $(<access_token.dat)" \
|
||||
-H 'accept: */*' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "${orderJson}"
|
||||
|
||||
160
autoTradeSPX_IB_1DTE.sh
Executable file
160
autoTradeSPX_IB_1DTE.sh
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
set -e
|
||||
IFS=$'\0'
|
||||
myPID=$$
|
||||
|
||||
marketOpen=$([[ $(./getMarketHours.sh | jq '.option[].isOpen' | grep true | wc -l) -ne 0 ]] && echo true || echo false)
|
||||
if [[ ${marketOpen} == false ]]; then
|
||||
errMsg="The market is closed, exiting."
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${errMsg}
|
||||
>&2 echo "${errMsg}"
|
||||
# exit 2
|
||||
fi
|
||||
|
||||
inputFile="$1"
|
||||
if [[ "" == "$inputFile" ]]; then
|
||||
inputFile=temp/orderInputFile.$$.json
|
||||
./getOptionChain.sh '$SPX' fromDate $(date "+%Y-%m-%d" -d "+1 days") toDate $(date "+%Y-%m-%d" -d "+1 days") > "${inputFile}"
|
||||
fi
|
||||
if [[ ! -f "${inputFile}" ]]; then
|
||||
errMsg="ERROR: Input file _${inputFile}_ does not exist."
|
||||
systemd-cat -t "`basename $0` $1" -p err <<< ${errMsg}
|
||||
>&2 echo "${errMsg}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dateKey=$(jq -r '.putExpDateMap | keys | .[]' "${inputFile}" | head -n 1)
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Date-Key: _${dateKey}_"
|
||||
echo "Date-Key: _${dateKey}_"
|
||||
|
||||
underlyingPrice=$(jq ".underlyingPrice" "${inputFile}")
|
||||
atmStrike=$(jq -r '.callExpDateMap[]|keys[]' "${inputFile}" | sort -n | awk -e '{lastStrike=$1; if ($1 > '${underlyingPrice}') {print $1; exit } }')
|
||||
|
||||
|
||||
optionRoot=SPXW #I only want the PM expiry (SPX without the W is AM expiry)
|
||||
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) |.[] | select(.optionRoot == "'${optionRoot}'" and .strikePrice=='${atmStrike}') ' "${inputFile}" | tail -n 8 > temp/shortLegP.json
|
||||
shortStrikeP=$(jq -r '.strikePrice' < temp/shortLegP.json)
|
||||
shortBidP=$(jq -r '.bid' < temp/shortLegP.json)
|
||||
shortAskP=$(jq -r '.ask' < temp/shortLegP.json)
|
||||
shortSymbolP=$(jq -r '.symbol' < temp/shortLegP.json)
|
||||
msg="Short Put Symbol: _${shortSymbolP}_ Strike: _${shortStrikeP}_ Bid: _${shortBidP}_ Ask: _${shortAskP}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
jq '.callExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) |.[] | select(.optionRoot == "'${optionRoot}'" and .strikePrice=='${atmStrike}') ' "${inputFile}" | tail -n 8 > temp/shortLegC.json
|
||||
shortStrikeC=$(jq -r '.strikePrice' < temp/shortLegC.json)
|
||||
shortBidC=$(jq -r '.bid' < temp/shortLegC.json)
|
||||
shortAskC=$(jq -r '.ask' < temp/shortLegC.json)
|
||||
shortSymbolC=$(jq -r '.symbol' < temp/shortLegC.json)
|
||||
msg="Short Call Symbol: _${shortSymbolC}_ Strike: _${shortStrikeC}_ Bid: _${shortBidC}_ Ask: _${shortAskC}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
jq '.putExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) | .[] | select(.optionRoot == "'${optionRoot}'" and .strikePrice >= '${shortStrikeP}'-5 and .strikePrice < '${shortStrikeP}')' "${inputFile}" | head -n 8 > temp/longLegP.json
|
||||
longStrikeP=$(jq -r '.strikePrice' < temp/longLegP.json)
|
||||
longBidP=$(jq -r '.bid' < temp/longLegP.json)
|
||||
longAskP=$(jq -r '.ask' < temp/longLegP.json)
|
||||
longSymbolP=$(jq -r '.symbol' < temp/longLegP.json)
|
||||
msg="Long Symbol: _${longSymbolP}_ Strike: _${longStrikeP}_ Bid: _${longBidP}_ Ask: _${longAskP}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
#Check if this order has already been submitted.
|
||||
jq '.callExpDateMap."'${dateKey}'"[]|map({symbol,delta,strikePrice,bid,ask,optionRoot}) | .[] | select(.optionRoot == "'${optionRoot}'" and .strikePrice >= '${shortStrikeC}'+5 and .strikePrice > '${shortStrikeP}')' "${inputFile}" | head -n 8 > temp/longLegC.json
|
||||
longStrikeC=$(jq -r '.strikePrice' < temp/longLegC.json)
|
||||
longBidC=$(jq -r '.bid' < temp/longLegC.json)
|
||||
longAskC=$(jq -r '.ask' < temp/longLegC.json)
|
||||
longSymbolC=$(jq -r '.symbol' < temp/longLegC.json)
|
||||
msg="Long Symbol: _${longSymbolC}_ Strike: _${longStrikeC}_ Bid: _${longBidC}_ Ask: _${longAskC}_"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo "${msg}"
|
||||
|
||||
#Check if this order has already been submitted.
|
||||
./getOrders.sh | (grep '\(WORKING\|FILLED\),'${longSymbolC:0:12} || true) > temp/existingOrders.${myPID}
|
||||
|
||||
if [[ $(wc -l < temp/existingOrders.${myPID}) -eq 0 ]];then
|
||||
msg="Not Yet traded, continuing"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo ${msg}
|
||||
else
|
||||
msg="Already traded, exiting"
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${msg}
|
||||
echo ${msg}
|
||||
# exit 0
|
||||
fi
|
||||
|
||||
priceOffset=0.00 # try to get a little better price
|
||||
|
||||
#For SPX we need to submit orders at the closest 5cent price
|
||||
#To find the closest 5cent price the mathematical solution is
|
||||
# 1) Multiply by 20
|
||||
# 2) Round to the Coloses full number
|
||||
# 3) Divide by 20
|
||||
priceOpen=$(echo "scale=2; exact=((${shortBidC}+${shortAskC})/2) + ((${shortBidP}+${shortAskP})/2) - ((${longBidC}+${longAskC})/2) - ((${longBidP}+${longAskP})/2) + ${priceOffset}; scale=0; round5=exact*20/1; scale=2; round5/20" | bc)
|
||||
|
||||
orderJson=$(jq -c <<-EOM
|
||||
{
|
||||
"orderType": "NET_CREDIT",
|
||||
"session": "NORMAL",
|
||||
"price": ${priceOpen},
|
||||
"duration": "GOOD_TILL_CANCEL",
|
||||
"orderStrategyType": "SINGLE",
|
||||
"quantity": 1,
|
||||
"orderLegCollection": [
|
||||
{
|
||||
"instruction": "SELL_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${shortSymbolP}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "SELL_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${shortSymbolC}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "BUY_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${longSymbolP}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
},
|
||||
{
|
||||
"instruction": "BUY_TO_OPEN",
|
||||
"quantity": 1,
|
||||
"instrument": {
|
||||
"symbol": "${longSymbolC}",
|
||||
"assetType": "OPTION"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOM
|
||||
)
|
||||
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Order: _${orderJson}_"
|
||||
|
||||
if [[ "${noconfirm}" != "true" ]]; then
|
||||
echo ${orderJson} | jq
|
||||
echo Enter to continue, Ctrl+C to cancel _${noconfirm}_
|
||||
read
|
||||
fi
|
||||
|
||||
./getNewAccessToken.sh
|
||||
|
||||
|
||||
curl -s -X POST \
|
||||
'https://api.schwabapi.com/trader/v1/accounts/C819AC820A502BA92E55D775B22BDF0E1BC91D86C62685714347734A5827CCB3/orders' \
|
||||
-H "Authorization: Bearer $(<access_token.dat)" \
|
||||
-H 'accept: */*' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "${orderJson}"
|
||||
|
||||
@@ -7,6 +7,14 @@ daysOutMax=91
|
||||
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
|
||||
errMsg="The market is closed, exiting."
|
||||
systemd-cat -t "`basename $0` $1" -p info <<< ${errMsg}
|
||||
>&2 echo "${errMsg}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
inputFile="$1"
|
||||
if [[ "" == "$inputFile" ]]; then
|
||||
latestFile="$(ls data/`date +%Y-%m-%d`/*SPY* | sort | tail -n 1)"
|
||||
@@ -21,7 +29,7 @@ if [[ ! -f "${inputFile}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dateKey=$(jq -r '.callExpDateMap | keys | .[]' temp/orderInputFile.json | sort -r -t ":" +2 | awk -F ":" -e '{theDay=$2; if (theDay < '${daysOutMin}') { print lastDay; exit; } else { lastDay=$0; } }')
|
||||
dateKey=$(jq -r '.callExpDateMap | keys | .[]' "${inputFile}" | sort -r -t ":" +2 | awk -F ":" -e '{theDay=$2; if (theDay < '${daysOutMin}') { print lastDay; exit; } else { lastDay=$0; } }')
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Date-Key: _${dateKey}_"
|
||||
|
||||
daysOut=$(cut -d : -f 2 <<< ${dateKey})
|
||||
@@ -89,8 +97,11 @@ EOM
|
||||
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< "Order: _${orderJson}_"
|
||||
|
||||
echo Enter to continue, Ctrl+C to cancel
|
||||
read
|
||||
if [[ "${noconfirm}" != "true" ]]; then
|
||||
echo Enter to continue, Ctrl+C to cancel _${noconfirm}_
|
||||
read
|
||||
fi
|
||||
|
||||
./getNewAccessToken.sh
|
||||
|
||||
curl -s -X POST \
|
||||
|
||||
52
getMarketHours.sh
Executable file
52
getMarketHours.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
set -e
|
||||
mkdir -p temp
|
||||
|
||||
ErrorLogLevel=err
|
||||
#Handle additional commandline parameters
|
||||
if [[ $1 == -* ]]; then
|
||||
if [[ $1 == "-ErrorAsWarning" ]]; then
|
||||
ErrorLogLevel=warning
|
||||
shift
|
||||
fi
|
||||
fi
|
||||
|
||||
markets=""
|
||||
if [[ ! -z $1 ]]; then
|
||||
markets=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ -z "${markets}" ]]; then
|
||||
markets="equity&markets=option&markets=bond&markets=future&markets=forex"
|
||||
fi
|
||||
|
||||
queryString="?markets=${markets}"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
queryString="${queryString}&$1=$2"
|
||||
shift; shift
|
||||
done
|
||||
|
||||
msg="Querying for markets: _${markets}_ query string: _${queryString}_"
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< ${msg}
|
||||
|
||||
curl -s -X GET "https://api.schwabapi.com/marketdata/v1/markets${queryString}" \
|
||||
-H "Authorization: Bearer $(<access_token.dat)" > temp/markets.tmp.$$.json
|
||||
|
||||
|
||||
marketsCheck=$(jq -e -r '.. | .isOpen?' temp/markets.tmp.$$.json | grep -v null | wc -l)
|
||||
if [[ ${marketsCheck} -eq 0 ]]; then
|
||||
errMsg="ERROR: THE RESPONSE IS INCORRECT! markets: _${markets}_ Check: _${marketsCheck}_ check file _temp/markets.tmp.$$.json_"
|
||||
systemd-cat -t "`basename $0` $1" -p ${ErrorLogLevel} <<< ${errMsg}
|
||||
if [[ "${ErrorLogLevel}" == "err" ]]; then
|
||||
>&2 echo "${errMsg}"
|
||||
fi
|
||||
exit 2
|
||||
else
|
||||
jq < temp/markets.tmp.$$.json
|
||||
rm temp/markets.tmp.$$.json
|
||||
fi
|
||||
|
||||
|
||||
@@ -17,11 +17,12 @@ if [[ $? -ne 0 ]]; then
|
||||
fi
|
||||
#echo Access Token: $(<access_token.dat)
|
||||
|
||||
# I have not seen it change, but let's see if they give us a new one before expiry...
|
||||
# after all they send it so we should probably process it.
|
||||
jq -e -r .refresh_token temp/accessTokenReqResp.$$.json > temp/refresh_token.dat
|
||||
if [[ $? -eq 0 ]]; then
|
||||
mv temp/refresh_token.dat refresh_token.dat
|
||||
fi
|
||||
#echo Refresh Token: $(<refresh_token.dat)
|
||||
|
||||
## I found the refresh token to be empty after the network is unreachable, therefore I don't handle the refresh token here...
|
||||
## I have not seen it change, but let's see if they give us a new one before expiry...
|
||||
## after all they send it so we should probably process it.
|
||||
#jq -e -r .refresh_token temp/accessTokenReqResp.$$.json > temp/refresh_token.dat
|
||||
#if [[ $? -eq 0 ]]; then
|
||||
# mv temp/refresh_token.dat refresh_token.dat
|
||||
#fi
|
||||
##echo Refresh Token: $(<refresh_token.dat)
|
||||
#
|
||||
|
||||
44
getOptionChain.sh
Executable file
44
getOptionChain.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
#set -x
|
||||
mkdir -p temp
|
||||
|
||||
ErrorLogLevel=err
|
||||
#Handle additional commandline parameters
|
||||
if [[ $1 == -* ]]; then
|
||||
if [[ $1 == "-ErrorAsWarning" ]]; then
|
||||
ErrorLogLevel=warning
|
||||
shift
|
||||
fi
|
||||
fi
|
||||
|
||||
symbol=$1
|
||||
shift
|
||||
|
||||
queryString="?symbol=${symbol}"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
queryString="${queryString}&$1=$2"
|
||||
shift; shift
|
||||
done
|
||||
|
||||
msg="Querying for Symbol: _${symbol}_ query string: _${queryString}_"
|
||||
systemd-cat -t "`basename $0` $1" -p debug <<< ${msg}
|
||||
|
||||
curl -s -X GET "https://api.schwabapi.com/marketdata/v1/chains${queryString}" \
|
||||
-H "Authorization: Bearer $(<access_token.dat)" > temp/optionChain.${symbol}.tmp.$$.json
|
||||
|
||||
jqQuery=".symbol"
|
||||
symbolCheck=$(jq -r ${jqQuery} < temp/optionChain.${symbol}.tmp.$$.json)
|
||||
if [[ "${symbol}" != "${symbolCheck}" ]]; then
|
||||
errMsg="ERROR: THE RESPONSE IS INCORRECT! Symbol: _${symbol}_ Check: _${symbolCheck}_ check file _temp/optionChain.${symbol}.tmp.$$.json_"
|
||||
systemd-cat -t "`basename $0` $1" -p ${ErrorLogLevel} <<< ${errMsg}
|
||||
if [[ "${ErrorLogLevel}" == "err" ]]; then
|
||||
>&2 echo "${errMsg}"
|
||||
fi
|
||||
exit 2
|
||||
else
|
||||
jq < temp/optionChain.${symbol}.tmp.$$.json
|
||||
rm temp/optionChain.${symbol}.tmp.$$.json
|
||||
fi
|
||||
|
||||
|
||||
@@ -10,12 +10,7 @@ if [[ $? -ne 0 ]]; then
|
||||
fi
|
||||
|
||||
jq -r '.[].Symbol' allSymbols.json | sort | while read theSymbol; do
|
||||
# I am not interested in detail quotes at the moment
|
||||
#./recordQuoteSingleSymbolSingleRun.sh ${theSymbol}
|
||||
#if [[ $? -ne 0 ]]; then
|
||||
# touch temp/hadErrors.$$.tmp
|
||||
#fi
|
||||
|
||||
#The result of XSP is too big causing a problem at the server, therefore limiting to future 400 days and splitting if needed
|
||||
if [[ '$XSP' = ${theSymbol} ]]; then
|
||||
./recordOptionChainSingleSymbolSingleRun.sh -ErrorAsWarning ${theSymbol} toDate $(date "+%Y-%m-%d" -d "+400 days")
|
||||
if [[ $? -ne 0 ]]; then
|
||||
@@ -29,14 +24,6 @@ jq -r '.[].Symbol' allSymbols.json | sort | while read theSymbol; do
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ '$SPX' = ${theSymbol} ]]; then
|
||||
./recordOptionChainSingleSymbolSingleRun.sh -ErrorAsWarning ${theSymbol} fromDate $(date "+%Y-%m-%d" -d "+40 days") toDate $(date "+%Y-%m-%d" -d "+46 days")
|
||||
if [[ $? -ne 0 ]]; then
|
||||
touch temp/hadErrors.$$.tmp
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
#Default behavior - fall back to stitching on error
|
||||
./recordOptionChainSingleSymbolSingleRun.sh -ErrorAsWarning ${theSymbol}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
|
||||
Reference in New Issue
Block a user