Proof of Idea
Creates a new Signal based Investment Idea within an Investment Strategy. Use the template below to get started.
Strategy Reference
When creating the very first idea in a strategy, please specify a unique reference such as a UUID. This reference is used as a seed to create a truly unique key which is returned in a successful response.
For all subsequent ideas, please use this unique key.
To create a new strategy, simply specify a new reference.
Strategy & Creator Details
General information about your strategy and about you.
Images are included to give a little colour but they can be any dimension according to where you intend for the Ideas to be displayed.
Note: images can be either a url, base64 or an IPFS cid reference (for all images). If the images are not changing, proessing speed and cost will improve if the cid is used.
Wallets (accessWallets)
Wallets that are granted share of token upon creation. These are wallets that should receive access outside of the Subscription process.
Asset (ticker)
The ticker used should be the ticker supported by the brokerage, exchange or pricing provider form which the market price will be requested (and the asset validated). This includes any subtleties such use of hyphens eg. BTC-USDT, BTC/USDT or BTCUSDT
Alternative Tickers
Where there is variation between the pricing provider and the commonly known exchange ticker, providing an alternative ticker can be a helpful for investors consuming your ideas. This is effectively a simple mapping table - the alternative ticker should reflect the same primary asset. For example:
alternativeProviderSymbols: [
{
provider: 'IEX',
symbol: 'MSFT',
},
{
provider: 'IG Group',
symbol: 'UC.D.MSFT.DAILY.IP',
},
],
Pricing
Note that the credentials for the pricing provider will vary between providers. See further details on Pricing.
Create Idea Object
Create the object to be posted.
// Initialize the SDK
const activ = await getActiv();
// Build the Idea object
const newIdea: CI.ICreateIdeaRequest = {
content: {
reference: v4.generateUUID(),
},
strategy: {
reference: '',
name: '',
description: '',
image: {
url: '',
},
externalLink: '',
},
creator: {
company: '',
name: '',
url: '',
companyLogo: {
url: '',
}
},
accessWallets: [
'0x27674...',
'0xaB31A...'
],
idea: {
title: '',
asset: {
alternativeProviderSymbols: [
{
provider: '',
symbol: '',
},
],
ticker: '',
description: '',
image: {
b64: ''
},
},
trade: {
conviction: 100,
direction: '',
},
notes: {
commentary: '',
},
},
pricing: {
provider: '',
credentials: {
key: '',
secret: '',
},
},
}
Create Idea Request
A retry mechanism can be useful to ensure that the process completes successfully.
let validError = false;
data = await Helpers.retryFunctionHelper({
maxRetries: 3,
retryCallback: async () => {
let dt: v4.IdeaCreationResult;
if (!validError) {
dt = await activ.createIdea(newIdea);
}
return dt;
},
notificationCallback: async (error: string, retryIndex: number) => {
// if error
if (error.includes('is already opened in this strategy')) {
validError = true;
} else if (error.includes('is duplicated in the strategy')) {
validError = true;
}
log({
message: `[createActivIdeaInStrategy] Error creating Activ Idea (retry ${retryIndex}): ${error}`,
type: 'error',
});
}
});
-------
// Helper file
export const retryFunctionHelper = async <T>(payload: {
maxRetries: number,
retryCallback: (retryIndex: number) => Promise<any>,
notificationCallback?: (errMsg: string, retryCount: number) => Promise<any>,
rejectOnMaxRetries?: boolean,
}) => {
let retryCount = 1;
// this is the function that will be called to notify the caller of the error
// using slack or email or whatever instead of throwing an error
const notify = async (errMsg: string, retryCount: number) => {
try {
if (payload?.notificationCallback) {
await payload.notificationCallback(errMsg, retryCount);
}
} catch (err) {
console.log('retryFunctionHelper [Error notifying]', `${err?.message}. Retry #${retryCount}`);
}
}
try {
const { maxRetries, retryCallback } = payload;
while (retryCount <= maxRetries) {
try {
const data = await retryCallback(retryCount);
if (data) {
return data as T;
} else {
await notify('No data returned', retryCount);
}
} catch (err) {
await notify(err?.message || 'Unknown error', retryCount);
// optionally reject on max retries
if (payload?.rejectOnMaxRetries && retryCount === payload.maxRetries) {
throw new Error(err?.message || 'Unknown error');
}
}
if (retryCount < maxRetries) {
// await 5 second before retrying
await wait(5000);
}
retryCount++;
}
return null;
} catch (err) {
await notify(err?.message || 'Unknown error', retryCount);
// optionally reject on max retries
if (payload?.rejectOnMaxRetries && retryCount === payload.maxRetries) {
throw new Error(err?.message || 'Unknown error');
}
}
}
Last updated