DAINTRADER Autonomous Trading Agents
Introducing Autonomous Trading Agents! Our platform allows you to create powerful trading agents that automatically execute trades and manage your portfolio on the Solana blockchain.
How It Works
Create an Agent: Start by creating a new trading agent on our platform.
Deposit Funds: Deposit SOL or supported tokens into your agent’s wallet. Only these deposited funds will be used for trading.
Define Trading Strategies: Write custom trading scripts using our provided functions to define your trading strategies.
Schedule Execution: Schedule your scripts to run automatically at specific intervals using cron jobs. Our platform handles the execution based on your cron schedule.
Automatic Trading: Your agent will automatically execute trades and manage your portfolio according to your defined strategies.
Withdraw or Close: Withdraw your funds or close your agent at any time. Closing the agent will automatically redeposit all remaining funds back to your main wallet.
Get started now and unleash the power of autonomous trading on the Solana blockchain!
License
This project is open source but fully proprietary. Contributions are welcome and will be licensed under the same terms.
Disclaimer: The software is provided “as is”, without any warranty.
Usage: Only for triggers on daintrader.com. All rights reserved by Dain, Inc.
For more information, visit daintrader.com.
Example Scripts
No need to import any libraries when using it in your bots!
Make sure to await any async functions, if you do not await all of the async properties of your script then it will close out and your script will not fully execute.
Dynamic Token Rebalancing
const desiredAllocation = {
"TokenA": 0.5,
"TokenB": 0.3,
"TokenC": 0.2
};
async function rebalancePortfolio() {
const walletAssets: WalletAssets = await assets();
const totalBalance = walletAssets.total_in_usd;
for (const token in desiredAllocation) {
const targetBalance = totalBalance * desiredAllocation[token];
const currentBalance = walletAssets.tokens.find(t => t.symbol === token)?.balanceInUSD || 0;
const difference = targetBalance - currentBalance;
if (difference > 0) {
// Buy tokens to reach the desired allocation
await swap("USDC", token, difference, 50);
} else if (difference < 0) {
// Sell tokens to reach the desired allocation
await swap(token, "USDC", Math.abs(difference), 50);
}
}
log("Portfolio rebalanced successfully");
}
await rebalancePortfolio(); Cron Schedule: 0 0 * * *
Price-Based Limit Orders
const tokenSymbol = "SOL";
const targetPrice = 100;
const stopLossPrice = 90;
async function placeLimitOrder() {
const currentPrice: number = await price(tokenSymbol);
if (currentPrice >= targetPrice) {
// Place a sell order when the target price is reached
await swap(tokenSymbol, "USDC", 1, 50);
log(`Sold ${tokenSymbol} at price: ${currentPrice}`);
} else if (currentPrice <= stopLossPrice) {
// Place a sell order when the stop-loss price is reached
await swap(tokenSymbol, "USDC", 1, 50);
log(`Stop-loss triggered. Sold ${tokenSymbol} at price: ${currentPrice}`);
} else {
log(`Current ${tokenSymbol} price: ${currentPrice}. No action taken.`);
}
}
await placeLimitOrder(); Cron Schedule: */30 * * * *
Dollar-Cost Averaging (DCA)
const tokenSymbol = "BTC";
const usdAmount = 100;
async function dcaInvestment() {
const currentPrice: number = await price(tokenSymbol);
const tokenAmount = usdAmount / currentPrice;
await swap("USDC", tokenSymbol, tokenAmount, 50);
log(`Invested ${usdAmount} USD in ${tokenSymbol} at price: ${currentPrice}`);
}
await dcaInvestment(); Cron Schedule: 0 9 * * 1
Webhook Triggers
In addition to scheduling scripts using cron jobs, you can also trigger your trading scripts by sending a webhook request to your agent’s unique webhook URL. When a script is triggered via a webhook, the body of the webhook request is passed to the script through the webhookBody variable.
The webhookBody variable will contain the parsed body of the webhook request. You can access and utilize this data to make decisions or perform specific actions in your trading script.
Here’s an example of how to use the webhookBody in your script:
async function handleWebhook() {
if (webhookBody) {
const action = webhookBody.action;
const amount = webhookBody.amount;
if (action === "buy") {
await swap("USDC", "SOL", amount, 50);
log(`Bought ${amount} SOL based on webhook trigger`);
} else if (action === "sell") {
await swap("SOL", "USDC", amount, 50);
log(`Sold ${amount} SOL based on webhook trigger`);
}
} else {
log("No webhook body found");
}
}
await handleWebhook();Functions
price(token: string): Promise<number>
Fetches the price of a given token.
token: The symbol of the token (e.g., “SOL”).- Returns a promise that resolves to the price of the token as a number.
assets(): Promise<WalletAssets>
Fetches the asset balances of the trigger agent’s wallet.
- Returns a promise that resolves to a
WalletAssetsobject containing the wallet’s asset balances.
The WalletAssets type is defined as follows:
interface WalletAssets {
tokens: FungibleTokenBalanceExpanded[];
nfts: NFTBalance[];
sol: SolBalance;
total_in_usd: number;
}
interface FungibleTokenBalanceExpanded {
balance: number;
balanceInUSD: number;
price_per_token: number;
symbol: string;
name: string;
token: {
address: string;
decimals: number;
image: string;
};
}
interface NFTBalance {
name: string;
symbol: string;
mint: string;
image: string;
}
interface SolBalance {
balance: number;
balanceInUSD: number;
} The WalletAssets object contains the following properties:
tokens: An array ofFungibleTokenBalanceExpandedobjects representing the fungible token balances.nfts: An array ofNFTBalanceobjects representing the non-fungible token (NFT) balances.sol: ASolBalanceobject representing the SOL balance.total_in_usd: The total balance of all assets in USD.
end(): Promise<void>
Ends the trigger agent and redeposits all assets into the main account.
- Returns a promise that resolves when the operation is complete.
swap(fromToken: string, toToken: string, amount: number, slippageBps: number): Promise<string | undefined>
Performs a token swap.
fromToken: The address of the token to swap from.toToken: The address of the token to swap to.amount: The amount of tokens to swap.slippageBps: The allowed slippage in basis points.- Returns a promise that resolves to the transaction signature as a string if successful, or
undefinedif the swap fails.
sendToken(to: string, token: string, amount: number): Promise<string | undefined>
Sends a specified amount of tokens to a recipient.
to: The recipient’s wallet address.token: The address of the token to send.amount: The amount of tokens to send.- Returns a promise that resolves to the transaction signature as a string if successful, or
undefinedif the transaction fails.
sendSol(to: string, amount: number): Promise<string | undefined>
Sends a specified amount of SOL to a recipient.
to: The recipient’s wallet address.amount: The amount of SOL to send.- Returns a promise that resolves to the transaction signature as a string if successful, or
undefinedif the transaction fails.
Persistent Storage
Since the trading scripts run on non-persistent serverless functions, you cannot directly set a variable and expect it to be available the next time the script runs. To overcome this limitation, we provide the getValue and setValue functions for persistent storage.
Note: The stored values are specific to each trigger agent, so different agents will have their own separate storage.
setValue(key: string, value: any): Promise<any>
Sets a key-value pair in persistent storage.
key: The key to store the value under.value: The value to store.- Returns a promise that resolves to the stored value.
getValue(key: string): Promise<any>
Retrieves a value from persistent storage based on the provided key.
key: The key to retrieve the value for.- Returns a promise that resolves to the retrieved value.
Use the setValue function to store values that you want to persist across script executions. You can then retrieve those values using the getValue function in subsequent script runs.
Here’s an example of how to use getValue and setValue:
async function persistantCounter() {
// Store a value
await setValue("counter", 0);
// Retrieve the value
const counter = await getValue("counter");
console.log(counter); // Output: 0
// Increment the counter
await setValue("counter", counter + 1);
}
await persistantCounter();Spawning a Sub Agent
You can spawn a sub agent to search the web and find any information you need. This can be useful for making decisions based on external data or events.
spawn_sub_agent(query: string, responseType: string): Promise<string>
Spawns a sub AI agent that can search the web and find the requested information.
query: The query or question to ask the sub agent.responseType: The expected type of the response. Can be “boolean”, “number”, or “string”.- Returns a promise that resolves to the sub agent’s response as a string.
The response from the sub agent is always a string, but you can specify the expected response type and convert it accordingly in your code:
- Booleans will be in “TRUE” or “FALSE” format.
- Numbers will be in “123” format.
- Strings will be in “hello” format.
Here’s an example of how to use spawn_sub_agent to check if World War 3 has started and sell all your Bitcoin accordingly:
async function checkWorldWarStatus() {
const query = "Has World War 3 started?";
const response = await spawn_sub_agent(query, "boolean");
if (response === "TRUE") {
const bitcoinBalance = await assets().sol.balance;
await swap("BTC", "USDC", bitcoinBalance, 50);
log("World War 3 has started. Sold all Bitcoin.");
} else {
log("World War 3 has not started. Holding Bitcoin.");
}
}
await checkWorldWarStatus();In this example, the script spawns a sub agent to check if World War 3 has started. The sub agent searches the web and returns a boolean response. If the response is “TRUE”, indicating that World War 3 has started, the script retrieves the Bitcoin balance from the wallet and sells all of it for USDC. If the response is “FALSE”, the script logs a message indicating that it is holding Bitcoin.
Remember to handle the response appropriately based on the specified responseType. Convert the string response to the desired type (boolean, number, or string) in your code.