Skip to content
This repository was archived by the owner on Feb 22, 2024. It is now read-only.

Commit 953bae4

Browse files
committed
Refactor Proposal.js
1 parent ed26161 commit 953bae4

File tree

2 files changed

+74
-82
lines changed

2 files changed

+74
-82
lines changed

src/botPage/bot/TradeEngine/Proposal.js

Lines changed: 72 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,43 @@ export default Engine =>
99
if (!this.isNewTradeOption(tradeOption)) {
1010
return;
1111
}
12+
13+
// Generate a purchase reference when trade options are different from previous trade options.
14+
// This will ensure the bot doesn't mistakenly purchase the wrong proposal.
15+
this.regeneratePurchaseReference();
1216
this.tradeOption = tradeOption;
13-
this.proposalTemplates = tradeOptionToProposal(tradeOption);
17+
this.proposalTemplates = tradeOptionToProposal(tradeOption, this.getPurchaseReference());
1418
this.renewProposalsOnPurchase();
1519
}
1620
selectProposal(contractType) {
17-
let toBuy;
21+
const { proposals } = this.data;
1822

19-
if (!this.data.has('proposals')) {
23+
if (proposals.length === 0) {
2024
throw Error(translate('Proposals are not ready'));
2125
}
2226

23-
this.data.get('proposals').forEach(proposal => {
24-
if (proposal.contractType === contractType) {
27+
const toBuy = proposals.find(proposal => {
28+
if (
29+
proposal.contractType === contractType &&
30+
proposal.purchaseReference === this.getPurchaseReference()
31+
) {
2532
if (proposal.error) {
26-
const { error } = proposal.error;
27-
throw new TrackJSError(error.error.code, error.error.message, error);
28-
} else {
29-
toBuy = proposal;
33+
const { error } = proposal.error.error;
34+
const { code, message } = error;
35+
throw new TrackJSError(code, message, error);
3036
}
37+
38+
return proposal;
3139
}
40+
41+
return false;
3242
});
3343

3444
if (!toBuy) {
3545
throw new TrackJSError(
3646
'CustomInvalidProposal',
3747
translate('Selected proposal does not exist'),
38-
Array.from(this.data.get('proposals')).map(proposal => proposal[1])
48+
this.data.proposals
3949
);
4050
}
4151

@@ -48,93 +58,73 @@ export default Engine =>
4858
this.unsubscribeProposals().then(() => this.requestProposals());
4959
}
5060
clearProposals() {
51-
this.data = this.data.set('proposals', new Map());
61+
this.data.proposals = [];
5262
this.store.dispatch(clearProposals());
5363
}
5464
requestProposals() {
5565
Promise.all(
5666
this.proposalTemplates.map(proposal =>
57-
doUntilDone(() =>
58-
this.api.subscribeToPriceForContractProposal(proposal).catch(e => {
59-
if (e && e.name === 'RateLimit') {
60-
throw e;
61-
}
62-
63-
const errorCode = e.error && e.error.error && e.error.error.code;
64-
65-
if (errorCode === 'ContractBuyValidationError') {
66-
const { uuid } = e.error.echo_req.passthrough;
67-
68-
if (!this.data.hasIn(['forgetProposals', uuid])) {
69-
// Add to proposals map with error. Will later be shown to user, see selectProposal.
70-
this.data = this.data.setIn(['proposals', uuid], {
71-
...proposal,
72-
...proposal.passthrough,
73-
error: e,
74-
});
75-
}
76-
77-
return null;
78-
}
79-
80-
throw e;
81-
})
82-
)
67+
doUntilDone(() => this.api.subscribeToPriceForContractProposal(proposal))
8368
)
8469
).catch(e => this.$scope.observer.emit('Error', e));
8570
}
8671
observeProposals() {
87-
this.listen('proposal', r => {
88-
const { proposal, passthrough } = r;
89-
const id = passthrough.uuid;
90-
91-
if (!this.data.hasIn(['forgetProposals', id])) {
92-
this.data = this.data.setIn(['proposals', id], {
93-
...proposal,
94-
...passthrough,
95-
});
72+
this.listen('proposal', response => {
73+
const { passthrough, proposal } = response;
74+
75+
if (
76+
this.data.proposals.findIndex(p => p.id === proposal.id) === -1 &&
77+
!this.data.forgetProposals.includes(proposal.id)
78+
) {
79+
// Add proposals based on the ID returned by the API.
80+
this.data.proposals.push({ ...proposal, ...passthrough });
9681
this.checkProposalReady();
9782
}
9883
});
9984
}
10085
unsubscribeProposals() {
101-
const proposalObj = this.data.get('proposals');
102-
103-
if (!proposalObj) {
104-
return Promise.resolve();
105-
}
106-
107-
const proposals = Array.from(proposalObj.values());
86+
const { proposals } = this.data;
87+
const removeForgetProposalById = forgetProposalId => {
88+
this.data.forgetProposals = this.data.forgetProposals.filter(id => id !== forgetProposalId);
89+
};
10890

10991
this.clearProposals();
11092

11193
return Promise.all(
11294
proposals.map(proposal => {
113-
const { uuid: id } = proposal;
114-
const removeProposal = () => {
115-
this.data = this.data.deleteIn(['forgetProposals', id]);
116-
};
117-
118-
this.data = this.data.setIn(['forgetProposals', id], true);
95+
if (!this.data.forgetProposals.includes(proposal.id)) {
96+
this.data.forgetProposals.push(proposal.id);
97+
}
11998

12099
if (proposal.error) {
121-
removeProposal();
100+
removeForgetProposalById(proposal.id);
122101
return Promise.resolve();
123102
}
124103

125-
return doUntilDone(() => this.api.unsubscribeByID(proposal.id)).then(() => removeProposal());
104+
return doUntilDone(() => this.api.unsubscribeByID(proposal.id)).then(() =>
105+
removeForgetProposalById(proposal.id)
106+
);
126107
})
127108
);
128109
}
129110
checkProposalReady() {
130-
const proposals = this.data.get('proposals');
131-
132-
if (proposals && proposals.size === this.proposalTemplates.length) {
133-
const isSameWithTemplate = this.proposalTemplates.every(p =>
134-
this.data.hasIn(['proposals', p.passthrough.uuid])
135-
);
136-
137-
if (isSameWithTemplate) {
111+
// Proposals are considered ready when the proposals in our memory match the ones
112+
// we've requested from the API, we determine this by checking the passthrough of the response.
113+
const { proposals } = this.data;
114+
115+
if (proposals.length > 0) {
116+
const hasEqualLength = proposals.length === this.proposalTemplates.length;
117+
const hasEqualProposals = () =>
118+
this.proposalTemplates.every(
119+
template =>
120+
proposals.findIndex(
121+
proposal =>
122+
proposal.purchaseReference === template.passthrough.purchaseReference &&
123+
proposal.contractType === template.contract_type
124+
) !== -1
125+
);
126+
127+
if (hasEqualLength && hasEqualProposals()) {
138128
this.startPromise.then(() => this.store.dispatch(proposalsReady()));
139129
}
140130
}
@@ -145,16 +135,18 @@ export default Engine =>
145135
return true;
146136
}
147137

148-
const isNotEqual = key => this.tradeOption[key] !== tradeOption[key];
149-
150-
return (
151-
isNotEqual('duration') ||
152-
isNotEqual('duration_unit') ||
153-
isNotEqual('amount') ||
154-
isNotEqual('prediction') ||
155-
isNotEqual('barrierOffset') ||
156-
isNotEqual('secondBarrierOffset') ||
157-
isNotEqual('symbol')
158-
);
138+
// Compare incoming "tradeOption" argument with "this.tradeOption", if any
139+
// of the values is different, this is a new tradeOption and new proposals
140+
// should be generated.
141+
return [
142+
'amount',
143+
'barrierOffset',
144+
'basis',
145+
'duration',
146+
'duration_unit',
147+
'prediction',
148+
'secondBarrierOffset',
149+
'symbol',
150+
].some(value => this.tradeOption[value] !== tradeOption[value]);
159151
}
160152
};

src/botPage/bot/tools.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { notify } from './broadcast';
55

66
export const noop = () => {};
77

8-
export const tradeOptionToProposal = tradeOption =>
8+
export const tradeOptionToProposal = (tradeOption, purchaseReference) =>
99
tradeOption.contractTypes.map(type => {
1010
const proposal = {
1111
duration_unit: tradeOption.duration_unit,
@@ -17,7 +17,7 @@ export const tradeOptionToProposal = tradeOption =>
1717
contract_type: type,
1818
passthrough : {
1919
contractType: type,
20-
uuid : getUUID(),
20+
purchaseReference,
2121
},
2222
};
2323
if (tradeOption.prediction !== undefined) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy