Skip to content

Commit

Permalink
fixed bankroll calculations, improved readability of the formulas
Browse files Browse the repository at this point in the history
- position already included on_orders, fixed this across the app.
- added additional global values under metrics for total bank, available bank, and in orders to prevent calculating on the component level.
- reworded some items to be a bit cleaner.
- activeSum now is totalBoughtVolume
- added formulas and known issues
  • Loading branch information
coltoneshaw committed Jul 30, 2021
1 parent 97e47af commit 359d021
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 56 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules/
node/
/node_modules
src/main-app.js
dist/*
dist/*
/src/main-app.js
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
v0.0.2-RC1

- Fixed issue where the data table hid the overflow and prevented scrolling. Will need further improvements for responsiveness.
- Added alerts when making changes to the settings page to inform you of a needed refresh
- Alternating colors on the data table
- try/catch block to the data functions so it properly changes the state of the spinner
- conditional routing rules based on if API keys are set up or not.
- Spinning icons when the data is updating.
- Added a rough description of API key perms needed to the settings page
- Increased pie chart size (praise), added formatting to the tooltips
- fixed application height issues
- settings button height, and scrolling on that page.

v0.0.1-RC1
- added spinner to the update data icons
- added description of API keys
- modified the chart to show thousands
- application height issues resolved
- settings button height has been updated

v0.0.1
- implemented and tested the mac dmg installer
- moved files from public into the src
- moved asset files around
- fixed a bug in the lenght of the name array for filters causing an error
- added columns to the bots table
21 changes: 21 additions & 0 deletions FORMULA_DESCRIPTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## Bank Roll Calculations

### Total Bankroll
Formula:
`Total Bankroll = Position ( Funds in that currency ) + funds currently in deals`

Additional information:
- What is in position?
- Position is a sum of what you have in active deals + what you have in available funds. This
- Why doesn't it match exactly to my crypto account?
- Your crypto account also takes into account any coins that you hold that are not a part of your DCA bots. For example, if you've made a smart trade, holding coins, etc.
- Additionally, the data from your crypto account to 3Commas is not always up to date, there may be slight variances in the numbers. But you should see within 1-4% the number is right.

### Bankroll Available:
Formula:
` ( 1 - ( ( funds currently in deals ) / ( Total Bankroll )) ) * 100 = remaining bankroll percent`


Additional information:
- This takes into account all the bankroll you have for the selected currency and gives the percent remaining after you remove what's on an order plus funds in a deal.
- This is calculated within the `calculateMetrics` inside `DataContext.js`
6 changes: 6 additions & 0 deletions KNOWNISSUES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

- when you save config settings it does not auto start to sync. You have to manually start it.
- scroll bars on the bot manager table can be weird. Resize to a bigger window for now.
- dark mode isn't built yet, but the button is there
- the Trading View tab may require a refresh to show. Somethign is weird with that
- active deals on stats is just a blank page, you're not crazy
2 changes: 1 addition & 1 deletion src/Components/Charts/Bar/SoDistribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class SoDistribution extends PureComponent {
const MaxSO = Math.max( ...data.map( deal => deal.completed_safety_orders_count ))
const soNumbers = Array.from(Array(MaxSO + 1).keys())
const totalDeals = data.length
const totalDealFunds = metrics.activeSum
const totalDealFunds = metrics.totalBoughtVolume

dataArray = soNumbers.map(SO => {
let matchingDeals = data.filter( deal => deal.completed_safety_orders_count === SO)
Expand Down
13 changes: 7 additions & 6 deletions src/Components/Charts/Pie/BalancePie.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@ class BalancePie extends PureComponent {

render() {
const { title, balance, metrics } = this.props
console.log(metrics)

const { availableBankroll, position, totalBoughtVolume, on_orders } = metrics
const chartData = [{
name: 'Available',
metric: parseInt(balance.position - balance.on_orders),
metric: parseInt( availableBankroll ),
key: 1
},
{
name: 'On Orders',
metric: parseInt(balance.on_orders),
name: 'Limit Orders',
metric: parseInt( on_orders ),
key: 2
},
{
name: "In Deals",
metric: parseInt(metrics.activeSum),
name: "Purchased",
metric: parseInt(totalBoughtVolume),
key: 3
}

Expand Down
2 changes: 1 addition & 1 deletion src/Components/Pages/BotManager/BotManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const BotManagerPage = (props) => {

return (
<>
<h1>Bot Manager</h1>
<h1>Bot Planner</h1>
<div className="flex-row padding">
<Button
variant="outlined"
Expand Down
8 changes: 4 additions & 4 deletions src/Components/Pages/BotManager/Risk.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useGlobalData } from '../../../Context/DataContext';
const Risk = ({ localBotData }) => {

const state = useGlobalData();
const { data: { metricsData: { sum } } } = state;
const { data: { metricsData: { totalBankroll } } } = state;

/**
* Bankroll - sum, on_orders, position all added together. Needs to come from global state most likely.
Expand All @@ -27,7 +27,7 @@ const Risk = ({ localBotData }) => {
let maxDCA = (enabledDeals.length > 0) ? enabledDeals.map(deal => deal.max_funds).reduce((sum, max) => sum + max) : 0;


let bankroll = sum
let bankroll = totalBankroll
let risk = (maxDCA / bankroll) * 100
let botCount = localBotData.filter(deal => deal.is_enabled).length

Expand All @@ -36,8 +36,8 @@ const Risk = ({ localBotData }) => {

const metricData = [
{
title: "Bank Roll",
metric: "$" + parseNumber(bankroll),
title: "Total Bank Roll",
metric: "$" + parseNumber(totalBankroll),
key: 1
},
{
Expand Down
52 changes: 35 additions & 17 deletions src/Components/Pages/Settings/StatSettings/AccountDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import {
Select
} from '@material-ui/core';

import Checkbox from '@material-ui/core/Checkbox';
import ListItemText from '@material-ui/core/ListItemText';
import Input from '@material-ui/core/Input';

import { accountDataAll } from '../../../../utils/3Commas';
import { useGlobalState } from '../../../../Context/Config';
import { defaultConfig } from '../../../../utils/defaultConfig';
Expand All @@ -22,13 +26,22 @@ const findData = (config, path) => {
}

// initializing a state for each of the two props that we are using.

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};



const AccountDropdown = () => {
const state = useGlobalState()
const { config, state: { accountID, updateAccountID }} = state;
const { config, state: { accountID, updateAccountID } } = state;


/**
Expand All @@ -51,17 +64,13 @@ const AccountDropdown = () => {
}, [])

useEffect(() => {
// let defaultAccountID = findData(config, accountIdPath)

// if(defaultAccountID == "" && accountData.length > 0){
// selectElement( accountData[0].account_id )
// } else {
selectElement(findData(config, accountIdPath))
//


selectElement([findData(config, accountIdPath)])

}, [config])

const [select, selectElement ] = useState(() => accountID)
// const [select, selectElement] = useState(() => accountID)
const [select, selectElement] = useState([])


// changing the select value
Expand All @@ -71,19 +80,28 @@ const AccountDropdown = () => {
console.log('changing the default account ID')
};


return (
<FormControl >
<InputLabel>Account Filter</InputLabel>


<Select
multiple
value={select}
onChange={handleChange}
// inputRef={accountIDPicker}
input={<Input />}
renderValue={() => (accountData.length > 0) ? accountData.filter(e => select.includes(e.account_id)).map(e => e.account_name).join(', ') : ""}
MenuProps={MenuProps}
>
<MenuItem value=""></MenuItem>

{/* Add filter here that if it's an array of 1 or the value is not defined in the config then we just pick accounts[0] */}
{accountData.map(a => <MenuItem value={a.account_id} key={a.account_id}>{a.account_name}</MenuItem>)}

{/* Need to think through All because it's now a selector. */}
{/* <MenuItem value=""></MenuItem> */}
{accountData.map((account) => (
<MenuItem key={account.account_id} value={account.account_id}>
<Checkbox checked={select.indexOf(account.account_id) > -1} />
<ListItemText primary={account.account_name} />
</MenuItem>
))}
</Select>
</FormControl>
)
Expand Down
8 changes: 4 additions & 4 deletions src/Components/Pages/Stats/Stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const StatsPage = () => {
const state = useGlobalData()
const { data :{metricsData, accountData, isSyncing }, actions: {updateAllData, refreshData} } = state

const { activeDealCount, activeSum, maxRisk, position, on_orders, totalProfit } = metricsData
const { activeDealCount, totalInDeals, maxRisk,totalBankroll, position, on_orders, totalProfit, sum } = metricsData

const [currentView, changeView] = useState('summary-stats')
const date = dotProp.get(config, 'statSettings.startDate')
Expand Down Expand Up @@ -120,7 +120,7 @@ const StatsPage = () => {
{
buttonElements.map(button => {
if (button.id === currentView) return <Button onClick={() => viewChanger(button.id)} color="primary" >{button.name}</Button>
return <Button onClick={() => viewChanger(button.id)} >{button.name}</Button>
return <Button key={button.id} onClick={() => viewChanger(button.id)} >{button.name}</Button>

})
}
Expand All @@ -135,9 +135,9 @@ const StatsPage = () => {

<div className="riskDiv">
<Card title="Active Deals" metric={activeDealCount} />
<Card title="$ In Deals" metric={"$" + parseNumber(activeSum)} />
<Card title="Total in Deals" metric={"$" + parseNumber(totalInDeals)} />
<Card title="DCA Max" metric={"$" + parseNumber(maxRisk)} />
<Card title="Remaining Bankroll" metric={"$" + parseNumber((position - on_orders))} />
<Card title="Total Bankroll" metric={"$" + parseNumber( totalBankroll ) } />
<Card title="Total Profit" metric={"$" + parseNumber(totalProfit)} />
</div>

Expand Down
8 changes: 2 additions & 6 deletions src/Components/Pages/Stats/Views/RiskMonitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@ const RiskMonitor = () => {
return (
<>
<SpeedometerDiv
metrics={{
maxRiskPercent: metricsData.maxRiskPercent,
bankrollAvailable: metricsData.bankrollAvailable,
activeSum: metricsData.activeSum
}}
balance={balanceData}
metrics={metricsData}
balance={balanceData}
/>
<Grid item xs={12}>
<DealSoUtalizationBar data={activeDeals} title="Current Deal SO Utalization" />
Expand Down
4 changes: 2 additions & 2 deletions src/Components/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ class Sidebar extends Component {
return (
<div id="sidebar">
<div className="flex-column sidebar-column">
<SidebarOption Icon={BotManagerIcon} name="Bot Manager" link="/botmanager" />
<SidebarOption Icon={BotManagerIcon} name="Bot Planner" link="/botmanager" />
<SidebarOption Icon={PieChart} name="Stats" link="/stats" />
<SidebarOption Icon={BackwardClock} name="Backtesting" link="/backtesting" />
<SidebarOption Icon={BackwardClock} name="Trading View" link="/backtesting" />
</div>
<div className="flex-column sidebar-column" style={{justifyContent: 'flex-end'}}>
<SidebarOption Icon={Coffee} name="Donate" link="/donate" />
Expand Down
42 changes: 32 additions & 10 deletions src/Context/DataContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ const defaultBalance = {
}

const defaultMetrics = {
activeSum: 0,
totalBoughtVolume: 0,
maxRisk: 0,
totalProfit: 0,
maxRiskPercent: 0,
bankrollAvailable: 0
bankrollAvailable: 0,
totalBankroll: 0
}

/**
Expand Down Expand Up @@ -84,7 +85,7 @@ const DataProvider = ({ children }) => {
*/
useEffect(() => {
calculateMetrics()
}, [metricsData.sum, metricsData.activeSum, metricsData.maxRisk])
}, [metricsData.sum, metricsData.totalBoughtVolume, metricsData.maxRisk])


const fetchBotData = async () => {
Expand Down Expand Up @@ -146,7 +147,7 @@ const DataProvider = ({ children }) => {
}

/**
* @metrics - activeSum, maxRisk, activeDealCount
* @metrics - totalBoughtVolume, maxRisk, activeDealCount
* @data - active deals, entire array returned by 3C
* Confirmed working
*/
Expand Down Expand Up @@ -209,20 +210,41 @@ const DataProvider = ({ children }) => {
}


/**
* maxRisk - Active deals max risk total. This comes from the deals endpoint. 3Commas.js / getActiveDealsFunction()
* sum - ((balanceData.on_orders + balanceData.position + balanceData.on_orders)) - this comes from the accounts endpoint.
* totalBoughtVolume - Active Deals bot volume total.
*
* postition - this includes what's on orders!!!!!
*/
const calculateMetrics = () => {
updateMetricsData(prevState => {
const { maxRisk, sum, activeSum } = prevState
console.log(prevState)
const { maxRisk, sum, totalBoughtVolume, position, on_orders } = prevState

// Position = available + on orders.
const totalBankroll = parseInt( position + totalBoughtVolume )
const availableBankroll = parseInt( position - on_orders)
const totalInDeals = on_orders + totalBoughtVolume

console.log({
maxRiskPercent: ((parseInt(maxRisk) / (parseInt(sum) + parseInt(activeSum))) * 100).toFixed(0),
bankrollAvailable: ((parseInt(sum) / (parseInt(sum) + parseInt(activeSum))) * 100).toFixed(0)
maxRiskPercent: parseInt((( maxRisk / totalBankroll ) * 100).toFixed(0)),
bankrollAvailable: parseInt( (( 1 - (( totalInDeals ) / totalBankroll ) ) * 100 ).toFixed(0) ),
totalBankroll,
availableBankroll,
prevState,
totalInDeals
})

// active sum already includes on_orders.


return {
...prevState,
maxRiskPercent: parseInt(((parseInt(maxRisk) / (parseInt(sum) + parseInt(activeSum))) * 100).toFixed(0)),
bankrollAvailable: parseInt(((parseInt(sum) / (parseInt(sum) + parseInt(activeSum))) * 100).toFixed(0))
maxRiskPercent: parseInt(((maxRisk / totalBankroll ) * 100).toFixed(0)),
bankrollAvailable: parseInt( (( 1 - (( totalInDeals ) / totalBankroll ) ) * 100 ).toFixed(0) ),
totalBankroll,
availableBankroll,
totalInDeals
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Bot Portfolio Manager</title>
<title>3C Bot Portfolio Manager</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Loading

0 comments on commit 359d021

Please sign in to comment.