-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
70 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { useCounterParty, useSeriesMap, useSimplePositionManager } from "@libs"; | ||
|
||
// Shannon's re-balance strategy | ||
export default () => { | ||
// Define parameters of the agent | ||
const datasource_id = useParamString('DataSource', 'Y'); | ||
const product_id = useParamString('Product'); | ||
const period = useParamString('Period', 'PT1H'); | ||
// Get the product information and price data | ||
const product = useProduct(datasource_id, product_id); | ||
const { close } = useOHLC(datasource_id, product_id, period); | ||
// More parameters | ||
const initial_balance = useParamNumber('Initial Balance', 100_000); | ||
const threshold = useParamNumber('Threshold', 1); | ||
// Get the account information | ||
const accountInfo = useAccountInfo(); | ||
// Use a simple position manager | ||
const [actualVolume, setVolume] = useSimplePositionManager(accountInfo.account_id, product_id); | ||
// Re-balance the position | ||
useEffect(() => { | ||
if (close.length < 2) return; | ||
const price = close[close.length - 1]; | ||
const totalValue = accountInfo.money.equity + initial_balance; | ||
const totalValueToHold = totalValue * 0.5; | ||
// infer the volume to hold | ||
const valuePerVolume = | ||
price * (product.value_speed ?? 1) * (product.is_underlying_base_currency ? -1 / price : 1); | ||
const expectedVolume = totalValueToHold / valuePerVolume; | ||
// calculate the error rate | ||
const volume_step = product.volume_step ?? 1; | ||
const errorRate = Math.abs((actualVolume - expectedVolume) / volume_step); | ||
if (errorRate > threshold) { | ||
setVolume(roundToStep(expectedVolume, volume_step)); | ||
} | ||
}, [close.length]); | ||
// Advanced: Visualize the equity and margin | ||
useSeriesMap( | ||
"Equity", | ||
close, | ||
{ display: "line", chart: "new" }, | ||
() => accountInfo.money.equity | ||
); | ||
useSeriesMap( | ||
"Margin", | ||
close, | ||
{ display: "line", chart: "new" }, | ||
() => accountInfo.money.used | ||
); | ||
// Advanced: use counter-party to show if we take the opposite position | ||
useCounterParty(accountInfo.account_id); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters