gui trade kukatko
This commit is contained in:
@ -1,27 +1,35 @@
|
|||||||
from alpaca.data.historical import CryptoHistoricalDataClient, StockHistoricalDataClient
|
from alpaca.data.historical import CryptoHistoricalDataClient, StockHistoricalDataClient
|
||||||
from alpaca.data.requests import CryptoLatestTradeRequest, StockLatestTradeRequest, StockLatestBarRequest, StockTradesRequest
|
from alpaca.data.requests import CryptoLatestTradeRequest, StockLatestTradeRequest, StockLatestBarRequest, StockTradesRequest
|
||||||
from alpaca.data.enums import DataFeed
|
from alpaca.data.enums import DataFeed
|
||||||
from config import API_KEY, SECRET_KEY, MAX_BATCH_SIZE
|
from v2realbot.config import ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY
|
||||||
import datetime
|
from datetime import datetime
|
||||||
import time
|
import time
|
||||||
|
from v2realbot.utils.utils import zoneNY
|
||||||
|
|
||||||
parametry = {}
|
parametry = {}
|
||||||
|
|
||||||
# no keys required
|
# no keys required
|
||||||
#client = CryptoHistoricalDataClient()
|
#client = CryptoHistoricalDataClient()
|
||||||
client = StockHistoricalDataClient(API_KEY, SECRET_KEY, raw_data=True)
|
client = StockHistoricalDataClient(ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY, raw_data=True)
|
||||||
|
|
||||||
# single symbol request
|
# single symbol request
|
||||||
#request_trade_params = StockTradesRequest(symbol_or_symbols="BAC", feed = DataFeed.SIP)
|
#request_trade_params = StockTradesRequest(symbol_or_symbols="BAC", feed = DataFeed.SIP)
|
||||||
#request_last_bar_params = StockLatestBarRequest(symbol_or_symbols="BAC", feed=DataFeed.SIP)
|
#request_last_bar_params = StockLatestBarRequest(symbol_or_symbols="BAC", feed=DataFeed.SIP)
|
||||||
|
|
||||||
#2023, 2, 27, 18, 51, 38
|
#2023, 2, 27, 18, 51, 38
|
||||||
|
client = StockHistoricalDataClient(ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY, raw_data=False)
|
||||||
datetime_object_from = datetime.datetime(2023, 2, 26, 17, 51, 38, tzinfo=datetime.timezone.utc)
|
ted = datetime.now()
|
||||||
|
timstp=ted.timestamp()
|
||||||
datetime_object_to = datetime.datetime(2023, 2, 28, 17, 51, 39, tzinfo=datetime.timezone.utc)
|
print(f"{timstp=}")
|
||||||
|
datumfromtimestamp = datetime.fromtimestamp(timstp, zoneNY)
|
||||||
trades_request = StockTradesRequest(symbol_or_symbols="C", feed = DataFeed.SIP, start=datetime_object_from, end=datetime_object_to)
|
print(datumfromtimestamp)
|
||||||
|
datetime_object_from = datetime(2023, 4, 14, 15, 51, 38, tzinfo=zoneNY)
|
||||||
|
datetime_object_to = datetime(2023, 4, 14, 15, 51, 39, tzinfo=zoneNY)
|
||||||
|
# datetime_object_from = datetime.fromtimestamp(1682310012.024338)
|
||||||
|
# datetime_object_to = datetime.fromtimestamp(1682310015.024338)
|
||||||
|
print(datetime_object_from.timestamp())
|
||||||
|
print(datetime_object_to.timestamp())
|
||||||
|
trades_request = StockTradesRequest(symbol_or_symbols="BAC", feed = DataFeed.SIP, start=datetime_object_from, end=datetime_object_to)
|
||||||
#latest_trade = client.get_stock_latest_trade(request_trade_params)
|
#latest_trade = client.get_stock_latest_trade(request_trade_params)
|
||||||
#latest_bar = client.get_stock_latest_bar(request_last_bar_params)
|
#latest_bar = client.get_stock_latest_bar(request_last_bar_params)
|
||||||
|
|
||||||
@ -36,4 +44,17 @@ all_trades = client.get_stock_trades(trades_request)
|
|||||||
# print("last trade",latest_trade)
|
# print("last trade",latest_trade)
|
||||||
# print("latest bar",latest_bar)
|
# print("latest bar",latest_bar)
|
||||||
# print("Trades Today", all_trades)
|
# print("Trades Today", all_trades)
|
||||||
print(len(all_trades["C"]))
|
#print(len(all_trades["C"]))
|
||||||
|
#1682310012.024338
|
||||||
|
print(all_trades["BAC"])
|
||||||
|
# raw True
|
||||||
|
# [{'t': '2023-04-14T19:51:38.432128256Z', 'x': 'D', 'p': 49.805, 's': 100, 'c': [' '], 'i': 71696766285400, 'z': 'A'}, {'t': '2023-04-14T19:51:38.518662144Z', 'x': 'T', 'p': 49.8, 's': 9, 'c': [' ', 'I'], 'i': 62880002366518, 'z': 'A'}]
|
||||||
|
# raw False
|
||||||
|
# [{ 'conditions': [' '],
|
||||||
|
# 'exchange': 'D',
|
||||||
|
# 'id': 71696766285400,
|
||||||
|
# 'price': 49.805,
|
||||||
|
# 'size': 100.0,
|
||||||
|
# 'symbol': 'C',
|
||||||
|
# 'tape': 'A',
|
||||||
|
# 'timestamp': datetime.datetime(2023, 4, 14, 19, 51, 38, 432128, tzinfo=datetime.timezone.utc)}, ]
|
||||||
Binary file not shown.
Binary file not shown.
@ -6,6 +6,7 @@ from typing import Any, Optional, List, Union
|
|||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from v2realbot.enums.enums import Mode, Account
|
from v2realbot.enums.enums import Mode, Account
|
||||||
|
from alpaca.data.enums import Exchange
|
||||||
|
|
||||||
#tu samou variantu pak UpdateStrategyInstanceWhileRunning
|
#tu samou variantu pak UpdateStrategyInstanceWhileRunning
|
||||||
|
|
||||||
@ -23,6 +24,19 @@ from v2realbot.enums.enums import Mode, Account
|
|||||||
# return user.id
|
# return user.id
|
||||||
# raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")
|
# raise HTTPException(status_code=404, detail=f"Could not find user with id: {id}")
|
||||||
|
|
||||||
|
|
||||||
|
#for GUI
|
||||||
|
class Trade(BaseModel):
|
||||||
|
symbol: str
|
||||||
|
timestamp: datetime
|
||||||
|
exchange: Optional[Union[Exchange, str]]
|
||||||
|
price: float
|
||||||
|
size: float
|
||||||
|
id: int
|
||||||
|
conditions: Optional[List[str]]
|
||||||
|
tape: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
#persisted object in pickle
|
#persisted object in pickle
|
||||||
class StrategyInstance(BaseModel):
|
class StrategyInstance(BaseModel):
|
||||||
id: Optional[UUID | str | None] = None
|
id: Optional[UUID | str | None] = None
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
from typing import Any, List
|
from typing import Any, List
|
||||||
from uuid import UUID, uuid4
|
from uuid import UUID, uuid4
|
||||||
import pickle
|
import pickle
|
||||||
|
from alpaca.data.historical import StockHistoricalDataClient
|
||||||
|
from alpaca.data.requests import StockTradesRequest
|
||||||
|
from alpaca.data.enums import DataFeed
|
||||||
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account
|
from v2realbot.enums.enums import RecordType, StartBarAlign, Mode, Account
|
||||||
from v2realbot.common.model import StrategyInstance, Runner, RunRequest
|
from v2realbot.common.model import StrategyInstance, Runner, RunRequest
|
||||||
from v2realbot.utils.utils import AttributeDict, zoneNY, dict_replace_value, Store, parse_toml_string
|
from v2realbot.utils.utils import AttributeDict, zoneNY, dict_replace_value, Store, parse_toml_string
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from threading import Thread, current_thread, Event, enumerate
|
from threading import Thread, current_thread, Event, enumerate
|
||||||
from v2realbot.config import STRATVARS_UNCHANGEABLES
|
from v2realbot.config import STRATVARS_UNCHANGEABLES, ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY
|
||||||
import importlib
|
import importlib
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
db = Store()
|
db = Store()
|
||||||
@ -352,3 +355,17 @@ def run_stratin(id: UUID, runReq: RunRequest):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return (-2, "Exception: "+str(e))
|
return (-2, "Exception: "+str(e))
|
||||||
return (-2, "not found")
|
return (-2, "not found")
|
||||||
|
|
||||||
|
def get_trade_history(symbol: str, timestamp_from: float, timestamp_to:float):
|
||||||
|
try:
|
||||||
|
datetime_object_from = datetime.fromtimestamp(timestamp_from, zoneNY)
|
||||||
|
datetime_object_to = datetime.fromtimestamp(timestamp_to, zoneNY)
|
||||||
|
#datetime_object_from = datetime(2023, 4, 14, 15, 51, 38, tzinfo=zoneNY)
|
||||||
|
#datetime_object_to = datetime(2023, 4, 14, 15, 51, 39, tzinfo=zoneNY)
|
||||||
|
client = StockHistoricalDataClient(ACCOUNT1_LIVE_API_KEY, ACCOUNT1_LIVE_SECRET_KEY, raw_data=False)
|
||||||
|
trades_request = StockTradesRequest(symbol_or_symbols=symbol, feed = DataFeed.SIP, start=datetime_object_from, end=datetime_object_to)
|
||||||
|
all_trades = client.get_stock_trades(trades_request)
|
||||||
|
#print(all_trades[symbol])
|
||||||
|
return 0, all_trades[symbol]
|
||||||
|
except Exception as e:
|
||||||
|
return (-2, f"problem {e}")
|
||||||
@ -12,7 +12,7 @@ from fastapi.security import APIKeyHeader
|
|||||||
import uvicorn
|
import uvicorn
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
import v2realbot.controller.services as cs
|
import v2realbot.controller.services as cs
|
||||||
from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest
|
from v2realbot.common.model import StrategyInstance, RunnerView, RunRequest, Trade
|
||||||
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
|
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException, status, WebSocketException, Cookie, Query
|
||||||
from fastapi.responses import HTMLResponse, FileResponse
|
from fastapi.responses import HTMLResponse, FileResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
@ -254,6 +254,14 @@ def stop_all_stratins():
|
|||||||
elif res < 0:
|
elif res < 0:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error: {res}:{id}")
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Error: {res}:{id}")
|
||||||
|
|
||||||
|
@app.get("/tradehistory/{symbol}", dependencies=[Depends(api_key_auth)])
|
||||||
|
def get_trade_history(symbol: str, timestamp_from: float, timestamp_to:float) -> list[Trade]:
|
||||||
|
res, set = cs.get_trade_history(symbol, timestamp_from, timestamp_to)
|
||||||
|
if res == 0:
|
||||||
|
return set
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=404, detail=f"No trades found {res}")
|
||||||
|
|
||||||
#join cekej na dokonceni vsech
|
#join cekej na dokonceni vsech
|
||||||
for i in cs.db.runners:
|
for i in cs.db.runners:
|
||||||
i.run_thread.join()
|
i.run_thread.join()
|
||||||
|
|||||||
@ -36,7 +36,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="hist-trades" class="flex-items">
|
||||||
|
<div id="form-trades">
|
||||||
|
<label data-toggle="collapse" data-target="#trades-data">Trade history</label>
|
||||||
|
<label>Timestamp: <input type="text" id="trade-timestamp" autocomplete="off"/></label>
|
||||||
|
<label>SYM: <input type="text" id="trade-symbol" autocomplete="off"/></label>
|
||||||
|
<label>Count: <input type="number" id="trade-count" autocomplete="off" value="2"/></label>
|
||||||
|
<label>Minsize: <input type="number" id="trade-minsize" autocomplete="off" value="100"/></label>
|
||||||
|
<label>Filter: <input type="text" id="trade-filter" autocomplete="off"/></label>
|
||||||
|
<button id="bt-trade" class="btn btn-success">Show</button></div>
|
||||||
|
<div id="trades-data" style="display: none" class="collapse in">
|
||||||
|
<table id="trades-data-table" class="display dataTable no-footer" style="width: 300px;display: contents;"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="runner-table" class="flex-items">
|
<div id="runner-table" class="flex-items">
|
||||||
<div id="controls">
|
<div id="controls">
|
||||||
<label>API-KEY: <input type="password" id="api-key" autocomplete="off"/></label>
|
<label>API-KEY: <input type="password" id="api-key" autocomplete="off"/></label>
|
||||||
|
|||||||
@ -1,6 +1,14 @@
|
|||||||
|
|
||||||
API_KEY = localStorage.getItem("api-key")
|
API_KEY = localStorage.getItem("api-key")
|
||||||
|
|
||||||
|
// Iterate through each element in the
|
||||||
|
// first array and if some of them
|
||||||
|
// include the elements in the second
|
||||||
|
// array then return true.
|
||||||
|
function findCommonElements3(arr1, arr2) {
|
||||||
|
return arr1.some(item => arr2.includes(item))
|
||||||
|
}
|
||||||
|
|
||||||
//KEY shortcuts
|
//KEY shortcuts
|
||||||
Mousetrap.bind('e', function() {
|
Mousetrap.bind('e', function() {
|
||||||
$( "#button_edit" ).trigger( "click" );
|
$( "#button_edit" ).trigger( "click" );
|
||||||
@ -88,6 +96,13 @@ $(document).ready(function () {
|
|||||||
stratinRecords.ajax.reload();
|
stratinRecords.ajax.reload();
|
||||||
runnerRecords.ajax.reload();
|
runnerRecords.ajax.reload();
|
||||||
|
|
||||||
|
$('#trade-timestamp').val(localStorage.getItem("trade_timestamp"));
|
||||||
|
$('#trade-count').val(localStorage.getItem("trade_count"));
|
||||||
|
$('#trade-symbol').val(localStorage.getItem("trade_symbol"));
|
||||||
|
$('#trade-minsize').val(localStorage.getItem("trade_minsize"));
|
||||||
|
$('#trade-filter').val(localStorage.getItem("trade_filter"));
|
||||||
|
|
||||||
|
|
||||||
//disable buttons (enable on row selection)
|
//disable buttons (enable on row selection)
|
||||||
$('#button_pause').attr('disabled','disabled');
|
$('#button_pause').attr('disabled','disabled');
|
||||||
$('#button_stop').attr('disabled','disabled');
|
$('#button_stop').attr('disabled','disabled');
|
||||||
@ -131,13 +146,86 @@ $(document).ready(function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//button get historical trades
|
||||||
|
$('#bt-trade').click(function () {
|
||||||
|
event.preventDefault();
|
||||||
|
$('#bt-trade').attr('disabled','disabled');
|
||||||
|
$( "#trades-data").addClass("in");
|
||||||
|
|
||||||
|
localStorage.setItem("trade_timestamp",$('#trade-timestamp').val());
|
||||||
|
localStorage.setItem("trade_count",$('#trade-count').val());
|
||||||
|
localStorage.setItem("trade_symbol",$('#trade-symbol').val());
|
||||||
|
localStorage.setItem("trade_minsize",$('#trade-minsize').val());
|
||||||
|
localStorage.setItem("trade_filter",$('#trade-filter').val());
|
||||||
|
|
||||||
|
const rec = new Object()
|
||||||
|
rec.timestamp_from = parseFloat($('#trade-timestamp').val())-parseInt($('#trade-count').val())
|
||||||
|
rec.timestamp_to = parseFloat($('#trade-timestamp').val())+parseInt($('#trade-count').val())
|
||||||
|
symbol = $('#trade-symbol').val()
|
||||||
|
//jsonString = JSON.stringify(rec);
|
||||||
|
//alert(JSON.stringify(rec))
|
||||||
|
$.ajax({
|
||||||
|
url:"/tradehistory/"+symbol+"/",
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-API-Key',
|
||||||
|
API_KEY); },
|
||||||
|
method:"GET",
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: "json",
|
||||||
|
data: rec,
|
||||||
|
success:function(data){
|
||||||
|
$('#bt-trade').attr('disabled', false);
|
||||||
|
$('#trades-data').show();
|
||||||
|
//$('#trades-data').text("")
|
||||||
|
var minsize = parseInt($('#trade-minsize').val());
|
||||||
|
//filter string to filter array
|
||||||
|
var valueInserted = $("#trade-filter").val(); // "tag1,tag2,tag3, "two words""
|
||||||
|
var filterList = valueInserted.split(","); // ["tag1", "tag2", "tag3", "two words"]
|
||||||
|
for (var i in filterList) {
|
||||||
|
filterList[i] = filterList[i].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("filter list")
|
||||||
|
console.log(filterList)
|
||||||
|
console.log(minsize)
|
||||||
|
var row = ""
|
||||||
|
var puvodni = parseFloat($('#trade-timestamp').val())
|
||||||
|
$('#trades-data-table').html(row);
|
||||||
|
data.forEach((tradeLine) => {
|
||||||
|
//console.log(JSON.stringify(tradeLine))
|
||||||
|
date = new Date(tradeLine.timestamp)
|
||||||
|
timestamp = date.getTime()/1000
|
||||||
|
|
||||||
|
//trade contains filtered condition
|
||||||
|
bg = (findCommonElements3(filterList, tradeLine.conditions) ? 'style="background-color: #e6e6e6;"' : '')
|
||||||
|
|
||||||
|
row += '<tr role="row" '+ ((timestamp == puvodni) ? 'class="selected"' : '') +' ' + bg + '><td>' + timestamp + '</td><td>' + tradeLine.price + '</td>' +
|
||||||
|
'<td>' + tradeLine.size + '</td><td>' + tradeLine.id + '</td>' +
|
||||||
|
'<td>' + tradeLine.conditions + '</td><td>' + tradeLine.tape + '</td>' +
|
||||||
|
'<td>' + tradeLine.timestamp + '</td></tr>';
|
||||||
|
|
||||||
|
});
|
||||||
|
//console.log(row);
|
||||||
|
$('#trades-data-table').html(row);
|
||||||
|
// $('#trades-data').html(row)
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
|
window.alert(JSON.stringify(xhr));
|
||||||
|
console.log(JSON.stringify(xhr));
|
||||||
|
$('#bt-trade').attr('disabled', false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
//button refresh
|
//button refresh
|
||||||
$('#button_refresh').click(function () {
|
$('#button_refresh').click(function () {
|
||||||
runnerRecords.ajax.reload();
|
runnerRecords.ajax.reload();
|
||||||
stratinRecords.ajax.reload();
|
stratinRecords.ajax.reload();
|
||||||
})
|
})
|
||||||
|
|
||||||
//button refresh
|
//button copy
|
||||||
$('#button_copy').click(function () {
|
$('#button_copy').click(function () {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$('#button_copy').attr('disabled','disabled');
|
$('#button_copy').attr('disabled','disabled');
|
||||||
|
|||||||
@ -79,3 +79,8 @@ pre {
|
|||||||
/* display: block; */
|
/* display: block; */
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#trades-data {
|
||||||
|
height: 350px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user