From a41d55338750b864ecf89a32d753b1fe8e9a23b3 Mon Sep 17 00:00:00 2001 From: nikolabjelo Date: Tue, 21 May 2019 17:49:02 +0200 Subject: [PATCH 1/2] Switching to trading protocol 0.1 --- .eslintrc.js | 1 + package-lock.json | 5 + package.json | 1 + src/models/Strategy.js | 351 ------------------ src/models/TradingSystem.js | 54 +++ src/models/index.js | 4 +- src/schema/mutations/CreateStrategy.js | 41 -- src/schema/mutations/CreateTradingSystem.js | 41 ++ src/schema/mutations/EditStrategy.js | 43 --- src/schema/mutations/EditTradingSystem.js | 43 +++ src/schema/mutations/index.js | 8 +- .../{StrategyByFB.js => TradingSystemByFB.js} | 16 +- src/schema/queries/index.js | 4 +- src/schema/types/Condition.js | 15 - src/schema/types/Phase.js | 25 -- src/schema/types/Situation.js | 24 -- src/schema/types/Strategy.js | 27 +- src/schema/types/SubStrategy.js | 67 ---- src/schema/types/TheSevenMonolitics.js | 113 ------ src/schema/types/TradingSystem.js | 31 ++ src/schema/types/index.js | 26 +- src/schema/types/input/Condition.js | 15 - src/schema/types/input/Phase.js | 18 - src/schema/types/input/Situation.js | 17 - src/schema/types/input/Strategy.js | 17 +- src/schema/types/input/SubStrategy.js | 32 -- src/schema/types/input/TheSevenMonolitics.js | 75 ---- src/schema/types/input/TradingSystem.js | 15 + src/schema/types/input/index.js | 26 +- src/templates/strategyTemplate.js | 259 ------------- src/templates/tradingSystemTemplate.js | 7 + 31 files changed, 239 insertions(+), 1182 deletions(-) delete mode 100644 src/models/Strategy.js create mode 100644 src/models/TradingSystem.js delete mode 100644 src/schema/mutations/CreateStrategy.js create mode 100644 src/schema/mutations/CreateTradingSystem.js delete mode 100644 src/schema/mutations/EditStrategy.js create mode 100644 src/schema/mutations/EditTradingSystem.js rename src/schema/queries/{StrategyByFB.js => TradingSystemByFB.js} (53%) delete mode 100644 src/schema/types/Condition.js delete mode 100644 src/schema/types/Phase.js delete mode 100644 src/schema/types/Situation.js delete mode 100644 src/schema/types/SubStrategy.js delete mode 100644 src/schema/types/TheSevenMonolitics.js create mode 100644 src/schema/types/TradingSystem.js delete mode 100644 src/schema/types/input/Condition.js delete mode 100644 src/schema/types/input/Phase.js delete mode 100644 src/schema/types/input/Situation.js delete mode 100644 src/schema/types/input/SubStrategy.js delete mode 100644 src/schema/types/input/TheSevenMonolitics.js create mode 100644 src/schema/types/input/TradingSystem.js delete mode 100644 src/templates/strategyTemplate.js create mode 100644 src/templates/tradingSystemTemplate.js diff --git a/.eslintrc.js b/.eslintrc.js index c06bffbce..93f90913a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,5 +5,6 @@ module.exports = { 'max-len': ['error', 140, 2], 'no-underscore-dangle': 'off', 'no-param-reassign': 'off', + 'import/no-cycle': 'off', } }; diff --git a/package-lock.json b/package-lock.json index 80cc95a42..db1d1bca1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3587,6 +3587,11 @@ "uuid": "^3.1.0" } }, + "graphql-type-json": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.0.tgz", + "integrity": "sha512-lnxg5HiB95yxy+/5cDKtP6pZo0zgntsOmqsjeCBXFGJ4YoMF3+1YaSEKWJntNTu+VsAm3zf6lPxFpp1kxzofLA==" + }, "graphql-upload": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-8.0.6.tgz", diff --git a/package.json b/package.json index 667c39594..c139ff155 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "dotenv": "^6.0.0", "express": "^4.16.3", "graphql": "^0.13.2", + "graphql-type-json": "^0.3.0", "mongoose": "^5.3.4" } } diff --git a/src/models/Strategy.js b/src/models/Strategy.js deleted file mode 100644 index e8116b208..000000000 --- a/src/models/Strategy.js +++ /dev/null @@ -1,351 +0,0 @@ -import mongoose, { Schema } from 'mongoose'; - -const strategySchema = new Schema( - { - fbSlug: { - type: String, - required: true, - unique: true, - dropDups: true, - }, - subStrategies: [{ - active: { - type: Boolean, - required: true, - default: true, - }, - name: { - type: String, - default: '', - }, - entryPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - exitPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - sellPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - buyPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - stopLoss: { - phases: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }], - }, - buyOrder: { - phases: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }], - }, - sellOrder: { - phases: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }], - }, - }], - history: [{ - updatedAt: Date, - subStrategies: [{ - name: { - type: String, - default: '', - }, - entryPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - exitPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - sellPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - buyPoint: { - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }, - stopLoss: { - phases: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }], - }, - buyOrder: { - phases: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }], - }, - sellOrder: { - phases: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - situations: [{ - name: { - type: String, - default: '', - }, - conditions: [{ - name: { - type: String, - default: '', - }, - code: { - type: String, - default: 'false', - }, - }], - }], - }], - }, - }], - }], - }, - { - timestamps: true, - }, -); - -const Strategy = mongoose.model('Strategy', strategySchema); - -export default Strategy; diff --git a/src/models/TradingSystem.js b/src/models/TradingSystem.js new file mode 100644 index 000000000..f6741e1a1 --- /dev/null +++ b/src/models/TradingSystem.js @@ -0,0 +1,54 @@ +import mongoose, { Schema } from 'mongoose'; + +const tradingSystemSchema = new Schema( + { + fbSlug: { + type: String, + required: true, + unique: true, + dropDups: true, + }, + strategies: [{ + active: { + type: Boolean, + required: true, + default: true, + }, + name: { + type: String, + default: '', + }, + filter: Object, + triggerStage: Object, + openStage: Object, + manageStage: Object, + closeStage: Object, + }], + history: [{ + updatedAt: Date, + strategies: [{ + active: { + type: Boolean, + required: true, + default: true, + }, + name: { + type: String, + default: '', + }, + filter: Object, + triggerStage: Object, + openStage: Object, + manageStage: Object, + closeStage: Object, + }], + }], + }, + { + timestamps: true, + }, +); + +const TradingSystem = mongoose.model('Signal', tradingSystemSchema); + +export default TradingSystem; diff --git a/src/models/index.js b/src/models/index.js index d3593c1da..3ea7d795c 100644 --- a/src/models/index.js +++ b/src/models/index.js @@ -1,6 +1,6 @@ /* eslint-disable import/prefer-default-export */ -import Strategy from './Strategy'; +import TradingSystem from './TradingSystem'; export { - Strategy, + TradingSystem, }; diff --git a/src/schema/mutations/CreateStrategy.js b/src/schema/mutations/CreateStrategy.js deleted file mode 100644 index 0ab2216a9..000000000 --- a/src/schema/mutations/CreateStrategy.js +++ /dev/null @@ -1,41 +0,0 @@ -import { - GraphQLNonNull, - GraphQLString, -} from 'graphql'; -import { StrategyType } from '../types'; -import { Strategy } from '../../models'; -import { StrategyInputType } from '../types/input'; -import defaultStrategy from '../../templates/strategyTemplate'; - -export const args = { - fbSlug: { type: new GraphQLNonNull(GraphQLString) }, - strategy: { type: StrategyInputType }, -}; - -const resolve = (parent, { fbSlug, strategy }) => { - if (strategy === undefined) { - strategy = defaultStrategy; - } - strategy.fbSlug = fbSlug; - const newStrategy = new Strategy(strategy); - - return new Promise((res, rej) => { - newStrategy.save((err) => { - if (err) { - rej(err); - return; - } - res(newStrategy); - }); - }); -}; - -const mutation = { - createStrategy: { - type: StrategyType, - args, - resolve, - }, -}; - -export default mutation; diff --git a/src/schema/mutations/CreateTradingSystem.js b/src/schema/mutations/CreateTradingSystem.js new file mode 100644 index 000000000..d94819943 --- /dev/null +++ b/src/schema/mutations/CreateTradingSystem.js @@ -0,0 +1,41 @@ +import { + GraphQLNonNull, + GraphQLString, +} from 'graphql'; +import { TradingSystemType } from '../types'; +import { TradingSystem } from '../../models'; +import { TradingSystemInputType } from '../types/input'; +import defaultTradingSystem from '../../templates/tradingSystemTemplate'; + +export const args = { + fbSlug: { type: new GraphQLNonNull(GraphQLString) }, + tradingSystem: { type: TradingSystemInputType }, +}; + +const resolve = (parent, { fbSlug, tradingSystem }) => { + if (tradingSystem === undefined) { + tradingSystem = defaultTradingSystem; + } + tradingSystem.fbSlug = fbSlug; + const newTradingSystem = new TradingSystem(tradingSystem); + + return new Promise((res, rej) => { + newTradingSystem.save((err) => { + if (err) { + rej(err); + return; + } + res(newTradingSystem); + }); + }); +}; + +const mutation = { + createTradingSystem: { + type: TradingSystemType, + args, + resolve, + }, +}; + +export default mutation; diff --git a/src/schema/mutations/EditStrategy.js b/src/schema/mutations/EditStrategy.js deleted file mode 100644 index 8c864d537..000000000 --- a/src/schema/mutations/EditStrategy.js +++ /dev/null @@ -1,43 +0,0 @@ -import { - GraphQLNonNull, - GraphQLID, -} from 'graphql'; -import { StrategyType } from '../types'; -import { Strategy } from '../../models'; -import { StrategyInputType } from '../types/input'; - -const args = { - id: { type: new GraphQLNonNull(GraphQLID) }, - strategy: { type: new GraphQLNonNull(StrategyInputType) }, -}; - -const resolve = (parent, { id: _id, strategy: editedStrategy }) => new Promise((res, rej) => { - Strategy.findOne({ _id }).exec((err, strategy) => { - if (err) { - rej(err); - return; - } - strategy.history.push({ - updatedAt: strategy.updatedAt, - subStrategies: strategy.subStrategies, - }); - strategy.subStrategies = editedStrategy.subStrategies; - strategy.save((error) => { - if (error) { - rej(error); - return; - } - res(strategy); - }); - }); -}); - -const mutation = { - editStrategy: { - type: StrategyType, - args, - resolve, - }, -}; - -export default mutation; diff --git a/src/schema/mutations/EditTradingSystem.js b/src/schema/mutations/EditTradingSystem.js new file mode 100644 index 000000000..bb9b2235b --- /dev/null +++ b/src/schema/mutations/EditTradingSystem.js @@ -0,0 +1,43 @@ +import { + GraphQLNonNull, + GraphQLID, +} from 'graphql'; +import { TradingSystemType } from '../types'; +import { TradingSystem } from '../../models'; +import { TradingSystemInputType } from '../types/input'; + +const args = { + id: { type: new GraphQLNonNull(GraphQLID) }, + tradingSystem: { type: new GraphQLNonNull(TradingSystemInputType) }, +}; + +const resolve = (parent, { id: _id, tradingSystem: editedTradingSystem }) => new Promise((res, rej) => { + TradingSystem.findOne({ _id }).exec((err, tradingSystem) => { + if (err) { + rej(err); + return; + } + tradingSystem.history.push({ + updatedAt: tradingSystem.updatedAt, + subStrategies: tradingSystem.subStrategies, + }); + tradingSystem.subStrategies = editedTradingSystem.subStrategies; + tradingSystem.save((error) => { + if (error) { + rej(error); + return; + } + res(tradingSystem); + }); + }); +}); + +const mutation = { + editTradingSystem: { + type: TradingSystemType, + args, + resolve, + }, +}; + +export default mutation; diff --git a/src/schema/mutations/index.js b/src/schema/mutations/index.js index b5b401e8a..bfbd12119 100644 --- a/src/schema/mutations/index.js +++ b/src/schema/mutations/index.js @@ -2,14 +2,14 @@ import { GraphQLObjectType, } from 'graphql'; -import CreateStrategyMutation from './CreateStrategy'; -import EditStrategyMutation from './EditStrategy'; +import CreateTradingSystemMutation from './CreateTradingSystem'; +import EditTradingSystemMutation from './EditTradingSystem'; const Mutation = new GraphQLObjectType({ name: 'Mutation', fields: Object.assign( - CreateStrategyMutation, - EditStrategyMutation, + CreateTradingSystemMutation, + EditTradingSystemMutation, ), }); diff --git a/src/schema/queries/StrategyByFB.js b/src/schema/queries/TradingSystemByFB.js similarity index 53% rename from src/schema/queries/StrategyByFB.js rename to src/schema/queries/TradingSystemByFB.js index 03b4005a1..3bbfdd4e8 100644 --- a/src/schema/queries/StrategyByFB.js +++ b/src/schema/queries/TradingSystemByFB.js @@ -3,30 +3,30 @@ import { GraphQLString, } from 'graphql'; import { DatabaseError } from '../../errors'; -import { StrategyType } from '../types'; -import { Strategy } from '../../models'; +import { TradingSystemType } from '../types'; +import { TradingSystem } from '../../models'; const args = { fbSlug: { type: new GraphQLNonNull(GraphQLString) }, }; const resolve = (parent, { fbSlug }) => new Promise((res, rej) => { - Strategy.findOne({ fbSlug }).exec((err, strategy) => { + TradingSystem.findOne({ fbSlug }).exec((err, tradingSystem) => { if (err) { rej(err); return; } - if (!strategy) { - rej(new DatabaseError('None of the strategy are linked to that fbSlug')); + if (!tradingSystem) { + rej(new DatabaseError('None of the tradingSystem are linked to that fbSlug')); return; } - res(strategy); + res(tradingSystem); }); }); const query = { - strategyByFb: { - type: StrategyType, + tradingSystemByFb: { + type: TradingSystemType, args, resolve, }, diff --git a/src/schema/queries/index.js b/src/schema/queries/index.js index dcb6a77a5..aed625e49 100644 --- a/src/schema/queries/index.js +++ b/src/schema/queries/index.js @@ -2,12 +2,12 @@ import { GraphQLObjectType, } from 'graphql'; -import StrategyByFbQuery from './StrategyByFB'; +import TradingSystemByFbQuery from './TradingSystemByFB'; const RootQuery = new GraphQLObjectType({ name: 'RootQueryType', fields: Object.assign( - StrategyByFbQuery, + TradingSystemByFbQuery, ), }); diff --git a/src/schema/types/Condition.js b/src/schema/types/Condition.js deleted file mode 100644 index 6634a2df9..000000000 --- a/src/schema/types/Condition.js +++ /dev/null @@ -1,15 +0,0 @@ -import { - GraphQLObjectType, - GraphQLString, -} from 'graphql'; - -const Type = new GraphQLObjectType({ - name: 'Condition', - description: 'Condition definition', - fields: () => ({ - name: { type: GraphQLString }, - code: { type: GraphQLString }, - }), -}); - -export default Type; diff --git a/src/schema/types/Phase.js b/src/schema/types/Phase.js deleted file mode 100644 index 603efe9d1..000000000 --- a/src/schema/types/Phase.js +++ /dev/null @@ -1,25 +0,0 @@ -import { - GraphQLObjectType, - GraphQLString, - GraphQLList, -} from 'graphql'; -import { - SituationType, -} from './index'; - -const Type = new GraphQLObjectType({ - name: 'Phase', - description: 'Phase definition', - fields: () => ({ - name: { type: GraphQLString }, - code: { type: GraphQLString }, - situations: { - type: new GraphQLList(SituationType), - resolve(parent) { - return parent.situations; - }, - }, - }), -}); - -export default Type; diff --git a/src/schema/types/Situation.js b/src/schema/types/Situation.js deleted file mode 100644 index 5b74f7f56..000000000 --- a/src/schema/types/Situation.js +++ /dev/null @@ -1,24 +0,0 @@ -import { - GraphQLObjectType, - GraphQLString, - GraphQLList, -} from 'graphql'; -import { - ConditionType, -} from './index'; - -const Type = new GraphQLObjectType({ - name: 'Situation', - description: 'Situation definition', - fields: () => ({ - name: { type: GraphQLString }, - conditions: { - type: new GraphQLList(ConditionType), - resolve(parent) { - return parent.conditions; - }, - }, - }), -}); - -export default Type; diff --git a/src/schema/types/Strategy.js b/src/schema/types/Strategy.js index 034d8bcd7..3b9245c74 100644 --- a/src/schema/types/Strategy.js +++ b/src/schema/types/Strategy.js @@ -1,30 +1,21 @@ import { GraphQLObjectType, GraphQLString, - GraphQLList, GraphQLBoolean, - GraphQLID, } from 'graphql'; -import { - SubStrategyType, -} from './index'; +import GraphQLJSON from 'graphql-type-json'; const Type = new GraphQLObjectType({ name: 'Strategy', - description: 'Everything you need to know about a strategy', + description: 'Strategy composing a trading system', fields: () => ({ - id: { type: GraphQLID }, - fbSlug: { type: GraphQLString }, - subStrategies: { - args: { activeOnly: { type: GraphQLBoolean } }, - type: new GraphQLList(SubStrategyType), - resolve(parent, { activeOnly }) { - if (activeOnly) { - return parent.subStrategies.filter(subStrategy => subStrategy.active); - } - return parent.subStrategies; - }, - }, + active: { type: GraphQLBoolean }, + name: { type: GraphQLString }, + filter: { type: GraphQLJSON }, + triggerStage: { type: GraphQLJSON }, + openStage: { type: GraphQLJSON }, + manageStage: { type: GraphQLJSON }, + closeStage: { type: GraphQLJSON }, }), }); diff --git a/src/schema/types/SubStrategy.js b/src/schema/types/SubStrategy.js deleted file mode 100644 index 7facc4dc4..000000000 --- a/src/schema/types/SubStrategy.js +++ /dev/null @@ -1,67 +0,0 @@ -import { - GraphQLObjectType, - GraphQLString, - GraphQLBoolean, -} from 'graphql'; -import { - EntryPointType, - ExitPointType, - SellPointType, - BuyPointType, - StopLossType, - BuyOrderType, - SellOrderType, -} from './index'; - -const Type = new GraphQLObjectType({ - name: 'SubStrategy', - description: 'SubStrategy composing a strategy', - fields: () => ({ - active: { type: GraphQLBoolean }, - name: { type: GraphQLString }, - entryPoint: { - type: EntryPointType, - resolve(parent) { - return parent.entryPoint; - }, - }, - exitPoint: { - type: ExitPointType, - resolve(parent) { - return parent.exitPoint; - }, - }, - sellPoint: { - type: SellPointType, - resolve(parent) { - return parent.sellPoint; - }, - }, - buyPoint: { - type: BuyPointType, - resolve(parent) { - return parent.buyPoint; - }, - }, - stopLoss: { - type: StopLossType, - resolve(parent) { - return parent.stopLoss; - }, - }, - buyOrder: { - type: BuyOrderType, - resolve(parent) { - return parent.buyOrder; - }, - }, - sellOrder: { - type: SellOrderType, - resolve(parent) { - return parent.sellOrder; - }, - }, - }), -}); - -export default Type; diff --git a/src/schema/types/TheSevenMonolitics.js b/src/schema/types/TheSevenMonolitics.js deleted file mode 100644 index 3d08d4acf..000000000 --- a/src/schema/types/TheSevenMonolitics.js +++ /dev/null @@ -1,113 +0,0 @@ -import { - GraphQLObjectType, - GraphQLList, -} from 'graphql'; -import { - SituationType, - PhaseType, -} from './index'; - -// SituationBased - -const EntryPointType = new GraphQLObjectType({ - name: 'EntryPoint', - description: 'EntryPoint definition', - fields: () => ({ - situations: { - type: new GraphQLList(SituationType), - resolve(parent) { - return parent.situations; - }, - }, - }), -}); - -const ExitPointType = new GraphQLObjectType({ - name: 'ExitPoint', - description: 'ExitPoint definition', - fields: () => ({ - situations: { - type: new GraphQLList(SituationType), - resolve(parent) { - return parent.situations; - }, - }, - }), -}); - -const SellPointType = new GraphQLObjectType({ - name: 'SellPoint', - description: 'SellPoint definition', - fields: () => ({ - situations: { - type: new GraphQLList(SituationType), - resolve(parent) { - return parent.situations; - }, - }, - }), -}); - -const BuyPointType = new GraphQLObjectType({ - name: 'BuyPoint', - description: 'BuyPoint definition', - fields: () => ({ - situations: { - type: new GraphQLList(SituationType), - resolve(parent) { - return parent.situations; - }, - }, - }), -}); - -// PhaseBased - -const StopLossType = new GraphQLObjectType({ - name: 'StopLoss', - description: 'StopLoss definition', - fields: () => ({ - phases: { - type: new GraphQLList(PhaseType), - resolve(parent) { - return parent.phases; - }, - }, - }), -}); - -const BuyOrderType = new GraphQLObjectType({ - name: 'BuyOrder', - description: 'BuyOrder definition', - fields: () => ({ - phases: { - type: new GraphQLList(PhaseType), - resolve(parent) { - return parent.phases; - }, - }, - }), -}); - -const SellOrderType = new GraphQLObjectType({ - name: 'SellOrder', - description: 'SellOrder definition', - fields: () => ({ - phases: { - type: new GraphQLList(PhaseType), - resolve(parent) { - return parent.phases; - }, - }, - }), -}); - -export { - EntryPointType, - ExitPointType, - SellPointType, - BuyPointType, - StopLossType, - BuyOrderType, - SellOrderType, -}; diff --git a/src/schema/types/TradingSystem.js b/src/schema/types/TradingSystem.js new file mode 100644 index 000000000..1c8d8a632 --- /dev/null +++ b/src/schema/types/TradingSystem.js @@ -0,0 +1,31 @@ +import { + GraphQLObjectType, + GraphQLString, + GraphQLList, + GraphQLBoolean, + GraphQLID, +} from 'graphql'; +import { + StrategyType, +} from './index'; + +const Type = new GraphQLObjectType({ + name: 'TradingSystem', + description: 'Everything you need to know about a trading system', + fields: () => ({ + id: { type: GraphQLID }, + fbSlug: { type: GraphQLString }, + Strategies: { + args: { activeOnly: { type: GraphQLBoolean } }, + type: new GraphQLList(StrategyType), + resolve(parent, { activeOnly }) { + if (activeOnly) { + return parent.Strategies.filter(Strategy => Strategy.active); + } + return parent.Strategies; + }, + }, + }), +}); + +export default Type; diff --git a/src/schema/types/index.js b/src/schema/types/index.js index 87d2fface..af93e80f4 100644 --- a/src/schema/types/index.js +++ b/src/schema/types/index.js @@ -1,29 +1,7 @@ +import TradingSystemType from './TradingSystem'; import StrategyType from './Strategy'; -import SubStrategyType from './SubStrategy'; -import ConditionType from './Condition'; -import SituationType from './Situation'; -import PhaseType from './Phase'; -import { - EntryPointType, - ExitPointType, - SellPointType, - BuyPointType, - StopLossType, - BuyOrderType, - SellOrderType, -} from './TheSevenMonolitics'; export { StrategyType, - SubStrategyType, - ConditionType, - SituationType, - PhaseType, - EntryPointType, - ExitPointType, - SellPointType, - BuyPointType, - StopLossType, - BuyOrderType, - SellOrderType, + TradingSystemType, }; diff --git a/src/schema/types/input/Condition.js b/src/schema/types/input/Condition.js deleted file mode 100644 index a6271162a..000000000 --- a/src/schema/types/input/Condition.js +++ /dev/null @@ -1,15 +0,0 @@ -import { - GraphQLString, - GraphQLInputObjectType, -} from 'graphql'; - -const Type = new GraphQLInputObjectType({ - name: 'ConditionInput', - description: 'Payload for condition input', - fields: () => ({ - name: { type: GraphQLString }, - code: { type: GraphQLString }, - }), -}); - -export default Type; diff --git a/src/schema/types/input/Phase.js b/src/schema/types/input/Phase.js deleted file mode 100644 index 81b50757e..000000000 --- a/src/schema/types/input/Phase.js +++ /dev/null @@ -1,18 +0,0 @@ -import { - GraphQLString, - GraphQLInputObjectType, - GraphQLList, -} from 'graphql'; -import { SituationInputType } from './index'; - -const Type = new GraphQLInputObjectType({ - name: 'PhaseInput', - description: 'Payload for phase input', - fields: () => ({ - name: { type: GraphQLString }, - code: { type: GraphQLString }, - situations: { type: new GraphQLList(SituationInputType) }, - }), -}); - -export default Type; diff --git a/src/schema/types/input/Situation.js b/src/schema/types/input/Situation.js deleted file mode 100644 index 673881bee..000000000 --- a/src/schema/types/input/Situation.js +++ /dev/null @@ -1,17 +0,0 @@ -import { - GraphQLString, - GraphQLInputObjectType, - GraphQLList, -} from 'graphql'; -import { ConditionInputType } from './index'; - -const Type = new GraphQLInputObjectType({ - name: 'SituationInput', - description: 'Payload for situation input', - fields: () => ({ - name: { type: GraphQLString }, - conditions: { type: new GraphQLList(ConditionInputType) }, - }), -}); - -export default Type; diff --git a/src/schema/types/input/Strategy.js b/src/schema/types/input/Strategy.js index d4ca64c05..f5b89261d 100644 --- a/src/schema/types/input/Strategy.js +++ b/src/schema/types/input/Strategy.js @@ -1,14 +1,21 @@ import { + GraphQLString, + GraphQLBoolean, GraphQLInputObjectType, - GraphQLList, } from 'graphql'; -import { SubStrategyInputType } from './index'; +import GraphQLJSON from 'graphql-type-json'; const Type = new GraphQLInputObjectType({ - name: 'StrategyInput', - description: 'Payload for strategy input', + name: 'SubStrategyInput', + description: 'Payload for subStrategy input', fields: () => ({ - subStrategies: { type: new GraphQLList(SubStrategyInputType) }, + active: { type: GraphQLBoolean }, + name: { type: GraphQLString }, + filter: { type: GraphQLJSON }, + triggerStage: { type: GraphQLJSON }, + openStage: { type: GraphQLJSON }, + manageStage: { type: GraphQLJSON }, + closeStage: { type: GraphQLJSON }, }), }); diff --git a/src/schema/types/input/SubStrategy.js b/src/schema/types/input/SubStrategy.js deleted file mode 100644 index 08a56e37b..000000000 --- a/src/schema/types/input/SubStrategy.js +++ /dev/null @@ -1,32 +0,0 @@ -import { - GraphQLString, - GraphQLBoolean, - GraphQLInputObjectType, -} from 'graphql'; -import { - EntryPointInputType, - ExitPointInputType, - SellPointInputType, - BuyPointInputType, - StopLossInputType, - BuyOrderInputType, - SellOrderInputType, -} from './index'; - -const Type = new GraphQLInputObjectType({ - name: 'SubStrategyInput', - description: 'Payload for subStrategy input', - fields: () => ({ - active: { type: GraphQLBoolean }, - name: { type: GraphQLString }, - entryPoint: { type: EntryPointInputType }, - exitPoint: { type: ExitPointInputType }, - sellPoint: { type: SellPointInputType }, - buyPoint: { type: BuyPointInputType }, - stopLoss: { type: StopLossInputType }, - buyOrder: { type: BuyOrderInputType }, - sellOrder: { type: SellOrderInputType }, - }), -}); - -export default Type; diff --git a/src/schema/types/input/TheSevenMonolitics.js b/src/schema/types/input/TheSevenMonolitics.js deleted file mode 100644 index 8a6b3ba37..000000000 --- a/src/schema/types/input/TheSevenMonolitics.js +++ /dev/null @@ -1,75 +0,0 @@ -import { - GraphQLInputObjectType, - GraphQLList, -} from 'graphql'; -import { SituationInputType, PhaseInputType } from './index'; - -// SituationBased - -const EntryPointInputType = new GraphQLInputObjectType({ - name: 'EntryPointInput', - description: 'Payload for entryPoint input', - fields: () => ({ - situations: { type: new GraphQLList(SituationInputType) }, - }), -}); - -const ExitPointInputType = new GraphQLInputObjectType({ - name: 'ExitPointInput', - description: 'Payload for exitPoint input', - fields: () => ({ - situations: { type: new GraphQLList(SituationInputType) }, - }), -}); - -const SellPointInputType = new GraphQLInputObjectType({ - name: 'SellPointInput', - description: 'Payload for sellPoint input', - fields: () => ({ - situations: { type: new GraphQLList(SituationInputType) }, - }), -}); - -const BuyPointInputType = new GraphQLInputObjectType({ - name: 'BuyPointInput', - description: 'Payload for buyPoint input', - fields: () => ({ - situations: { type: new GraphQLList(SituationInputType) }, - }), -}); - -// PhaseBased - -const StopLossInputType = new GraphQLInputObjectType({ - name: 'StopLossTypeInput', - description: 'Payload for stopLossType input', - fields: () => ({ - phases: { type: new GraphQLList(PhaseInputType) }, - }), -}); - -const BuyOrderInputType = new GraphQLInputObjectType({ - name: 'BuyOrderTypeInput', - description: 'Payload for buyOrderType input', - fields: () => ({ - phases: { type: new GraphQLList(PhaseInputType) }, - }), -}); - -const SellOrderInputType = new GraphQLInputObjectType({ - name: 'SellOrderTypeInput', - description: 'Payload for sellOrderType input', - fields: () => ({ - phases: { type: new GraphQLList(PhaseInputType) }, - }), -}); - -export { - EntryPointInputType, - ExitPointInputType, - SellPointInputType, - BuyPointInputType, - StopLossInputType, - BuyOrderInputType, - SellOrderInputType, -}; diff --git a/src/schema/types/input/TradingSystem.js b/src/schema/types/input/TradingSystem.js new file mode 100644 index 000000000..ed69ebe2a --- /dev/null +++ b/src/schema/types/input/TradingSystem.js @@ -0,0 +1,15 @@ +import { + GraphQLInputObjectType, + GraphQLList, +} from 'graphql'; +import { StrategyInputType } from './index'; + +const Type = new GraphQLInputObjectType({ + name: 'TradingSystemInput', + description: 'Payload for trading system input', + fields: () => ({ + strategies: { type: new GraphQLList(StrategyInputType) }, + }), +}); + +export default Type; diff --git a/src/schema/types/input/index.js b/src/schema/types/input/index.js index 8472b9cfd..690768a68 100644 --- a/src/schema/types/input/index.js +++ b/src/schema/types/input/index.js @@ -1,29 +1,7 @@ +import TradingSystemInputType from './TradingSystem'; import StrategyInputType from './Strategy'; -import SubStrategyInputType from './SubStrategy'; -import ConditionInputType from './Condition'; -import SituationInputType from './Situation'; -import PhaseInputType from './Phase'; -import { - EntryPointInputType, - ExitPointInputType, - SellPointInputType, - BuyPointInputType, - StopLossInputType, - BuyOrderInputType, - SellOrderInputType, -} from './TheSevenMonolitics'; export { + TradingSystemInputType, StrategyInputType, - SubStrategyInputType, - ConditionInputType, - SituationInputType, - PhaseInputType, - EntryPointInputType, - ExitPointInputType, - SellPointInputType, - BuyPointInputType, - StopLossInputType, - BuyOrderInputType, - SellOrderInputType, }; diff --git a/src/templates/strategyTemplate.js b/src/templates/strategyTemplate.js deleted file mode 100644 index ae2118e48..000000000 --- a/src/templates/strategyTemplate.js +++ /dev/null @@ -1,259 +0,0 @@ -/* eslint-disable max-len */ -const strategy = { - subStrategies: [ - { - active: true, - name: 'Trend Following', - entryPoint: { - situations: [ - { - name: 'Price Collapsing', - conditions: [ - { - name: '%B Moving Average going down', - code: "percentageBandwidth.previous.direction === 'down' && percentageBandwidth.direction === 'down'", - }, - { - name: '%B Bandwidth going up', - code: 'percentageBandwidth.previous.previous.bandwidth < percentageBandwidth.previous.bandwidth && percentageBandwidth.previous.bandwidth < percentageBandwidth.bandwidth', - }, - { - name: 'Candles Min going down', - code: 'candle.previous.previous.min > candle.previous.min && candle.previous.min > candle.min', - }, - ], - }, - ], - }, - exitPoint: { - situations: [ - { - name: 'Market Reversing', - conditions: [ - { - name: 'Close above Band Moving Average', - code: 'candle.close > bollingerBand.movingAverage', - }, - ], - }, - ], - }, - sellPoint: { - situations: [ - { - name: 'Min below lower bollingerBand.', - conditions: [ - { - name: '3 Candles MIN below Lower Band', - code: 'candle.previous.previous.min < bollingerBand.previous.previous.movingAverage - bollingerBand.previous.previous.deviation && candle.previous.min < bollingerBand.previous.movingAverage - bollingerBand.previous.deviation && candle.min < bollingerBand.movingAverage - bollingerBand.deviation', - }, - ], - }, - ], - }, - stopLoss: { - phases: [ - { - name: 'Following Sell Rate', - code: 'newStopLoss = sellRate + sellRate * (stopLossPercentage - stopLossDecay) / 100', - situations: [ - { - name: 'Candle below Moving Average', - conditions: [ - { - name: 'Candle fully below Band Moving Average', - code: 'candle.max < bollingerBand.movingAverage', - }, - { - name: 'Band Moving Average going down', - code: "bollingerBand.direction === 'down'", - }, - ], - }, - ], - }, - { - name: 'Above Bands Moving Average', - code: 'newStopLoss = bollingerBand.movingAverage + bollingerBand.movingAverage * (stopLossPercentage - stopLossDecay) / 100', - situations: [ - { - name: 'Candle below Moving Average', - conditions: [ - { - name: 'Candle MAX below lower band', - code: 'candle.max < bollingerBand.movingAverage - bollingerBand.deviation', - }, - ], - }, - ], - }, - { - name: 'At Bands Moving Average', - code: 'newStopLoss = bollingerBand.movingAverage', - situations: [], - }, - ], - }, - buyOrder: { - phases: [ - { - name: '12 times standard deviation', - code: 'buyOrder = bollingerBand.movingAverage - bollingerBand.standardDeviation * 12', - situations: [ - { - name: 'Candle cut by lower band', - conditions: [ - { - name: 'Max above lower band', - code: 'candle.max > bollingerBand.movingAverage - bollingerBand.deviation', - }, - { - name: 'MIN below lower band', - code: 'candle.min < bollingerBand.movingAverage - bollingerBand.deviation', - }, - { - name: 'Band Moving Average going down', - code: 'bollingerBand.previous.movingAverage > bollingerBand.movingAverage', - }, - ], - }, - ], - }, - { - name: '10 times standard deviation', - code: 'buyOrder = bollingerBand.movingAverage - bollingerBand.standardDeviation * 10', - situations: [ - { - name: '%B starting to revert', - conditions: [ - { - name: '%B Moving Average going up', - code: "percentageBandwidth.direction === 'up'", - }, - { - name: '%B Moving Average above 0', - code: 'percentageBandwidth.movingAverage > 0', - }, - ], - }, - ], - }, - { - name: '4 times standard deviation', - code: 'buyOrder = bollingerBand.movingAverage - bollingerBand.standardDeviation * 4', - situations: [ - { - name: '%B going down again', - conditions: [ - { - name: '%B Moving Average going down', - code: "percentageBandwidth.direction === 'down'", - }, - ], - }, - ], - }, - { - name: '3 times standard deviation', - code: 'buyOrder = bollingerBand.movingAverage - bollingerBand.standardDeviation * 3', - situations: [ - { - name: '%B going up and above 30', - conditions: [ - { - name: '%B Moving Average going up', - code: "percentageBandwidth.direction === 'up'", - }, - { - name: '%B Moving Average above 30', - code: 'percentageBandwidth.movingAverage > 30', - }, - ], - }, - ], - }, - { - name: 'At lower band', - code: 'buyOrder = bollingerBand.movingAverage - bollingerBand.standardDeviation * 2', - situations: [], - }, - ], - }, - }, - { - active: true, - name: 'Range Trading', - entryPoint: { - situations: [ - { - name: 'Gentle Up Trend', - conditions: [ - { - name: 'Sub-Channel going up', - code: "subChannel.direction === 'up'", - }, - { - name: 'Sub-Channel Side|Gentle|Medium', - code: "subChannel.slope === 'Side' || subChannel.slope === 'Gentle' || subChannel.slope === 'Medium'", - }, - { - name: 'Candle Close above Lower Band', - code: 'candle.close > bollingerBand.movingAverage + bollingerBand.deviation', - }, - ], - }, - ], - }, - exitPoint: { - situations: [ - { - name: 'Outside Sub-Channel', - conditions: [ - { - name: 'Going down or too Steep', - code: "subChannel.direction === 'Down' || subChannel.slope === 'Steep' || subChannel.slope === 'Extreme'", - }, - ], - }, - ], - }, - sellPoint: { - situations: [ - { - name: 'Min below lower bollingerBand.', - conditions: [ - { - name: '%B Moving Average going down', - code: 'percentageBandwidth.previous.movingAverage > percentageBandwidth.movingAverage', - }, - { - name: '%B Moving Average above 90', - code: 'percentageBandwidth.previous.movingAverage > 90', - }, - ], - }, - ], - }, - stopLoss: { - phases: [ - { - name: 'Following Sell Rate', - code: 'newStopLoss = sellRate + sellRate * (stopLossPercentage - stopLossDecay) / 100', - situations: [], - }, - ], - }, - buyOrder: { - phases: [ - { - name: 'Between Band Moving Average and Lower Band', - code: 'buyOrder = bollingerBand.movingAverage - bollingerBand.standardDeviation', - situations: [], - }, - ], - }, - }, - ], -}; - -export default strategy; diff --git a/src/templates/tradingSystemTemplate.js b/src/templates/tradingSystemTemplate.js new file mode 100644 index 000000000..23036cd02 --- /dev/null +++ b/src/templates/tradingSystemTemplate.js @@ -0,0 +1,7 @@ +/* eslint-disable max-len */ +const tradingSystem = { + strategies: [ + ], +}; + +export default tradingSystem; From 39f3071d2d8ae274eb266e469c38ff078eb6b1c5 Mon Sep 17 00:00:00 2001 From: nikolabjelo Date: Tue, 21 May 2019 18:05:31 +0200 Subject: [PATCH 2/2] Correcting bugs and linting --- src/db.js | 2 +- src/errors/index.js | 4 ++++ src/models/TradingSystem.js | 2 +- src/schema/mutations/EditTradingSystem.js | 4 ++-- src/schema/types/TradingSystem.js | 6 +++--- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/db.js b/src/db.js index e08de13f5..8f7d6a6cd 100644 --- a/src/db.js +++ b/src/db.js @@ -1,7 +1,7 @@ import 'dotenv/config'; import mongoose from 'mongoose'; -mongoose.connect(process.env.MONGO_URL, { useNewUrlParser: true }) +mongoose.connect(process.env.MONGO_URL, { useNewUrlParser: true }); mongoose.set('useCreateIndex', true); mongoose.set('useFindAndModify', false); mongoose.Promise = global.Promise; diff --git a/src/errors/index.js b/src/errors/index.js index 3cf8868b4..d97fc3ec5 100644 --- a/src/errors/index.js +++ b/src/errors/index.js @@ -1,19 +1,23 @@ export class AuthentificationError extends Error { code = 401 + message = 'Autentification not found, you have to be authentificated to perform this action' } export class DatabaseError extends Error { code = 404 + message = `Ressource not found : ${this.message}` } export class WrongArgumentsError extends Error { code = 400 + message = `Wrong arguments : ${this.message}` } export class ServiceUnavailableError extends Error { code = 503 + message = `At least one service is unresponding ${this.message}` } diff --git a/src/models/TradingSystem.js b/src/models/TradingSystem.js index f6741e1a1..88be8294d 100644 --- a/src/models/TradingSystem.js +++ b/src/models/TradingSystem.js @@ -49,6 +49,6 @@ const tradingSystemSchema = new Schema( }, ); -const TradingSystem = mongoose.model('Signal', tradingSystemSchema); +const TradingSystem = mongoose.model('TradingSystem', tradingSystemSchema); export default TradingSystem; diff --git a/src/schema/mutations/EditTradingSystem.js b/src/schema/mutations/EditTradingSystem.js index bb9b2235b..e9c03de06 100644 --- a/src/schema/mutations/EditTradingSystem.js +++ b/src/schema/mutations/EditTradingSystem.js @@ -19,9 +19,9 @@ const resolve = (parent, { id: _id, tradingSystem: editedTradingSystem }) => new } tradingSystem.history.push({ updatedAt: tradingSystem.updatedAt, - subStrategies: tradingSystem.subStrategies, + strategies: tradingSystem.strategies, }); - tradingSystem.subStrategies = editedTradingSystem.subStrategies; + tradingSystem.strategies = editedTradingSystem.strategies; tradingSystem.save((error) => { if (error) { rej(error); diff --git a/src/schema/types/TradingSystem.js b/src/schema/types/TradingSystem.js index 1c8d8a632..18d843c74 100644 --- a/src/schema/types/TradingSystem.js +++ b/src/schema/types/TradingSystem.js @@ -15,14 +15,14 @@ const Type = new GraphQLObjectType({ fields: () => ({ id: { type: GraphQLID }, fbSlug: { type: GraphQLString }, - Strategies: { + strategies: { args: { activeOnly: { type: GraphQLBoolean } }, type: new GraphQLList(StrategyType), resolve(parent, { activeOnly }) { if (activeOnly) { - return parent.Strategies.filter(Strategy => Strategy.active); + return parent.strategies.filter(strategy => strategy.active); } - return parent.Strategies; + return parent.strategies; }, }, }),