gui trade kukatko

This commit is contained in:
David Brazda
2023-04-24 13:57:23 +02:00
parent 541aaa4ab8
commit c4ba2fa9d8
9 changed files with 179 additions and 14 deletions

View File

@ -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)}, ]

View File

@ -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

View File

@ -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}")

View File

@ -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()

View File

@ -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>

View File

@ -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');

View File

@ -79,3 +79,8 @@ pre {
/* display: block; */ /* display: block; */
font-size: smaller; font-size: smaller;
} }
#trades-data {
height: 350px;
overflow: auto;
}