docasne ulozeni DYNAMICKY REFACTORING _NEW
This commit is contained in:
47
testy/pricecrosses.py
Normal file
47
testy/pricecrosses.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
|
||||||
|
test1_threshold = 28.905
|
||||||
|
bacma = []
|
||||||
|
bacma.append([28.91])
|
||||||
|
bacma.append([28.91,28.90])
|
||||||
|
bacma.append([28.91,28.90,28.89])
|
||||||
|
bacma.append([28.91,28.90,28.89,28.88])
|
||||||
|
bacma.append([28.91,28.90,28.89,28.88,28.87])
|
||||||
|
bacma.append([28.91,28.90,28.89,28.88,28.87,28.86])
|
||||||
|
|
||||||
|
|
||||||
|
def crossed_up(threshold, list):
|
||||||
|
"""check if threshold has crossed up last thresholdue in list"""
|
||||||
|
try:
|
||||||
|
if threshold < list[-1] and threshold >= list[-2]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except IndexError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def crossed_down(threshold, list):
|
||||||
|
"""check if threshold has crossed down last thresholdue in list"""
|
||||||
|
try:
|
||||||
|
if threshold > list[-1] and threshold <= list[-2]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except IndexError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def crossed(threshold, list):
|
||||||
|
"""check if threshold has crossed last thresholdue in list"""
|
||||||
|
if crossed_down(threshold, list) or crossed_up(threshold, list):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for i in bacma:
|
||||||
|
print(i)
|
||||||
|
print(f"threshold crossed down {i}", threshold_crossed_down(test1_threshold, i))
|
||||||
|
print(f"threshold crossed up {i}", threshold_crossed_up(test1_threshold, i))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -157,14 +157,14 @@ def next(data, state: StrategyState):
|
|||||||
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
pendingbuys_new[str(o.id)]=float(o.limit_price)
|
||||||
|
|
||||||
if pendingbuys_new != state.vars.pendingbuys:
|
if pendingbuys_new != state.vars.pendingbuys:
|
||||||
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
state.ilog(e="Rozdilna PB prepsana", pb_new=pendingbuys_new, pb_old = str(state.vars.pendingbuys))
|
||||||
print("ROZDILNA PENDINGBUYS přepsána")
|
print("ROZDILNA PENDINGBUYS přepsána")
|
||||||
print("OLD",state.vars.pendingbuys)
|
print("OLD",state.vars.pendingbuys)
|
||||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||||
print("NEW", state.vars.pendingbuys)
|
print("NEW", state.vars.pendingbuys)
|
||||||
else:
|
else:
|
||||||
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
print("PENDINGBUYS sedí - necháváme", state.vars.pendingbuys)
|
||||||
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = state.vars.pendingbuys)
|
state.ilog(e="PB sedi nechavame", pb_new=pendingbuys_new, pb_old = str(state.vars.pendingbuys))
|
||||||
print("OLD jevylozeno", state.vars.jevylozeno)
|
print("OLD jevylozeno", state.vars.jevylozeno)
|
||||||
if len(state.vars.pendingbuys) > 0:
|
if len(state.vars.pendingbuys) > 0:
|
||||||
state.vars.jevylozeno = 1
|
state.vars.jevylozeno = 1
|
||||||
@ -952,7 +952,7 @@ def next(data, state: StrategyState):
|
|||||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||||
#lp = state.interface.get_last_price(symbol=state.symbol)
|
#lp = state.interface.get_last_price(symbol=state.symbol)
|
||||||
lp = data['close']
|
lp = data['close']
|
||||||
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", last_price=lp, data=data, stratvars=state.vars)
|
state.ilog(e="ENTRY", msg=f"LP:{lp} P:{state.positions}/{round(float(state.avgp),3)} profit:{round(float(state.profit),2)} Trades:{len(state.tradeList)} DEF:{str(is_defensive_mode())}", pb=str(state.vars.pendingbuys), last_price=lp, data=data, stratvars=state.vars)
|
||||||
state.ilog(e="Indikatory", msg=str(get_last_ind_vals()))
|
state.ilog(e="Indikatory", msg=str(get_last_ind_vals()))
|
||||||
|
|
||||||
eval_buy()
|
eval_buy()
|
||||||
|
|||||||
1322
v2realbot/ENTRY_Vykladaci_RSI_MYSELL_type_NEW.py
Normal file
1322
v2realbot/ENTRY_Vykladaci_RSI_MYSELL_type_NEW.py
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@ -25,6 +25,16 @@ from alpaca.data.enums import Exchange
|
|||||||
# 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}")
|
||||||
|
|
||||||
|
|
||||||
|
class Intervals(BaseModel):
|
||||||
|
start: str
|
||||||
|
end: str
|
||||||
|
|
||||||
|
# Define the data model for the TestLists
|
||||||
|
class TestList(BaseModel):
|
||||||
|
id: Optional[UUID | str | None] = None
|
||||||
|
name: str
|
||||||
|
dates: List[Intervals]
|
||||||
|
|
||||||
#for GUI to fetch historical trades on given symbol
|
#for GUI to fetch historical trades on given symbol
|
||||||
class Trade(BaseModel):
|
class Trade(BaseModel):
|
||||||
symbol: str
|
symbol: str
|
||||||
|
|||||||
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
from v2realbot.enums.enums import RecordType, StartBarAlign
|
from v2realbot.enums.enums import RecordType, StartBarAlign
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from v2realbot.utils.utils import ltp
|
from v2realbot.utils.utils import ltp, send_to_telegram
|
||||||
from alpaca.trading.client import TradingClient
|
from alpaca.trading.client import TradingClient
|
||||||
from alpaca.trading.requests import MarketOrderRequest, TakeProfitRequest, LimitOrderRequest, ReplaceOrderRequest, GetOrdersRequest
|
from alpaca.trading.requests import MarketOrderRequest, TakeProfitRequest, LimitOrderRequest, ReplaceOrderRequest, GetOrdersRequest
|
||||||
from alpaca.trading.enums import OrderSide, TimeInForce, OrderClass, OrderStatus, QueryOrderStatus
|
from alpaca.trading.enums import OrderSide, TimeInForce, OrderClass, OrderStatus, QueryOrderStatus
|
||||||
@ -8,6 +8,7 @@ from alpaca.trading.models import Order, Position
|
|||||||
from alpaca.common.exceptions import APIError
|
from alpaca.common.exceptions import APIError
|
||||||
from v2realbot.config import Keys
|
from v2realbot.config import Keys
|
||||||
from v2realbot.interfaces.general_interface import GeneralInterface
|
from v2realbot.interfaces.general_interface import GeneralInterface
|
||||||
|
from traceback import format_exc
|
||||||
"""""
|
"""""
|
||||||
Live interface with Alpaca for LIVE and PAPER trading.
|
Live interface with Alpaca for LIVE and PAPER trading.
|
||||||
"""""
|
"""""
|
||||||
@ -159,12 +160,15 @@ class LiveInterface(GeneralInterface):
|
|||||||
a : Position = self.trading_client.get_open_position(self.symbol)
|
a : Position = self.trading_client.get_open_position(self.symbol)
|
||||||
self.avgp, self.poz = float(a.avg_entry_price), int(a.qty)
|
self.avgp, self.poz = float(a.avg_entry_price), int(a.qty)
|
||||||
return a.avg_entry_price, a.qty
|
return a.avg_entry_price, a.qty
|
||||||
except APIError as e:
|
except (APIError, Exception) as e:
|
||||||
#no position
|
#no position
|
||||||
if e.code == 40410000: return 0,0
|
if e.code == 40410000: return 0,0
|
||||||
else:
|
else:
|
||||||
|
reason = "Exception when calling LIVE interface pos, REPEATING:" + str(e) + format_exc()
|
||||||
|
print("API ERROR: Nepodarilo se ziskat pozici.", reason)
|
||||||
|
send_to_telegram(reason)
|
||||||
#raise Exception(e)
|
#raise Exception(e)
|
||||||
return -1
|
return -1,-1
|
||||||
|
|
||||||
"""get open orders ->list(Order)"""
|
"""get open orders ->list(Order)"""
|
||||||
def get_open_orders(self, symbol: str, side: OrderSide = OrderSide.SELL): # -> list(Order):
|
def get_open_orders(self, symbol: str, side: OrderSide = OrderSide.SELL): # -> list(Order):
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.4.6/mousetrap.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.4.6/mousetrap.min.js"></script>
|
||||||
<!-- <script src="https://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script> -->
|
<!-- <script src="https://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script> -->
|
||||||
<script src="/static/js/fast-toml.js" type="text/javascript"></script>
|
<script src="/static/js/fast-toml.js" type="text/javascript"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="main" class="mainConteiner flex-container content">
|
<div id="main" class="mainConteiner flex-container content">
|
||||||
@ -503,6 +504,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="TestListContainer" class="flex-items">
|
||||||
|
<label data-bs-toggle="collapse" data-bs-target="#TestListInner" aria-expanded="true">
|
||||||
|
<h4>TestList Configuration</h4>
|
||||||
|
</label>
|
||||||
|
<div id="TestListInner" class="collapse show">
|
||||||
|
<div>
|
||||||
|
<form id="recordFormTestList">
|
||||||
|
<input type="hidden" id="recordId">
|
||||||
|
<label for="recordName">Name:</label>
|
||||||
|
<input type="text" id="recordName" required>
|
||||||
|
<br>
|
||||||
|
<!-- TODO predelat na intervaly v ramci dne (tzn. 1.1. 9:30 - 1.1. 9:45) -->
|
||||||
|
<!-- tzn. jeden zaznam v poli = start + end -->
|
||||||
|
<label for="datepickerstart">Start:</label>
|
||||||
|
<input type="datetime-local" id="datepickerstart" step="1">
|
||||||
|
<label for="datepickerend">End:</label>
|
||||||
|
<input type="datetime-local" id="datepickerend" step="1">
|
||||||
|
<button type="button" id="addTagBtn" class="btn btn-outline-success btn-sm">Add Date</button>
|
||||||
|
<br>
|
||||||
|
<div id="tagContainer"></div>
|
||||||
|
<br>
|
||||||
|
<button type="submit" id="saveBtn" class="btn btn-outline-success btn-sm">Save</button>
|
||||||
|
<button type="button" id="cancelBtn" class="btn btn-outline-success btn-sm">Cancel</button>
|
||||||
|
</form>
|
||||||
|
<div id="output"></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4>Test Lists</h4>
|
||||||
|
<div id="recordsList"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="configContainer" class="flex-items">
|
<div id="configContainer" class="flex-items">
|
||||||
<label data-bs-toggle="collapse" data-bs-target="#configInner" aria-expanded="true">
|
<label data-bs-toggle="collapse" data-bs-target="#configInner" aria-expanded="true">
|
||||||
<h4>Config</h4>
|
<h4>Config</h4>
|
||||||
@ -523,5 +556,6 @@
|
|||||||
<script src="/static/js/livewebsocket.js"></script>
|
<script src="/static/js/livewebsocket.js"></script>
|
||||||
<script src="/static/js/realtimechart.js"></script>
|
<script src="/static/js/realtimechart.js"></script>
|
||||||
<script src="/static/js/mytables.js"></script>
|
<script src="/static/js/mytables.js"></script>
|
||||||
|
<script src="/static/js/testlist.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
244
v2realbot/static/js/testlist.js
Normal file
244
v2realbot/static/js/testlist.js
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
//TODO pridat podporu pro intervaly
|
||||||
|
//pridat skrz proklik intervalu na 1m chart s timto intervalem - pripadne odkaz na tradingview
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
var apiUrl = '/testlists';
|
||||||
|
|
||||||
|
var datesArray = [];
|
||||||
|
|
||||||
|
//$('#datepicker').datepicker();
|
||||||
|
|
||||||
|
function populateForm(record) {
|
||||||
|
$('#recordId').val(record.id);
|
||||||
|
$('#recordName').val(record.name);
|
||||||
|
datesArray = record.dates;
|
||||||
|
$('#tagContainer').empty();
|
||||||
|
datesArray.forEach(function(dates) {
|
||||||
|
var tag = $('<div class="tag">' + dates.start + " --- " + dates.end + '<span class="close">X</span></div>');
|
||||||
|
tag.find('.close').click(function() {
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
$('#tagContainer').append(tag);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRecords(records) {
|
||||||
|
var recordsList = $('#recordsList');
|
||||||
|
recordsList.empty();
|
||||||
|
|
||||||
|
records.forEach(function(record) {
|
||||||
|
var recordItem = $('<div class="recordItem"></div>');
|
||||||
|
var recordDetails = $('<div class="recordDetails"></div>').html('<strong>ID:</strong> ' + record.id + '<br><strong>Name:</strong> ' + record.name + '<br><strong>Dates:</strong> ');
|
||||||
|
|
||||||
|
record.dates.forEach(function(interval) {
|
||||||
|
var intervalItem = $('<div class="intervalContainer"></div>').html('<strong>Start:</strong> ' + interval.start + '<br><strong>End:</strong> ' + interval.end);
|
||||||
|
recordDetails.append(intervalItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var editButton = $('<button class="btn btn-outline-success btn-sm">Edit</button>');
|
||||||
|
var deleteButton = $('<button class="btn btn-outline-success btn-sm">X</button>');
|
||||||
|
|
||||||
|
editButton.click(function() {
|
||||||
|
editRecord(record);
|
||||||
|
});
|
||||||
|
|
||||||
|
deleteButton.click(function() {
|
||||||
|
var confirmed = window.confirm("Confirm?");
|
||||||
|
if (confirmed) {
|
||||||
|
deleteRecord(record);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
recordItem.append(recordDetails);
|
||||||
|
recordItem.append(editButton);
|
||||||
|
recordItem.append(deleteButton);
|
||||||
|
recordsList.append(recordItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function editRecord(record) {
|
||||||
|
populateForm(record);
|
||||||
|
|
||||||
|
// Hide Edit button, show Save and Cancel buttons
|
||||||
|
$('.editButton').hide();
|
||||||
|
$('.deleteButton').hide();
|
||||||
|
$('#saveBtn').show();
|
||||||
|
$('#cancelBtn').show();
|
||||||
|
|
||||||
|
// Disable input fields
|
||||||
|
$('#recordName').prop('disabled', false);
|
||||||
|
$('#addTagBtn').prop('disabled', false);
|
||||||
|
$('#datepickerstart').prop('disabled', false);
|
||||||
|
$('#datepickerend').prop('disabled', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelEdit() {
|
||||||
|
// Clear form
|
||||||
|
$('#recordId').val('');
|
||||||
|
$('#recordName').val('');
|
||||||
|
$('#datepickerstart').val('');
|
||||||
|
$('#datepickerend').val('');
|
||||||
|
$('#tagContainer').empty();
|
||||||
|
datesArray = [];
|
||||||
|
|
||||||
|
// Hide Save and Cancel buttons, show Edit button
|
||||||
|
$('.editButton').show();
|
||||||
|
$('.deleteButton').show();
|
||||||
|
// $('#saveBtn').hide();
|
||||||
|
// $('#cancelBtn').hide();
|
||||||
|
|
||||||
|
// Disable input fields
|
||||||
|
$('#recordName').prop('disabled', false);
|
||||||
|
$('#addTagBtn').prop('disabled', false);
|
||||||
|
$('#datepickerstart').prop('disabled', false);
|
||||||
|
$('#datepickerend').prop('disabled', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#addTagBtn').click(function() {
|
||||||
|
var dateTextStart = $('#datepickerstart').val().trim();
|
||||||
|
var dateTextEnd = $('#datepickerend').val().trim();
|
||||||
|
if ((dateTextStart !== '') && (dateTextEnd !== '')) {
|
||||||
|
var tag = $('<div class="tag">' + dateTextStart + " --- " + dateTextEnd + '<span class="close">X</span></div>');
|
||||||
|
tag.find('.close').click(function() {
|
||||||
|
$(this).parent().remove();
|
||||||
|
});
|
||||||
|
$('#tagContainer').append(tag);
|
||||||
|
var interval = {}
|
||||||
|
interval["start"] = dateTextStart
|
||||||
|
interval["end"] = dateTextEnd
|
||||||
|
datesArray.push(interval);
|
||||||
|
$('#datepicker').val('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#recordFormTestList').submit(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var recordId = $('#recordId').val();
|
||||||
|
var recordName = $('#recordName').val().trim();
|
||||||
|
if (recordName === '') {
|
||||||
|
alert('Please enter a name.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var recordDates = datesArray;
|
||||||
|
|
||||||
|
var recordData = {
|
||||||
|
id: recordId,
|
||||||
|
name: recordName,
|
||||||
|
dates: recordDates
|
||||||
|
};
|
||||||
|
|
||||||
|
if (recordId) {
|
||||||
|
// Update existing record
|
||||||
|
console.log("update")
|
||||||
|
updateRecord(recordData);
|
||||||
|
} else {
|
||||||
|
// Create new record¨
|
||||||
|
console.log("create")
|
||||||
|
createRecord(recordData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#cancelBtn').click(function() {
|
||||||
|
// Clear form
|
||||||
|
cancelEdit();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#tagContainer').on('click', '.tag .close', function() {
|
||||||
|
var tag = $(this).parent();
|
||||||
|
var dateText = tag.text();
|
||||||
|
datesArray = datesArray.filter(function(date) {
|
||||||
|
tagcontent = date.start + " --- " + date.end
|
||||||
|
return tagcontent !== dateText;
|
||||||
|
});
|
||||||
|
tag.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
function getRecords() {
|
||||||
|
$.ajax({
|
||||||
|
url: apiUrl,
|
||||||
|
method: 'GET',
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-API-Key',
|
||||||
|
API_KEY); },
|
||||||
|
success: function(data) {
|
||||||
|
renderRecords(data);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRecord(recordData) {
|
||||||
|
jsonString = JSON.stringify(recordData);
|
||||||
|
$.ajax({
|
||||||
|
url: apiUrl,
|
||||||
|
method: 'POST',
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: "json",
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-API-Key',
|
||||||
|
API_KEY); },
|
||||||
|
data: jsonString,
|
||||||
|
success: function(data) {
|
||||||
|
getRecords();
|
||||||
|
cancelEdit();
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
|
window.alert(JSON.stringify(xhr));
|
||||||
|
console.log(JSON.stringify(xhr));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateRecord(recordData) {
|
||||||
|
var recordId = recordData.id;
|
||||||
|
jsonString = JSON.stringify(recordData);
|
||||||
|
$.ajax({
|
||||||
|
url: apiUrl + '/' + recordId,
|
||||||
|
method: 'PUT',
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: "json",
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-API-Key',
|
||||||
|
API_KEY); },
|
||||||
|
data: jsonString,
|
||||||
|
success: function(data) {
|
||||||
|
getRecords();
|
||||||
|
cancelEdit();
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
|
window.alert(JSON.stringify(xhr));
|
||||||
|
console.log(JSON.stringify(xhr));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteRecord(recordData) {
|
||||||
|
$.ajax({
|
||||||
|
url: apiUrl + '/' + recordData.id,
|
||||||
|
method: 'DELETE',
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: "json",
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-API-Key',
|
||||||
|
API_KEY); },
|
||||||
|
success: function(data) {
|
||||||
|
getRecords();
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
var err = eval("(" + xhr.responseText + ")");
|
||||||
|
window.alert(JSON.stringify(xhr));
|
||||||
|
console.log(JSON.stringify(xhr));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load initial records
|
||||||
|
getRecords();
|
||||||
|
});
|
||||||
|
|
||||||
@ -28,8 +28,10 @@ indConfig = [ {name: "ema", titlevisible: false, embed: true, display: true, pri
|
|||||||
{name: "slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
|
{name: "slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slopeNEW", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
|
{name: "slopeNEW", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slope10", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
{name: "slope10", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
|
{name: "slope20", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slope10puv", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
{name: "slope10puv", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slope30", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
{name: "slopeS", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
|
{name: "slopeLP", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
{name: "slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slow_slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
|
{name: "slow_slope", titlevisible: true, embed: true, display: false, priceScaleId: "left", lastValueVisible: false},
|
||||||
{name: "slow_slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
{name: "slow_slopeMA", titlevisible: true, embed: true, display: true, priceScaleId: "left", lastValueVisible: false},
|
||||||
|
|||||||
@ -396,4 +396,81 @@ pre {
|
|||||||
'wght' 300,
|
'wght' 300,
|
||||||
'GRAD' 0,
|
'GRAD' 0,
|
||||||
'opsz' 24
|
'opsz' 24
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TestList part generated by ChatGPT */
|
||||||
|
.recordItem {
|
||||||
|
border: 1px solid #797979;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recordDetails {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .editButton,
|
||||||
|
#saveBtn,
|
||||||
|
#cancelBtn,
|
||||||
|
#addTagBtn {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 10px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editButton:hover,
|
||||||
|
#saveBtn:hover,
|
||||||
|
#cancelBtn:hover,
|
||||||
|
#addTagBtn:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editButton:active,
|
||||||
|
#saveBtn:active,
|
||||||
|
#cancelBtn:active,
|
||||||
|
#addTagBtn:active {
|
||||||
|
background-color: #3e8e41;
|
||||||
|
} */
|
||||||
|
|
||||||
|
.recordItem:after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recordItem .close {
|
||||||
|
visibility: hidden;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recordItem:hover .close {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#recordName:disabled,
|
||||||
|
#addTagBtn:disabled,
|
||||||
|
#datepicker:disabled {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|||||||
@ -77,11 +77,16 @@ class StrategyOrderLimitVykladaciNormalizedMYSELL(Strategy):
|
|||||||
|
|
||||||
#ic("notifikace sell mazeme limitku a update pozic")
|
#ic("notifikace sell mazeme limitku a update pozic")
|
||||||
#updatujeme pozice
|
#updatujeme pozice
|
||||||
self.state.avgp, self.state.positions = self.interface.pos()
|
a,p = self.interface.pos()
|
||||||
|
#pri chybe api nechavame puvodni hodnoty
|
||||||
|
if a != -1:
|
||||||
|
self.state.avgp, self.state.positions = a,p
|
||||||
#ic(self.state.avgp, self.state.positions)
|
#ic(self.state.avgp, self.state.positions)
|
||||||
self.state.vars.limitka = None
|
self.state.vars.limitka = None
|
||||||
self.state.vars.limitka_price = None
|
self.state.vars.limitka_price = None
|
||||||
self.state.vars.lastbuyindex = -5
|
#resetujeme lastbuyindex, pokud neni v konfiguraci jinak
|
||||||
|
if safe_get(self.state.vars, "last_buy_offset_reset_after_sell", True):
|
||||||
|
self.state.vars.lastbuyindex = -5
|
||||||
self.state.vars.jevylozeno = 0
|
self.state.vars.jevylozeno = 0
|
||||||
await self.state.cancel_pending_buys()
|
await self.state.cancel_pending_buys()
|
||||||
self.state.ilog(e="Příchozí SELL - FILL nebo CANCEL - mazeme limitku a pb", msg=data.order.status, orderid=str(data.order.id), pb=self.state.vars.pendingbuys)
|
self.state.ilog(e="Příchozí SELL - FILL nebo CANCEL - mazeme limitku a pb", msg=data.order.status, orderid=str(data.order.id), pb=self.state.vars.pendingbuys)
|
||||||
@ -125,11 +130,13 @@ class StrategyOrderLimitVykladaciNormalizedMYSELL(Strategy):
|
|||||||
if order != -1:
|
if order != -1:
|
||||||
print("ukladame pendingbuys")
|
print("ukladame pendingbuys")
|
||||||
self.state.vars.pendingbuys[str(order)]=price
|
self.state.vars.pendingbuys[str(order)]=price
|
||||||
|
ulozena_cena = self.state.vars.pendingbuys[str(order)]
|
||||||
|
self.state.ilog(e=f"Odeslan buy_l a ulozeno do pb {ulozena_cena=}", order=str(order), pb=str(self.state.vars.pendingbuys))
|
||||||
self.state.blockbuy = 1
|
self.state.blockbuy = 1
|
||||||
self.state.vars.lastbuyindex = self.state.bars['index'][-1]
|
self.state.vars.lastbuyindex = self.state.bars['index'][-1]
|
||||||
#ic(self.state.blockbuy)
|
#ic(self.state.blockbuy)
|
||||||
#ic(self.state.vars.lastbuyindex)
|
#ic(self.state.vars.lastbuyindex)
|
||||||
self.state.ilog(e="Odeslan buy_l a ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys)
|
#self.state.ilog(e="Odeslan buy_l a ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys)
|
||||||
else:
|
else:
|
||||||
self.state.ilog(e="Chyba - nepodarilo se odeslat buy_l - nebylo ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys)
|
self.state.ilog(e="Chyba - nepodarilo se odeslat buy_l - nebylo ulozeno do pb", order=str(order), pb=self.state.vars.pendingbuys)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@ -246,9 +246,13 @@ class Strategy:
|
|||||||
""""refresh positions and avgp - for CBAR once per confirmed, for BARS each time"""
|
""""refresh positions and avgp - for CBAR once per confirmed, for BARS each time"""
|
||||||
def refresh_positions(self, item):
|
def refresh_positions(self, item):
|
||||||
if self.rectype == RecordType.BAR:
|
if self.rectype == RecordType.BAR:
|
||||||
self.state.avgp, self.state.positions = self.interface.pos()
|
a,p = self.interface.pos()
|
||||||
|
if a != -1:
|
||||||
|
self.state.avgp, self.state.positions = a,p
|
||||||
elif self.rectype == RecordType.CBAR and item['confirmed'] == 1:
|
elif self.rectype == RecordType.CBAR and item['confirmed'] == 1:
|
||||||
self.state.avgp, self.state.positions= self.interface.pos()
|
a,p = self.interface.pos()
|
||||||
|
if a != -1:
|
||||||
|
self.state.avgp, self.state.positions = a,p
|
||||||
|
|
||||||
"""update state.last_trade_time a time of iteration"""
|
"""update state.last_trade_time a time of iteration"""
|
||||||
def update_times(self, item):
|
def update_times(self, item):
|
||||||
|
|||||||
Binary file not shown.
@ -9,7 +9,7 @@ import decimal
|
|||||||
from v2realbot.enums.enums import RecordType, Mode, StartBarAlign
|
from v2realbot.enums.enums import RecordType, Mode, StartBarAlign
|
||||||
import pickle
|
import pickle
|
||||||
import os
|
import os
|
||||||
from v2realbot.common.model import StrategyInstance, Runner, RunArchive, RunArchiveDetail
|
from v2realbot.common.model import StrategyInstance, Runner, RunArchive, RunArchiveDetail, Intervals
|
||||||
from typing import List
|
from typing import List
|
||||||
import tomli
|
import tomli
|
||||||
from v2realbot.config import DATA_DIR, QUIET_MODE,NORMALIZED_TICK_BASE_PRICE
|
from v2realbot.config import DATA_DIR, QUIET_MODE,NORMALIZED_TICK_BASE_PRICE
|
||||||
@ -23,6 +23,33 @@ import numpy as np
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
|
||||||
|
def crossed_up(threshold, list):
|
||||||
|
"""check if threshold has crossed up last thresholdue in list"""
|
||||||
|
try:
|
||||||
|
if threshold < list[-1] and threshold >= list[-2]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except IndexError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def crossed_down(threshold, list):
|
||||||
|
"""check if threshold has crossed down last thresholdue in list"""
|
||||||
|
try:
|
||||||
|
if threshold > list[-1] and threshold <= list[-2]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except IndexError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def crossed(threshold, list):
|
||||||
|
"""check if threshold has crossed last thresholdue in list"""
|
||||||
|
if crossed_down(threshold, list) or crossed_up(threshold, list):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def get_tick(price: float, normalized_ticks: float = 0.01):
|
def get_tick(price: float, normalized_ticks: float = 0.01):
|
||||||
"""
|
"""
|
||||||
prevede normalizovany tick na tick odpovidajici vstupni cene
|
prevede normalizovany tick na tick odpovidajici vstupni cene
|
||||||
@ -50,34 +77,47 @@ def eval_cond_dict(cond: dict) -> tuple[bool, str]:
|
|||||||
buy_cond["5siddngle"] = False
|
buy_cond["5siddngle"] = False
|
||||||
group eval rules. 1. single 2. AND 3. ORS
|
group eval rules. 1. single 2. AND 3. ORS
|
||||||
"""
|
"""
|
||||||
msg = ""
|
msg = {}
|
||||||
ret = False
|
ret = []
|
||||||
#eval single cond
|
|
||||||
for klic in cond:
|
|
||||||
if klic in ["AND","OR"]: continue
|
|
||||||
else:
|
|
||||||
if cond[klic]:
|
|
||||||
return True, klic
|
|
||||||
|
|
||||||
##check AND group
|
##check AND group
|
||||||
if 'AND' in cond.keys():
|
if 'AND' in cond.keys() and len(cond["AND"])>0:
|
||||||
|
msg["AND"] = {}
|
||||||
for key in cond["AND"]:
|
for key in cond["AND"]:
|
||||||
|
res = cond["AND"][key]
|
||||||
|
ret.append(res)
|
||||||
|
msg["AND"][key] = (str(res).upper() if res else str(res))
|
||||||
|
#msg += "[AND]" + key + ":" + (str(res).upper() if res else str(res)) + " "
|
||||||
|
|
||||||
if cond["AND"][key]:
|
if all(ret):
|
||||||
ret = True
|
|
||||||
msg += key + " AND "
|
|
||||||
else:
|
|
||||||
ret = False
|
|
||||||
break
|
|
||||||
if ret:
|
|
||||||
return True, msg
|
return True, msg
|
||||||
|
|
||||||
#eval OR groups
|
#eval OR groups
|
||||||
if "OR" in cond.keys():
|
if "OR" in cond.keys() and len(cond["OR"])>0:
|
||||||
|
ret = []
|
||||||
|
msg["OR"] = {}
|
||||||
for key in cond["OR"]:
|
for key in cond["OR"]:
|
||||||
if cond["OR"][key]:
|
res = cond["OR"][key]
|
||||||
return True, key
|
ret.append(res)
|
||||||
|
msg["OR"][key] = (str(res).upper() if res else str(res))
|
||||||
return False, None
|
#msg += "[OR]" + key + ":" + (str(res).upper() if res else str(res)) + " "
|
||||||
|
|
||||||
|
if any(ret):
|
||||||
|
return True, msg
|
||||||
|
|
||||||
|
#pokud nemame zadne AND ani OR, tak to je single cond
|
||||||
|
ret = []
|
||||||
|
for key in cond:
|
||||||
|
if key == "AND" or key == "OR":
|
||||||
|
continue
|
||||||
|
#je to vlastne to same jako OR
|
||||||
|
res = cond[key]
|
||||||
|
ret.append(res)
|
||||||
|
msg[key] = (str(res).upper() if res else str(res))
|
||||||
|
#msg += key + ":" + (str(res).upper() if res else str(res)) + " "
|
||||||
|
|
||||||
|
#pokud predchozi single obsahoval True, vratime True jinak False
|
||||||
|
return any(ret), msg
|
||||||
|
|
||||||
def Average(lst):
|
def Average(lst):
|
||||||
return sum(lst) / len(lst)
|
return sum(lst) / len(lst)
|
||||||
@ -132,6 +172,8 @@ def json_serial(obj):
|
|||||||
return obj.__dict__
|
return obj.__dict__
|
||||||
if type(obj) is RunArchiveDetail:
|
if type(obj) is RunArchiveDetail:
|
||||||
return obj.__dict__
|
return obj.__dict__
|
||||||
|
if type(obj) is Intervals:
|
||||||
|
return obj.__dict__
|
||||||
|
|
||||||
raise TypeError (str(obj)+"Type %s not serializable" % type(obj))
|
raise TypeError (str(obj)+"Type %s not serializable" % type(obj))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user