Easy profits to be made for those who wish to come and support the project.
Below I have given a small breakdown of some of the parts of the codebase I thought this might peak some interest.
This code defines a function called parse_message that parses incoming messages for a subscription-based data stream.
The function updates global dictionaries called dicts and offsets based on the message contents.
The customSort function is used to sort a list of dictionaries by their price value.
def parse_message(msg_):
global dicts, offsets
if msg_["type"] == "subscribed":
for side, data in msg_['contents'].items():
for entry in data:
size = Decimal(entry['size'])
if size > 0:
price = Decimal(entry['price'])
dicts[str(side)][price] = size
offset = Decimal(entry["offset"])
offsets[price] = offset
if msg_["type"] == "channel_data":
#parse updates
for side, data in msg_['contents'].items():
if side == 'offset':
offset = int(data)
continue
else:
for entry in data:
price = Decimal(entry[0])
amount = Decimal(entry[1])
if price in offsets and offset <= offsets[price]:
continue
offsets[price] = offset
if amount == 0:
if price in dicts[side]:
del dicts[side][price]
else:
try:
dicts[side].append((price, amount))
except AttributeError:
dicts[side][price] = amount
def customSort(k):
return float(k['price'])
def postGrid This code defines a function called postGrid that is used to post grid orders for the trading algorithm.
The function takes a single argument, side, which determines whether to post a long or short grid.
The function first declares and initializes several local variables.
These variables are used to calculate the order size, mid-price, and price step for the grid orders.
Then, the function loops through tp_gridOrderCount number of times to post limit orders for the grid.
For each iteration, the function calculates the order price based on the mid-price and price step,
and creates an order using the private_client.private.create_order method provided by a third-party library.
If the order creation is successful, the order data is appended to the dicts['grid'] list.
If the order creation is unsuccessful, the function prints the error message and waits for 1.5 seconds before retrying.
If the retry is successful, the function continues with the next iteration. If the retry is unsuccessful, the function skips that iteration.
Finally, the function sets isGridPosted to True and prints a message indicating whether a long or short grid was posted.
In summary, this code defines a function that posts grid orders for a trading algorithm,
which involves creating a series of limit orders based on a specified order count, order size, and price step.
def postGrid(side):
global isGridPosted, positionSize, best_ask, best_bid
try:
orderSize = abs(positionSize) / tp_gridOrderCount
midPrice = float(best_bid + best_ask) / 2
priceStep = midPrice * pct_gridTotalDistance / tp_gridOrderCount * -1
orderSide = ORDER_SIDE_BUY
if side == 'short':
orderSide = ORDER_SIDE_SELL
priceStep = priceStep * -1
for x in range(tp_gridOrderCount):
orderPrice = midPrice + priceStep + priceStep * x
order_params = {'position_id': position_id, 'market': security_name, 'side': orderSide,
'order_type': ORDER_TYPE_LIMIT, 'post_only': True, 'size': str(round(max(minOrderSize, orderSize),rounding_size_decimal)),
'price': str(round(orderPrice,rounding_price_decimal)), 'limit_fee': '0.002',
'expiration_epoch_seconds': time.time()*3}
try:
dicts['grid'].append(private_client.private.create_order(**order_params).data)
except Exception as e:
print(e)
x = x - 1
time.sleep(1.5)
except Exception as e:
print(e)
isGridPosted = True
if side == 'short':
print('post short grid')
elif side == 'long':
print('post long grid')
ef cancelGrid This code defines a function cancelGrid which cancels grid orders for a trading algorithm.
The function loops through the dicts['grid'] list and cancels each order using the private_client.private.cancel_order method.
If the order is successfully cancelled, the order data is removed from dicts['grid'] and if there is any error, the error message is printed.
Finally, the function sets isGridPosted to False and prints a message indicating that the grid has been canceled.
def cancelGrid():
global isGridPosted
for x in dicts['grid']:
try:
private_client.private.cancel_order(order_id=str(x['order']['id']))
except Exception as e:
print(e)
del dicts['grid'][0]
isGridPosted = False
print('canceled grid')
his code defines a function run_script that retrieves information about the current position of a security and establishes a
WebSocket connection to retrieve real-time data by setting up a subscription message for an order book channel.
The function first declares two global variables and then uses the private_client.private.get_positions method to retrieve information about all open positions.
The function then defines an inner function called on_open to handle WebSocket connection events, and ends without returning anything.
def run_script():
global positionSize, count
all_positions = private_client.private.get_positions(
market=security_name,
status=POSITION_STATUS_OPEN,
)
if len(all_positions.data["positions"]) > 0:
positionSize = float(all_positions.data["positions"][0]["size"])
if positionSize is None :
positionSize = 0
else:
positionSize = 0
def on_open(ws):
print("Websocked Connected - Fetching Best Bid / Best Ask")
channel_data = { "type": "subscribe", "channel": "v3_orderbook", "id": str(security_name), "includeOffsets": "True"}
ws.send(json.dumps(channel_data))
This code defines a function hot_path that executes the main algorithm for a trading bot.
The function defines several global variables and then enters an infinite loop that executes a series of tasks based on a timer.
Within the loop, the function checks the current bid and ask prices, cancels open orders, calculates and submits new orders, and executes take-profit and stop-loss actions.
The function also checks for inverse orderbook conditions and restarts the WebSocket connection if necessary. The function ends without returning anything.
def hot_path(message):
global dicts, count, bid_order_id, ask_order_id, position_balance_id, position_id, positionSize,oldPositionSize, entryPrice, maxPositionSizeThreshold, best_bid, best_ask, unrealizedPnl
try:
print(str(count) + ' bid: ' + str(best_bid) , end="\r")
best_bid = max(dicts["bids"].keys())
best_ask = min(dicts["asks"].keys())
#####################################
## Check For Any Inverse Orderbook ##
#####################################
if best_bid >= best_ask:
print("INVERSE CONDITIONS DETECTED - RESTARTING")
ws.close()
print("closed")
dicts['bids'] = {}
dicts['asks'] = {}
offsets = {}
run_script()
This code block is a part of a larger trading algorithm and is responsible for monitoring the position's unrealized profit or loss
to determine if it has reached certain profit or loss thresholds. If it has, it will place a market order to clear the position.
The code first checks if the current iteration count is a multiple of 150.
If it is, it retrieves the current open position, calculates the current position size, entry price, unrealized profit/loss,
and determines if the current unrealized profit is greater than the take profit threshold or if the current unrealized loss is greater than the stop loss threshold.
If either of these conditions is met, a market order to clear the position is placed.
If the iteration count exceeds 50,000, the code will close the WebSocket connection and restart the algorithm.
elif count %150== 0:
try:
if position_balance_id != 0:
try:
print('Take profit and stop loss')
private_client.private.cancel_order(order_id=str(position_balance_id))
except Exception as e:
print(e)
position_balance_id = 0
all_positions = private_client.private.get_positions(
market=security_name,
status=POSITION_STATUS_OPEN,
)
if len(all_positions.data["positions"]) > 0 and float(all_positions.data["positions"][0]["size"]) is not None:
oldPositionSize = positionSize
positionSize = float(all_positions.data["positions"][0]["size"])
absPositionSize = abs(positionSize)
entryPrice = float(all_positions.data["positions"][0]["entryPrice"])
unrealizedPnl = float(all_positions.data["positions"][0]["unrealizedPnl"])
wantedProfit = entryPrice * absPositionSize * pct_takeProfit
maxLoss = entryPrice * absPositionSize * pct_stopLoss * -1
inProfit = unrealizedPnl > wantedProfit
inStop = unrealizedPnl < maxLoss
print(f'{count} positionSize {positionSize} absPositionSize {absPositionSize} entryPrice {entryPrice} wantedProfit {wantedProfit} unrealizedPnl {unrealizedPnl} inProfit {inProfit} inStop {inStop}')