Skip to content

Commit

Permalink
Order updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlos Wu Fei authored and Carlos Wu Fei committed Jan 2, 2024
1 parent 5ce5db3 commit 2ae01c9
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 109 deletions.
1 change: 1 addition & 0 deletions api/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mypy = "*"
pytest = "*"
unittest = "*"
httpx = "*"
mongomock = "*"

[requires]
python_version = "3.10.8"
Expand Down
2 changes: 1 addition & 1 deletion api/account/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ def get_market_domination(self, size=7):
{ "$query": {}, "$orderby": { "_id" : -1 } }
).limit(size))
market_domination_series = MarketDominationSeries()

for item in data:
gainers_percent = 0
losers_percent = 0
Expand Down
56 changes: 0 additions & 56 deletions api/account/test_assets.py

This file was deleted.

90 changes: 41 additions & 49 deletions api/streaming/streaming_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,54 +167,50 @@ def get_klines(self):
logging.info(f"Streaming updates: {markets}")
self.client.klines(markets=markets, interval=interval)

def close_trailling_orders(self, result, db_collection: str = "bots"):
def update_order_data(self, result, db_collection: str = "bots"):
"""
This database query closes any orders found that are trailling orders i.e.
stop_loss, take_profit, trailling_profit, margin_short_stop_loss, margin_short_trailling_profit
the two latter also denoted as stop_loss and take_profit for simplification purposes
Keep order data up to date
If no order is found with the given order_id, then try with the paper_trading collection
as it could be a test bot
When buy_order or sell_order is executed, they are often in
status NEW, and it takes time to update to FILLED.
This keeps order data up to date as they are executed
throught the executionReport websocket
Args:
result (dict): executionReport websocket result
db_collection (str, optional): Defaults to "bots".
Finally, if paper_trading doesn't match that order_id either, then try any order in the DB
"""
order_id = result["i"]
# Close successful take_profit
update = {
"$set": {
"orders.$.status": result["X"],
"orders.$.qty": result["q"],
"orders.$.order_side": result["S"],
"orders.$.order_type": result["o"],
"orders.$.timestamp": result["T"],
},
"$inc": {"total_commission": float(result["n"])},
"$push": {"errors": "Order status updated"},
}
if float(result["p"]) > 0:
update["$set"]["orders.$.price"] = float(result["p"])
else:
total_qty = 0
weighted_avg = 0
for item in result["fills"]:
weighted_avg += float(item["price"]) * float(item["qty"])
total_qty += float(item["qty"])

weighted_avg_price = weighted_avg / total_qty
result["p"] = weighted_avg_price

query = self.streaming_db[db_collection].update_one(
{"orders": {"$elemMatch": {"order_id": order_id}}},
{
"$set": {
"orders.$.status": result["X"],
"orders.$.price": result["p"] if result["p"] else result["p"],
"orders.$.qty": result["q"],
"orders.$.order_side": result["S"],
"orders.$.order_type": result["o"],
"orders.$.timestamp": result["T"],
},
"$inc": {"total_commission": float(result["n"])},
"$push": {"errors": "Bot completed!"},
},
update,
)
return query

def process_user_data(self, result):
# Parse result. Print result for raw result from Binance
order_id = result["i"]
# Example of real update
# {'e': 'executionReport', 'E': 1676750256695, 's': 'UNFIUSDT', 'c': 'web_86e55fed9bad494fba5e213dbe5b2cfc', 'S': 'SELL', 'o': 'LIMIT', 'f': 'GTC', 'q': '8.20000000', 'p': '6.23700000', 'P': '0.00000000', 'F': '0.00000000', 'g': -1, 'C': 'KrHPY4jWdWwFBHUMtBBfJl', 'x': 'CANCELED', ...}
query = self.close_trailling_orders(result)
logging.debug(f'Order updates modified: {query.raw_result["nModified"]}')
if query.raw_result["nModified"] == 0:
# Order not found in bots, so try paper_trading collection
query = self.close_trailling_orders(result, db_collection="paper_trading")
logging.debug(f'Order updates modified: {query.raw_result["nModified"]}')
if query.raw_result["nModified"] == 0:
logging.debug(
f"No bot found with order client order id: {order_id}. Order status: {result['X']}"
)
return
return

def get_user_data(self):
listen_key = self.get_listen_key()
self.user_data_client = SpotWebsocketStreamClient(
Expand All @@ -226,20 +222,16 @@ def on_user_data_message(self, socket, message):
logging.info("Streaming user data")
res = json.loads(message)

if "result" in res and res["result"]:
logging.info(f'Subscriptions: {res["result"]}')

# if "data" in res:
# if "e" in res["data"] and res["data"]["e"] == "kline":
# self.process_klines(res["data"])
# self.process_user_data(res["data"])
# else:
# logging.error(f'Error: {res["data"]}')
# self.client.stop()
if "e" in res:
if "executionReport" in res["e"]:
logging.info(f'executionReport {res}')
self.process_user_data(res)
query = self.update_order_data(res)
if query.raw_result["nModified"] == 0:
logging.debug(
f'No bot found with order client order id: {res["i"]}. Order status: {res["X"]}'
)
return

elif "outboundAccountPosition" in res["e"]:
logging.info(f'Assets changed {res["e"]}')
elif "balanceUpdate" in res["e"]:
Expand Down
72 changes: 72 additions & 0 deletions api/tests/test_assets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from account.assets import Assets
from main import app
from db import setup_db

import mongomock

test_client = mongomock.MongoClient()

async def get_test_client():
return test_client

app.dependency_overrides[setup_db] = get_test_client

class TestAccount:

def __init__(self) -> None:
self.db = test_client["bots"]["market_domination"]
pass

def test_get_market_domination(self):
# Mock the database and its find method
data = [
{
"data": [
{"priceChangePercent": "0.5"},
{"priceChangePercent": "-0.3"},
{"priceChangePercent": "0.2"},
{"priceChangePercent": "-0.1"},
],
"time": "2022-01-01",
},
{
"data": [
{"priceChangePercent": "0.1"},
{"priceChangePercent": "-0.2"},
{"priceChangePercent": "0.3"},
{"priceChangePercent": "-0.4"},
],
"time": "2022-01-02",
},
{
"data": [
{"priceChangePercent": "0.4"},
{"priceChangePercent": "-0.5"},
{"priceChangePercent": "0.6"},
{"priceChangePercent": "-0.7"},
],
"time": "2022-01-03",
},
]

self.db.insert_one(data)

# Create an instance of AccountAssets and set the mock database
assets = Assets()

# Call the get_market_domination method
result = assets.get_market_domination()

# Assert the expected result
expected_result = {
"data": {
"dates": ["2022-01-01", "2022-01-02", "2022-01-03"],
"gainers_percent": [0.5, 0.1, 0.4],
"losers_percent": [0.3, 0.2, 0.5],
"gainers_count": 3,
"losers_count": 3,
},
"message": "Successfully retrieved market domination data.",
"error": 0,
}
assert result == expected_result
4 changes: 2 additions & 2 deletions web/src/pages/dashboard/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ class Dashboard extends React.Component {
</div>
</Col>
<Col lg="9">
{this.props.benchmarkData.dates?.btc && (
{this.props.benchmarkData?.dates && (
<PortfolioBenchmarkChart
data={this.props.benchmarkData}
legend={this.state.lineChartLegend}
Expand Down Expand Up @@ -398,13 +398,13 @@ const mapStateToProps = (s) => {
const { data: balance_raw } = s.balanceRawReducer;
const { data: gainersLosersData } = s.gainersLosersReducer;
const { data: gainersLosersSeries } = s.gainersLosersSeriesReducer;

const {
data: benchmarkData,
btcPrices,
usdtBalanceSeries,
dates,
} = s.btcBenchmarkReducer;

let percentageRevenue = 0;
let revenue = 0;

Expand Down
2 changes: 1 addition & 1 deletion web/src/pages/dashboard/saga.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function* watchGetGainersLosers() {
}

export function* getGainersLosersSeriesApi() {
const requestURL = `${process.env.REACT_APP_GAINERS_LOSERS_SERIES}?size=7`;
const requestURL = `${process.env.REACT_APP_GAINERS_LOSERS_SERIES}?size=14`;
try {
const res = yield call(request, requestURL, "GET");
yield put(getGainersLosersSeriesSucceeded(res));
Expand Down

0 comments on commit 2ae01c9

Please sign in to comment.