272 lines
9.9 KiB
Python
272 lines
9.9 KiB
Python
import os
|
||
import asyncio
|
||
from flextrade.flextrade_client import Client
|
||
from flextrade.constants.markets import BASE_MARKET_ETH_USD, BASE_MARKET_SOL_USD
|
||
from flextrade.constants.common import ADDRESS_ZERO
|
||
from flextrade.enum import Action
|
||
from dotenv import load_dotenv
|
||
|
||
load_dotenv()
|
||
|
||
RPC_URL = os.getenv("RPC_URL")
|
||
PRIVATE_KEY = os.getenv("PRIVATE_KEY")
|
||
|
||
|
||
def create_market_order(account_id, market, action, size, is_reduce_only=False, referral_code=ADDRESS_ZERO):
|
||
"""
|
||
Create a market order synchronously
|
||
|
||
Args:
|
||
account_id (int): Account ID to trade with
|
||
market (str): Market to trade (e.g., BASE_MARKET_ETH_USD)
|
||
action (Action): Action.BUY or Action.SELL
|
||
size (float): Order size
|
||
is_reduce_only (bool): Whether this is a reduce-only order
|
||
referral_code (str): Referral code address
|
||
|
||
Returns:
|
||
dict: Order result with transaction hash
|
||
"""
|
||
try:
|
||
client = Client(
|
||
eth_private_key=PRIVATE_KEY,
|
||
rpc_url=RPC_URL
|
||
)
|
||
|
||
result = client.private.create_market_order(
|
||
account_id, market, action, size, is_reduce_only, referral_code
|
||
)
|
||
|
||
# Safe action name handling
|
||
action_name = action.name if hasattr(action, 'name') else ('BUY' if action else 'SELL')
|
||
print(f'Market order created - Market: {market}, Action: {action_name}, Size: {size}')
|
||
print(f'Transaction hash: {result["tx"].hex()}')
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"Error creating market order: {e}")
|
||
return None
|
||
|
||
|
||
def create_trigger_order(account_id, market, action, size, trigger_price, trigger_above=True, is_reduce_only=False):
|
||
"""
|
||
Create a trigger order synchronously
|
||
|
||
Args:
|
||
account_id (int): Account ID to trade with
|
||
market (str): Market to trade (e.g., BASE_MARKET_ETH_USD)
|
||
action (Action): Action.BUY or Action.SELL
|
||
size (float): Order size
|
||
trigger_price (float): Price at which the order should trigger
|
||
trigger_above (bool): True to trigger when price goes above, False for below
|
||
is_reduce_only (bool): Whether this is a reduce-only order
|
||
|
||
Returns:
|
||
dict: Order result with transaction hash and order details
|
||
"""
|
||
try:
|
||
client = Client(
|
||
eth_private_key=PRIVATE_KEY,
|
||
rpc_url=RPC_URL
|
||
)
|
||
|
||
result = client.private.create_trigger_order(
|
||
account_id, market, action, size, trigger_price, trigger_above, is_reduce_only
|
||
)
|
||
|
||
trigger_direction = "above" if trigger_above else "below"
|
||
action_name = action.name if hasattr(action, 'name') else ('BUY' if action else 'SELL')
|
||
print(f'Trigger order created - Market: {market}, Action: {action_name}, Size: {size}')
|
||
print(f'Trigger: {trigger_direction} ${trigger_price:.2f}')
|
||
print(f'Transaction hash: {result["tx"].hex()}')
|
||
print(f'Order ID: {result["order"]["orderIndex"]}')
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"Error creating trigger order: {e}")
|
||
return None
|
||
|
||
|
||
def update_trigger_order(account_id, order_id, action, size, trigger_price, trigger_above=True, is_reduce_only=False, referral_code=ADDRESS_ZERO):
|
||
"""
|
||
Update an existing trigger order synchronously
|
||
|
||
Args:
|
||
account_id (int): Account ID
|
||
order_id (int): Order ID to update
|
||
action (Action): Action.BUY or Action.SELL
|
||
size (float): New order size
|
||
trigger_price (float): New trigger price
|
||
trigger_above (bool): True to trigger when price goes above, False for below
|
||
is_reduce_only (bool): Whether this is a reduce-only order
|
||
referral_code (str): Referral code address
|
||
|
||
Returns:
|
||
dict: Updated order result with transaction hash
|
||
"""
|
||
try:
|
||
client = Client(
|
||
eth_private_key=PRIVATE_KEY,
|
||
rpc_url=RPC_URL
|
||
)
|
||
|
||
result = client.private.update_trigger_order(
|
||
account_id, order_id, action, size, trigger_price, trigger_above, is_reduce_only, referral_code
|
||
)
|
||
|
||
trigger_direction = "above" if trigger_above else "below"
|
||
action_name = action.name if hasattr(action, 'name') else ('BUY' if action else 'SELL')
|
||
print(f'Trigger order updated - Order ID: {order_id}, Action: {action_name}, Size: {size}')
|
||
print(f'New trigger: {trigger_direction} ${trigger_price:.2f}')
|
||
print(f'Transaction hash: {result["tx"].hex()}')
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"Error updating trigger order: {e}")
|
||
return None
|
||
|
||
|
||
def cancel_trigger_order(account_id, market, order_id):
|
||
"""
|
||
Cancel an existing trigger order synchronously
|
||
|
||
Args:
|
||
account_id (int): Account ID
|
||
market (str): Market constant
|
||
order_id (int): Order ID to cancel
|
||
|
||
Returns:
|
||
dict: Cancel result with transaction hash
|
||
"""
|
||
try:
|
||
client = Client(
|
||
eth_private_key=PRIVATE_KEY,
|
||
rpc_url=RPC_URL
|
||
)
|
||
|
||
result = client.private.cancel_trigger_order(
|
||
account_id, market, order_id
|
||
)
|
||
|
||
print(f'Trigger order cancelled - Order ID: {order_id}')
|
||
print(f'Transaction hash: {result["tx"].hex()}')
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"Error cancelling trigger order: {e}")
|
||
return None
|
||
|
||
|
||
def list_trigger_orders(account_id, market):
|
||
"""
|
||
List all trigger orders for a specific account and market
|
||
|
||
Args:
|
||
account_id (int): Account ID to get orders for
|
||
market (str): Market to get orders for (e.g., BASE_MARKET_ETH_USD)
|
||
|
||
Returns:
|
||
list: List of trigger orders with their details, or empty list if method not available
|
||
"""
|
||
try:
|
||
client = Client(
|
||
eth_private_key=PRIVATE_KEY,
|
||
rpc_url=RPC_URL
|
||
)
|
||
|
||
# Check if the method exists before calling it
|
||
if not hasattr(client.private, 'get_all_orders'):
|
||
print(f'⚠️ get_all_orders method not available in FlexTrade SDK')
|
||
print(f'ℹ️ Cannot list existing trigger orders - this is expected with some SDK versions')
|
||
return []
|
||
|
||
orders = client.private.get_all_orders(account_id, market)
|
||
|
||
if orders:
|
||
print(f'Found {len(orders)} trigger orders for account {account_id} in market {market}:')
|
||
for i, order in enumerate(orders, 1):
|
||
order_id = order.get('orderIndex', 'N/A')
|
||
action = order.get('action', 'N/A')
|
||
size = order.get('size', 'N/A')
|
||
trigger_price = order.get('triggerPrice', 'N/A')
|
||
trigger_above = order.get('triggerAbove', 'N/A')
|
||
is_reduce_only = order.get('isReduceOnly', 'N/A')
|
||
|
||
print(f' {i}. Order ID: {order_id}')
|
||
print(f' Action: {action}')
|
||
print(f' Size: {size}')
|
||
print(f' Trigger Price: ${trigger_price}')
|
||
print(f' Trigger Above: {trigger_above}')
|
||
print(f' Reduce Only: {is_reduce_only}')
|
||
print()
|
||
else:
|
||
print(f'No trigger orders found for account {account_id} in market {market}')
|
||
|
||
return orders if orders else []
|
||
|
||
except AttributeError as e:
|
||
print(f"⚠️ Method not available in FlexTrade SDK: {e}")
|
||
print(f"ℹ️ Skipping trigger order listing - continuing with position check")
|
||
return []
|
||
except Exception as e:
|
||
print(f"❌ Error listing trigger orders: {e}")
|
||
return []
|
||
|
||
|
||
async def main():
|
||
client = Client(
|
||
eth_private_key=PRIVATE_KEY,
|
||
rpc_url=RPC_URL
|
||
)
|
||
# create_market_order = client.private.create_market_order(
|
||
# 0, BASE_MARKET_ETH_USD, Action.BUY, 10, False, ADDRESS_ZERO
|
||
# )
|
||
# print(f'Create market ETH/USD order tx: {create_market_order["tx"].hex()}\n')
|
||
# await asyncio.sleep(8)
|
||
|
||
# create_order = client.private.create_trigger_order(
|
||
# 0, BASE_MARKET_ETH_USD, Action.BUY, 20, 3000, True, False)
|
||
# print(f'Create ETH/USD order tx: {create_order["tx"].hex()} id: {create_order["order"]["orderIndex"]}\n')
|
||
# await asyncio.sleep(8)
|
||
|
||
# update_order = client.private.update_trigger_order(
|
||
# 0, create_order["order"]["orderIndex"], Action.SELL, 5, 2700, True, False, ADDRESS_ZERO)
|
||
# print(f'Update ETH/USD order tx: {update_order["tx"].hex()} id: {update_order["order"]["orderIndex"]}\n')
|
||
# await asyncio.sleep(20)
|
||
|
||
# cancel_order = client.private.cancel_trigger_order(
|
||
# 0, BASE_MARKET_ETH_USD, update_order["order"]["orderIndex"])
|
||
# print(f'Cancel ETH/USD order tx: {cancel_order["tx"].hex()} id: {cancel_order["order"]["orderIndex"]}\n')
|
||
# await asyncio.sleep(8)
|
||
|
||
# # SOL
|
||
# create_market_order = client.private.create_market_order(
|
||
# 0, BASE_MARKET_SOL_USD, Action.BUY, 10, False, ADDRESS_ZERO
|
||
# )
|
||
# print(f'Create market SOL/USD order tx: {create_market_order["tx"].hex()}\n')
|
||
# await asyncio.sleep(8)
|
||
|
||
list_orders = client.private.get_all_orders(1, BASE_MARKET_SOL_USD)
|
||
|
||
create_order = client.private.create_trigger_order(
|
||
1, BASE_MARKET_SOL_USD, Action.BUY, 20, 3000, True, False)
|
||
print(f'Create SOL/USD order tx: {create_order["tx"].hex()} id: {create_order["order"]["orderIndex"]}\n')
|
||
await asyncio.sleep(8)
|
||
|
||
update_order = client.private.update_trigger_order(
|
||
1, create_order["order"]["orderIndex"], Action.SELL, 5, 2700, True, False, ADDRESS_ZERO)
|
||
print(f'Update SOL/USD order tx: {update_order["tx"].hex()} id: {update_order["order"]["orderIndex"]}\n')
|
||
await asyncio.sleep(20)
|
||
|
||
cancel_order = client.private.cancel_trigger_order(
|
||
1, BASE_MARKET_SOL_USD, update_order["order"]["orderIndex"])
|
||
print(f'Cancel SOL/USD order tx: {cancel_order["tx"].hex()} id: {cancel_order["order"]["orderIndex"]}\n')
|
||
await asyncio.sleep(8)
|
||
|
||
if __name__ == '__main__':
|
||
asyncio.run(main())
|