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)
|
||||
|
||||
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("OLD",state.vars.pendingbuys)
|
||||
state.vars.pendingbuys = unpackb(packb(pendingbuys_new))
|
||||
print("NEW", state.vars.pendingbuys)
|
||||
else:
|
||||
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)
|
||||
if len(state.vars.pendingbuys) > 0:
|
||||
state.vars.jevylozeno = 1
|
||||
@ -952,7 +952,7 @@ def next(data, state: StrategyState):
|
||||
#HLAVNI ITERACNI LOG JESTE PRED AKCI - obsahuje aktualni hodnoty vetsiny parametru
|
||||
#lp = state.interface.get_last_price(symbol=state.symbol)
|
||||
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()))
|
||||
|
||||
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}")
|
||||
|
||||
|
||||
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
|
||||
class Trade(BaseModel):
|
||||
symbol: str
|
||||
|
||||
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
from v2realbot.enums.enums import RecordType, StartBarAlign
|
||||
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.requests import MarketOrderRequest, TakeProfitRequest, LimitOrderRequest, ReplaceOrderRequest, GetOrdersRequest
|
||||
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 v2realbot.config import Keys
|
||||
from v2realbot.interfaces.general_interface import GeneralInterface
|
||||
from traceback import format_exc
|
||||
"""""
|
||||
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)
|
||||
self.avgp, self.poz = float(a.avg_entry_price), int(a.qty)
|
||||
return a.avg_entry_price, a.qty
|
||||
except APIError as e:
|
||||
except (APIError, Exception) as e:
|
||||
#no position
|
||||
if e.code == 40410000: return 0,0
|
||||
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)
|
||||
return -1
|
||||
return -1,-1
|
||||
|
||||
"""get open orders ->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://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script> -->
|
||||
<script src="/static/js/fast-toml.js" type="text/javascript"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="main" class="mainConteiner flex-container content">
|
||||
@ -503,6 +504,38 @@
|
||||
</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">
|
||||
<label data-bs-toggle="collapse" data-bs-target="#configInner" aria-expanded="true">
|
||||
<h4>Config</h4>
|
||||
@ -523,5 +556,6 @@
|
||||
<script src="/static/js/livewebsocket.js"></script>
|
||||
<script src="/static/js/realtimechart.js"></script>
|
||||
<script src="/static/js/mytables.js"></script>
|
||||
<script src="/static/js/testlist.js"></script>
|
||||
</body>
|
||||
</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: "slopeNEW", titlevisible: true, embed: true, display: false, 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: "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: "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},
|
||||
|
||||
@ -397,3 +397,80 @@ pre {
|
||||
'GRAD' 0,
|
||||
'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")
|
||||
#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)
|
||||
self.state.vars.limitka = 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
|
||||
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)
|
||||
@ -125,11 +130,13 @@ class StrategyOrderLimitVykladaciNormalizedMYSELL(Strategy):
|
||||
if order != -1:
|
||||
print("ukladame pendingbuys")
|
||||
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.vars.lastbuyindex = self.state.bars['index'][-1]
|
||||
#ic(self.state.blockbuy)
|
||||
#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:
|
||||
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"""
|
||||
def refresh_positions(self, item):
|
||||
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:
|
||||
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"""
|
||||
def update_times(self, item):
|
||||
|
||||
Binary file not shown.
@ -9,7 +9,7 @@ import decimal
|
||||
from v2realbot.enums.enums import RecordType, Mode, StartBarAlign
|
||||
import pickle
|
||||
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
|
||||
import tomli
|
||||
from v2realbot.config import DATA_DIR, QUIET_MODE,NORMALIZED_TICK_BASE_PRICE
|
||||
@ -23,6 +23,33 @@ import numpy as np
|
||||
import pandas as pd
|
||||
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):
|
||||
"""
|
||||
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
|
||||
group eval rules. 1. single 2. AND 3. ORS
|
||||
"""
|
||||
msg = ""
|
||||
ret = False
|
||||
#eval single cond
|
||||
for klic in cond:
|
||||
if klic in ["AND","OR"]: continue
|
||||
else:
|
||||
if cond[klic]:
|
||||
return True, klic
|
||||
msg = {}
|
||||
ret = []
|
||||
|
||||
##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"]:
|
||||
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]:
|
||||
ret = True
|
||||
msg += key + " AND "
|
||||
else:
|
||||
ret = False
|
||||
break
|
||||
if ret:
|
||||
if all(ret):
|
||||
return True, msg
|
||||
#eval OR groups
|
||||
if "OR" in cond.keys():
|
||||
for key in cond["OR"]:
|
||||
if cond["OR"][key]:
|
||||
return True, key
|
||||
|
||||
return False, None
|
||||
#eval OR groups
|
||||
if "OR" in cond.keys() and len(cond["OR"])>0:
|
||||
ret = []
|
||||
msg["OR"] = {}
|
||||
for key in cond["OR"]:
|
||||
res = cond["OR"][key]
|
||||
ret.append(res)
|
||||
msg["OR"][key] = (str(res).upper() if res else str(res))
|
||||
#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):
|
||||
return sum(lst) / len(lst)
|
||||
@ -132,6 +172,8 @@ def json_serial(obj):
|
||||
return obj.__dict__
|
||||
if type(obj) is RunArchiveDetail:
|
||||
return obj.__dict__
|
||||
if type(obj) is Intervals:
|
||||
return obj.__dict__
|
||||
|
||||
raise TypeError (str(obj)+"Type %s not serializable" % type(obj))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user