Compare commits
10 Commits
05a55f6434
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 03dcec5708 | |||
| 1234277b41 | |||
| 94f6733e35 | |||
| 2143f7f636 | |||
| 08cd1d870a | |||
| 12fd00b3cd | |||
| ba4df998fb | |||
|
|
723f976d50 | ||
|
|
7c4683442d | ||
|
|
1fdf705eb5 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -110,3 +110,5 @@ dist
|
|||||||
server/quoteDBs/consolidated.sqlite3
|
server/quoteDBs/consolidated.sqlite3
|
||||||
server/quoteDBs/processedDBs
|
server/quoteDBs/processedDBs
|
||||||
server/quoteDBs/*.7z
|
server/quoteDBs/*.7z
|
||||||
|
server/quoteDBs/lastRun.stamp
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,14 @@ body {
|
|||||||
background-color: #cccccc;
|
background-color: #cccccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#frmChangePrice {
|
||||||
|
position: absolute;
|
||||||
|
width: 200px;
|
||||||
|
background-color: #FF0000;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#frmOrder {
|
#frmOrder {
|
||||||
background-color:#ccff00;
|
background-color:#ccff00;
|
||||||
position:fixed;
|
position:fixed;
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ let createMasterFilterFrame=()=>{
|
|||||||
return(_filterContext.theSymbol);
|
return(_filterContext.theSymbol);
|
||||||
}
|
}
|
||||||
me.symbolChanged=(newSymbol)=>{
|
me.symbolChanged=(newSymbol)=>{
|
||||||
|
localStorage["defaults"]=JSON.stringify({Symbol:newSymbol});
|
||||||
newSymbol=me.toBrokerName(newSymbol);
|
newSymbol=me.toBrokerName(newSymbol);
|
||||||
console.log("symbolChanged",newSymbol);
|
console.log("symbolChanged",newSymbol);
|
||||||
_filterContext.theSymbol=newSymbol
|
_filterContext.theSymbol=newSymbol
|
||||||
|
|||||||
@@ -5,10 +5,20 @@ $(document).ready(_=>{
|
|||||||
dta={};
|
dta={};
|
||||||
createOrderFrame();
|
createOrderFrame();
|
||||||
createMasterFilterFrame();
|
createMasterFilterFrame();
|
||||||
|
|
||||||
let selectDataFirst=_=>{
|
let selectDataFirst=_=>{
|
||||||
return {enabled:false, tooltip:"Select a Ticker!"};
|
return {enabled:false, tooltip:"Select a Ticker!"};
|
||||||
}
|
}
|
||||||
$("#datePicker").datepicker({beforeShowDay:selectDataFirst});
|
$("#datePicker").datepicker({beforeShowDay:selectDataFirst});
|
||||||
|
|
||||||
|
let selectedSymbol;
|
||||||
|
try {
|
||||||
|
selectedSymbol=JSON.parse(localStorage["defaults"]).Symbol;
|
||||||
|
document.getElementById("frmMasterFilter").symbolChanged(selectedSymbol);
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("No symbol found to preset",ex);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,17 @@ let createOrderFrame=()=>{
|
|||||||
<div id='lbCostAmount'>0</div>
|
<div id='lbCostAmount'>0</div>
|
||||||
<ul id='listOrderItems'>
|
<ul id='listOrderItems'>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="wrapper" id="frmChangePrice" style="display:none">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">$</span>
|
||||||
|
<input type="text" class="form-control" id='changePriceValue' aria-label="Amount (to the nearest dollar)">
|
||||||
|
<span class="input-group-addon">.00</span>
|
||||||
|
</div>
|
||||||
|
<div style="text-align:right">
|
||||||
|
<button class="btn btn-success" type="button" onclick='$("#frmChangePrice").data("targetLine").changePrice($("#changePriceValue").val()/100);$(frmChangePrice).hide();'>OK</button>
|
||||||
|
<button class="btn btn-primary" type="button" onclick='$(frmChangePrice).hide();'>CANCEL</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
$('#app').append(me);
|
$('#app').append(me);
|
||||||
|
|
||||||
@@ -32,6 +43,7 @@ let createOrderFrame=()=>{
|
|||||||
}
|
}
|
||||||
if (me.getElementsByClassName("quantity")[0] !== undefined) {
|
if (me.getElementsByClassName("quantity")[0] !== undefined) {
|
||||||
me.getElementsByClassName("quantity")[0].innerText = me.quantity;
|
me.getElementsByClassName("quantity")[0].innerText = me.quantity;
|
||||||
|
me.getElementsByClassName("singlePrice")[0].innerText = me.singleCostAmount.toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2}).padStart(6,"\xa0");
|
||||||
me.getElementsByClassName("totalCost")[0].innerText = me.totalCostAmount.toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2});
|
me.getElementsByClassName("totalCost")[0].innerText = me.totalCostAmount.toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -49,6 +61,19 @@ let createOrderFrame=()=>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
me.displayFrmPriceChange=_=>{
|
||||||
|
$("#changePriceValue").val(parseInt(me.price*100,10));
|
||||||
|
let clickElePos=$(event.target).position();
|
||||||
|
$("#frmChangePrice").css("left",clickElePos.left).css("top",clickElePos.top);
|
||||||
|
$("#frmChangePrice").data('targetLine',event.target.parentElement);
|
||||||
|
$("#frmChangePrice").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
me.changePrice=newPrice=>{
|
||||||
|
me.price=newPrice;
|
||||||
|
me.updateNumbers();
|
||||||
|
}
|
||||||
|
|
||||||
me.removeFromOrder=_=>{
|
me.removeFromOrder=_=>{
|
||||||
me.quantity=0;
|
me.quantity=0;
|
||||||
me.updateNumbers();
|
me.updateNumbers();
|
||||||
@@ -56,7 +81,7 @@ let createOrderFrame=()=>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
let splitOptionDetails=(input)=>{
|
let splitOptionDetails=(input)=>{
|
||||||
let symbolRest=input.split("_");
|
let symbolRest=input.split(/ +|_/);
|
||||||
let symbol=symbolRest[0];
|
let symbol=symbolRest[0];
|
||||||
|
|
||||||
let putCall=(symbolRest[1].indexOf("P")>-1)?"P":"C";
|
let putCall=(symbolRest[1].indexOf("P")>-1)?"P":"C";
|
||||||
@@ -70,12 +95,13 @@ let createOrderFrame=()=>{
|
|||||||
let optionDetails=splitOptionDetails(optionData.symbol);
|
let optionDetails=splitOptionDetails(optionData.symbol);
|
||||||
|
|
||||||
me.innerHTML=`
|
me.innerHTML=`
|
||||||
<a class='danger' onclick='this.parentElement.removeFromOrder();'>[X]</a> <b>${myMasterFilter.selectedDate}|${myMasterFilter.selectedTime.substr(0,5)}</b>|<span class="opentype${openType}">${((openType==="buy")?" ":"") + openType}</span>@<span class="singlePrice">${Math.abs(me.singleCostAmount).toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2}).padStart(7,"\xa0")}</span>|<span class='quantity'>${me.quantity}</span>
|
<a class='danger' onclick='this.parentElement.removeFromOrder();'>[X]</a><b>${myMasterFilter.selectedDate}|${myMasterFilter.selectedTime.substr(0,5)}</b>|<span class="opentype${openType}">${((openType==="buy")?" ":"") + openType}</span><span class='plusMinus' onclick='this.parentElement.displayFrmPriceChange();'>@</span><span class="singlePrice">${Math.abs(me.singleCostAmount).toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2}).padStart(6,"\xa0")}</span>|<span class='quantity'>${me.quantity}</span>
|
||||||
<div class='plusMinusContainer'>
|
<div class='plusMinusContainer'>
|
||||||
<a class='plusMinus' onclick='this.parentElement.parentElement.increaseQty();'>[+]</a><a class='plusMinus' onclick='this.parentElement.parentElement.decreaseQty();'>[-]</a>
|
<a class='plusMinus' onclick='this.parentElement.parentElement.increaseQty();'>[+]</a><a class='plusMinus' onclick='this.parentElement.parentElement.decreaseQty();'>[-]</a>
|
||||||
</div>
|
</div>
|
||||||
<div class='orderItemLine2'>
|
<div class='orderItemLine2'>
|
||||||
${optionDetails.symbol} ${optionDetails.date} ${optionDetails.putCall} ${optionDetails.strike} => <span class='totalCost'>${me.totalCostAmount.toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2})}</span>
|
${optionDetails.symbol} ${optionDetails.date} ${optionDetails.putCall} ${optionDetails.strike} =>
|
||||||
|
<span class='totalCost'>${me.totalCostAmount.toLocaleString('en',{minimumFractionDigits: 0, maximumFractionDigits: 2})}</span>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ module.exports = compress(async (req, res) => {
|
|||||||
if (func === "/getSymbols") {
|
if (func === "/getSymbols") {
|
||||||
console.log("Request for Symbols");
|
console.log("Request for Symbols");
|
||||||
const db = new Database('./quoteDBs/consolidated.sqlite3', { verbose: console.log });
|
const db = new Database('./quoteDBs/consolidated.sqlite3', { verbose: console.log });
|
||||||
const stmt = db.prepare("SELECT distinct Symbol FROM OptionQuotes order by 1");
|
const stmt = db.prepare("SELECT distinct Symbol FROM Symbols order by 1");
|
||||||
let allDates = stmt.all();
|
let allDates = stmt.all();
|
||||||
//console.log(JSON.stringify(allDates));
|
//console.log(JSON.stringify(allDates));
|
||||||
db.close();
|
db.close();
|
||||||
|
|||||||
44
server/quoteDBs/continuousOptionTrainerLoad.sh
Normal file
44
server/quoteDBs/continuousOptionTrainerLoad.sh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
while /bin/true; do
|
||||||
|
(set -e
|
||||||
|
find /home/schwab/OptionRecorderSchwab/data/ -type f -cnewer lastRun.stamp | grep -v -e '\..TM\.' | sort | while read singleFile; do
|
||||||
|
echo Processing ${singleFile} | tee | systemd-cat -t "`basename $0`" -p debug
|
||||||
|
symbol=$(pbzip2 -dc "${singleFile}" | jq -e -r '.symbol' | tr -d '$')
|
||||||
|
timeStamp=$(basename "${singleFile}" | cut -c 1-19 | tr '_' ":")
|
||||||
|
insertSQL=$(cat <<-EOF
|
||||||
|
.timeout 10000;
|
||||||
|
insert into OptionQuotes (
|
||||||
|
TimeStamp,
|
||||||
|
Symbol,
|
||||||
|
Data
|
||||||
|
) select
|
||||||
|
datetime('${timeStamp}','utc'),
|
||||||
|
'${symbol}',
|
||||||
|
'$(pbzip2 -dc "${singleFile}")'
|
||||||
|
where not exists (select 1
|
||||||
|
from OptionQuotes
|
||||||
|
where TimeStamp=datetime('${timeStamp}','utc')
|
||||||
|
and Symbol='${symbol}'
|
||||||
|
);
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
echo "$insertSQL" | sqlite3 consolidated.sqlite3
|
||||||
|
touch -r "${singleFile}" lastRun.stamp
|
||||||
|
done) 2>&1 | systemd-cat -t "`basename $0`" -p debug
|
||||||
|
|
||||||
|
set +e
|
||||||
|
echo filling symbols table | tee | systemd-cat -t "`basename $0`" -p info
|
||||||
|
symbolUpdateSQL=$(cat <<-EOF
|
||||||
|
.timeout 10000;
|
||||||
|
insert INTO Symbols
|
||||||
|
select DISTINCT Symbol
|
||||||
|
from OptionQuotes
|
||||||
|
where OptionQuotes.Symbol not in (select Symbol from Symbols)
|
||||||
|
and Symbol!='';
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
echo "${symbolUpdateSQL}" | sqlite3 consolidated.sqlite3
|
||||||
|
|
||||||
|
inotifywait -e create -r /home/schwab/OptionRecorderSchwab/data/ | tee | systemd-cat -t "`basename $0`" -p info
|
||||||
|
sleep 200 # wait 200 seconds - this should be enough time for all files to finish writing...
|
||||||
|
done
|
||||||
@@ -2,4 +2,8 @@ CREATE TABLE IF NOT EXISTS "OptionQuotes"( "TimeStamp"DateTime DEFAULT CURRENT_T
|
|||||||
"Symbol" Text,
|
"Symbol" Text,
|
||||||
"Data" Text);
|
"Data" Text);
|
||||||
|
|
||||||
CREATE INDEX smbDaTi on OptionQuotes (Symbol,timestamp);
|
CREATE INDEX IF NOT EXISTS smbDaTi on OptionQuotes (Symbol,timestamp);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "Symbols" (
|
||||||
|
"Symbol" TEXT UNIQUE
|
||||||
|
);
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "YOU DONT WANT TO RUN THIS - it will destroy the db."
|
||||||
|
exit 7
|
||||||
|
|
||||||
mkdir -p processedDBs
|
mkdir -p processedDBs
|
||||||
|
|
||||||
rm consolidated.sqlite3
|
rm consolidated.sqlite3
|
||||||
sqlite3 consolidated.sqlite3 < createTable.sql
|
sqlite3 consolidated.sqlite3 < createTable.sql
|
||||||
|
|
||||||
ls quoteStore_202*.sqlite3.gz | while read db; do
|
ls quoteStore_202*.sqlite3.gz | sort | while read db; do
|
||||||
echo unpacking $db
|
echo unpacking $db
|
||||||
gzip -dc $db >/tmp/xx.sqlite3
|
gzip -dc $db >/tmp/xx.sqlite3
|
||||||
echo processing...
|
echo processing...
|
||||||
@@ -13,6 +16,10 @@ ls quoteStore_202*.sqlite3.gz | while read db; do
|
|||||||
sqlite3 /tmp/xx.sqlite3 'drop table OptionQuotes;'
|
sqlite3 /tmp/xx.sqlite3 'drop table OptionQuotes;'
|
||||||
sqlite3 /tmp/xx.sqlite3 'alter table tmp rename to OptionQuotes;'
|
sqlite3 /tmp/xx.sqlite3 'alter table tmp rename to OptionQuotes;'
|
||||||
sqlite3 /tmp/xx.sqlite3 '.dump OptionQuotes' | sqlite3 consolidated.sqlite3
|
sqlite3 /tmp/xx.sqlite3 '.dump OptionQuotes' | sqlite3 consolidated.sqlite3
|
||||||
|
|
||||||
|
echo filling symbols table
|
||||||
|
sqlite3 consolidated.sqlite3 'insert INTO Symbols select DISTINCT Symbol from OptionQuotes where OptionQuotes.Symbol not in (select Symbol from Symbols);'
|
||||||
|
|
||||||
echo deleting...
|
echo deleting...
|
||||||
rm /tmp/xx.sqlite3
|
rm /tmp/xx.sqlite3
|
||||||
mv $db processedDBs
|
mv $db processedDBs
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ while getopts "d" opt; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
find . -maxdepth 1 -name 'quoteStore_202*.sqlite3.gz' | while read db; do
|
find . -maxdepth 1 -name 'quoteStore_202*.sqlite3.gz' | sort | while read db; do
|
||||||
echo unpacking $db
|
echo unpacking $db
|
||||||
gzip -dc $db >/tmp/xx.sqlite3
|
gzip -dc $db >/tmp/xx.sqlite3
|
||||||
echo processing...
|
echo processing...
|
||||||
@@ -18,6 +18,10 @@ find . -maxdepth 1 -name 'quoteStore_202*.sqlite3.gz' | while read db; do
|
|||||||
sqlite3 /tmp/xx.sqlite3 'drop table OptionQuotes;'
|
sqlite3 /tmp/xx.sqlite3 'drop table OptionQuotes;'
|
||||||
sqlite3 /tmp/xx.sqlite3 'alter table tmp rename to OptionQuotes;'
|
sqlite3 /tmp/xx.sqlite3 'alter table tmp rename to OptionQuotes;'
|
||||||
sqlite3 /tmp/xx.sqlite3 '.dump OptionQuotes' | sqlite3 consolidated.sqlite3
|
sqlite3 /tmp/xx.sqlite3 '.dump OptionQuotes' | sqlite3 consolidated.sqlite3
|
||||||
|
|
||||||
|
echo filling symbols table
|
||||||
|
sqlite3 consolidated.sqlite3 'insert INTO Symbols select DISTINCT Symbol from OptionQuotes where OptionQuotes.Symbol not in (select Symbol from Symbols);'
|
||||||
|
|
||||||
rm /tmp/xx.sqlite3
|
rm /tmp/xx.sqlite3
|
||||||
if [[ "$delete" == "1" ]]; then
|
if [[ "$delete" == "1" ]]; then
|
||||||
echo deleting...
|
echo deleting...
|
||||||
|
|||||||
Reference in New Issue
Block a user