Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ examples/secrets.py

# Environment variables
.env
.env.*
.env.*
api_key_config.json
1 change: 1 addition & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
api_key_config.json
49 changes: 37 additions & 12 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,43 @@
- this will require you to enter your Ethereum private key
- the eth private key will only be used in the Py SDK to sign a message
- the eth private key is not required in order to trade on the platform
- the eth private key is not passed to the binary
- copy the output of the script and post it into `create_cancel_order.py`
- the output should look like
```
BASE_URL = 'https://testnet.zklighter.elliot.ai'
API_KEY_PRIVATE_KEY = '0xea5d2eca5be67eca056752eaf27b173518b8a5550117c09d2b58c7ea7d306cc4426f913ccf27ab19'
ACCOUNT_INDEX = 595
API_KEY_INDEX = 1
```
- start trading using
- `create_cancel_order.py` has an example which created an order on testnet & cancels it
- you'll need to set up both your account index, api key index & API Key private key
- the eth private key is not passed to the binary
- the API key config is saved in a local file `./api_key_config.json`

## Start trading on testnet
- `create_modify_cancel_order.py`
- creates an ask (sell) order for 0.1 ETH @ $4050
- modified the order and increases the size to 0.11 ETH and increases the price to $4100
- cancels the order
- Note: all of these operations use the client order index of the order. You can use the order from the exchange as well

- `ws_send_tx.py`
- same flow as `create_modify_cancel_order.py`
- sends TXs over WS instead of HTTP

- `create_grouped_ioc_with_attached_sl_tp.py`
- creates an ask (sell) IoC order for 0.1 ETH
- along w/ the order, it sets up a Stop Loss (SL) and a Take Profit (TP) order for the whole size of the order
- the size of the SL/TP will be equal to the executed size of the order
- the SL/TP orders are canceled when the sign of your position changes

- `create_position_tied_sl_tl.py`
- creates a bid (buy) Stop Loss (SL) and a Take Profit (TP) to close your short position
- the size of the orders will be for your whole position (because BaseAmount=0)
- the orders will grow / shrink as you accumulate more position
- the SL/TP orders are canceled when the sign of your position changes

### On SL/TP orders
SL/TP orders need to be configured beyond just setting the trigger price. When the trigger price is set,
the order will just be executed, like a normal order. This means that a market order, for example, might not have enough slippage! \
Let's say that you have a 1 BTC long position, and the current price is $110'000. \
You want to set up a take profit at $120'000
- order should be an ask (sell) order, to close your position
- the trigger price should be $120'000

What about the order types? Just as normal orders, SL/TP orders trigger an order, which can be:
- market order
- limit IOC / GTC

## Setup steps for mainnet
- deposit money on Lighter to create an account first
Expand Down
70 changes: 0 additions & 70 deletions examples/create_cancel_order.py

This file was deleted.

61 changes: 61 additions & 0 deletions examples/create_grouped_ioc_with_attached_sl_tp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import asyncio
import lighter
from lighter.signer_client import CreateOrderTxReq
from utils import default_example_setup


async def main():
client, api_client, _ = default_example_setup()

ioc_order = CreateOrderTxReq(
MarketIndex=0,
ClientOrderIndex=0,
BaseAmount=1000, # 0.1 ETH
Price=300000, # $3000
IsAsk=1, # sell
Type=lighter.SignerClient.ORDER_TYPE_LIMIT,
TimeInForce=lighter.SignerClient.ORDER_TIME_IN_FORCE_IMMEDIATE_OR_CANCEL,
ReduceOnly=0,
TriggerPrice=0,
OrderExpiry=0,
)

# Create a One-Cancels-the-Other grouped order with a take-profit and a stop-loss order
take_profit_order = CreateOrderTxReq(
MarketIndex=0,
ClientOrderIndex=0,
BaseAmount=0,
Price=300000,
IsAsk=0,
Type=lighter.SignerClient.ORDER_TYPE_TAKE_PROFIT_LIMIT,
TimeInForce=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
ReduceOnly=1,
TriggerPrice=300000,
OrderExpiry=-1,
)

stop_loss_order = CreateOrderTxReq(
MarketIndex=0,
ClientOrderIndex=0,
BaseAmount=0,
Price=500000,
IsAsk=0,
Type=lighter.SignerClient.ORDER_TYPE_STOP_LOSS_LIMIT,
TimeInForce=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
ReduceOnly=1,
TriggerPrice=500000,
OrderExpiry=-1,
)

transaction = await client.create_grouped_orders(
grouping_type=lighter.SignerClient.GROUPING_TYPE_ONE_TRIGGERS_A_ONE_CANCELS_THE_OTHER,
orders=[ioc_order, take_profit_order, stop_loss_order],
)

print("Create Grouped Order Tx:", transaction)

await client.close()
await api_client.close()

if __name__ == "__main__":
asyncio.run(main())
31 changes: 8 additions & 23 deletions examples/create_market_order.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
import asyncio
import logging
import lighter

logging.basicConfig(level=logging.DEBUG)

# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
# It was generated using the setup_system.py script, and serves as an example.
BASE_URL = "https://testnet.zklighter.elliot.ai"
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
ACCOUNT_INDEX = 65
API_KEY_INDEX = 3


def trim_exception(e: Exception) -> str:
return str(e).strip().split("\n")[-1]
from utils import default_example_setup


async def main():
client = lighter.SignerClient(
url=BASE_URL,
private_key=API_KEY_PRIVATE_KEY,
account_index=ACCOUNT_INDEX,
api_key_index=API_KEY_INDEX,
)
client, api_client, _ = default_example_setup()

tx = await client.create_market_order(
tx, tx_hash, err = await client.create_market_order(
market_index=0,
client_order_index=0,
base_amount=1000, # 0.1 ETH
avg_execution_price=170000, # $1700 -- worst acceptable price for the order
is_ask=True,
)
print("Create Order Tx:", tx)
print(f"Create Order {tx=} {tx_hash=} {err=}")
if err is not None:
raise Exception(err)

await client.close()
await api_client.close()


if __name__ == "__main__":
Expand Down
34 changes: 11 additions & 23 deletions examples/create_market_order_max_slippage.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
import asyncio
import logging
import lighter

logging.basicConfig(level=logging.DEBUG)

# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
# It was generated using the setup_system.py script, and serves as an example.
BASE_URL = "https://testnet.zklighter.elliot.ai"
API_KEY_PRIVATE_KEY = "0xe0fa55e11d6b5575d54c0500bd2f3b240221ae90241e3b573f2307e27de20c04ea628de3f1936e56"
ACCOUNT_INDEX = 22
API_KEY_INDEX = 3


def trim_exception(e: Exception) -> str:
return str(e).strip().split("\n")[-1]
from utils import default_example_setup


async def main():
client = lighter.SignerClient(
url=BASE_URL,
private_key=API_KEY_PRIVATE_KEY,
account_index=ACCOUNT_INDEX,
api_key_index=API_KEY_INDEX,
)
client, api_client, _ = default_example_setup()

# tx = await client.create_market_order_limited_slippage(market_index=0, client_order_index=0, base_amount=30000000,
# max_slippage=0.001, is_ask=True)
tx = await client.create_market_order_if_slippage(market_index=0, client_order_index=0, base_amount=30000000,
max_slippage=0.01, is_ask=True, ideal_price=300000)
tx = await client.create_market_order_if_slippage(
market_index=0, # ETH
client_order_index=0,
base_amount=1000, # 0.1 ETH
max_slippage=0.01, # 1%
is_ask=True,
ideal_price=300000 # $3000
)

print("Create Order Tx:", tx)
await client.close()

Expand Down
51 changes: 51 additions & 0 deletions examples/create_modify_cancel_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import asyncio
import lighter
from utils import default_example_setup


async def main():
client, api_client, _ = default_example_setup()

# create order
tx, tx_hash, err = await client.create_order(
market_index=0,
client_order_index=123,
base_amount=1000, # 0.1 ETH
price=405000, # $4050
is_ask=True,
order_type=lighter.SignerClient.ORDER_TYPE_LIMIT,
time_in_force=lighter.SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
reduce_only=False,
trigger_price=0,
)
print(f"Create Order {tx=} {tx_hash=} {err=}")
if err is not None:
raise Exception(err)

# create order
tx, tx_hash, err = await client.modify_order(
market_index=0,
order_index=123,
base_amount=1100, # 0.11 ETH
price=410000, # $4100
trigger_price=0,
)
print(f"Modify Order {tx=} {tx_hash=} {err=}")
if err is not None:
raise Exception(err)

# cancel order
tx, tx_hash, err = await client.cancel_order(
market_index=0,
order_index=123,
)
print(f"Cancel Order {tx=} {tx_hash=} {err=}")
if err is not None:
raise Exception(err)

await client.close()
await api_client.close()


if __name__ == "__main__":
asyncio.run(main())
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
import asyncio
import lighter
import logging

from lighter.signer_client import CreateOrderTxReq
from utils import default_example_setup

logging.basicConfig(level=logging.DEBUG)

# The API_KEY_PRIVATE_KEY provided belongs to a dummy account registered on Testnet.
# It was generated using the setup_system.py script, and serves as an example.
BASE_URL = "https://testnet.zklighter.elliot.ai"
API_KEY_PRIVATE_KEY = "0xed636277f3753b6c0275f7a28c2678a7f3a95655e09deaebec15179b50c5da7f903152e50f594f7b"
ACCOUNT_INDEX = 65
API_KEY_INDEX = 3

async def main():
client = lighter.SignerClient(
url=BASE_URL,
private_key=API_KEY_PRIVATE_KEY,
account_index=ACCOUNT_INDEX,
api_key_index=API_KEY_INDEX,
)
client, api_client, _ = default_example_setup()

# Create a One-Cancels-the-Other grouped order with a take-profit and a stop-loss order
take_profit_order = CreateOrderTxReq(
MarketIndex=0,
ClientOrderIndex=0,
BaseAmount=1000,
BaseAmount=0,
Price=300000,
IsAsk=0,
Type=lighter.SignerClient.ORDER_TYPE_TAKE_PROFIT_LIMIT,
Expand All @@ -38,7 +25,7 @@ async def main():
stop_loss_order = CreateOrderTxReq(
MarketIndex=0,
ClientOrderIndex=0,
BaseAmount=1000,
BaseAmount=0,
Price=500000,
IsAsk=0,
Type=lighter.SignerClient.ORDER_TYPE_STOP_LOSS_LIMIT,
Expand All @@ -55,6 +42,7 @@ async def main():

print("Create Grouped Order Tx:", transaction)
await client.close()
await api_client.close()

if __name__ == "__main__":
asyncio.run(main())
Loading