Skip to content

Commit

Permalink
180 iterate on buy/sale logic (#186)
Browse files Browse the repository at this point in the history
* PlaceOrderButton: Prevent action on disabled btn

* tradesMeta: make comments into doc comments

* Add alpaca-ts (Alpaca TS client)

* Remove price-range check for buy orders

Handled in alpaca with limit rules, and if needed should be set from UI when creating the order

* api/broker/orders: cleanup

* tradesHandler: Refactor triggerUpdateOpenBuyOrders

* tradesHandler: only clear BUY trades

* helpers: Add isValidSymbol

* Fix sell logic to put sell orders correctly

Also fixes some other minor problems, naming, etc.

* Change buy breakout order to use stop order

* getTradesByStatus: Add support for multiple statuses

* Update take partial profit check

Only perform once, then revert to regular stop-loss procedure

* tradesHandler: Add stop-loss case (2), isToday check (closes #185)
  • Loading branch information
mold authored Jan 20, 2023
1 parent b1bead5 commit ae12b52
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 233 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"typescript": "4.8.4"
},
"dependencies": {
"@master-chief/alpaca": "^6.3.20",
"@polygon.io/client-js": "^6.0.6",
"@sentry/nextjs": "^7.20.0",
"@types/node-fetch": "^2.6.2",
Expand All @@ -55,4 +56,4 @@
"usehooks-ts": "^2.9.1",
"zustand": "^4.1.4"
}
}
}
6 changes: 5 additions & 1 deletion src/components/molecules/PlaceOrderButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,18 @@ const PlaceOrderButton = ({
<StyledButton
disabled={disabled}
onClick={() => {
if (disabled) {
return;
}

setDisabled(true);
upsertTrade(ticker, {
ticker,
breakoutRef,
status: TRADE_STATUS.READY,
side: TRADE_SIDE.BUY,
});
/* Note: rn this will not place an actual order. See /api/broker/orders */

void handleBuyOrder(ticker, buyPrice, quantity, breakoutRef);
typeof onClick === "function" && onClick();
}}
Expand Down
4 changes: 2 additions & 2 deletions src/db/tradesEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ export async function deleteTrade(ref: string) {
return;
}

export async function getTradesByStatus(status: TRADE_STATUS) {
export async function getTradesByStatus(...status: TRADE_STATUS[]) {
const query = db.collection("trades");
const results = await query.where("status", "==", status).get();
const results = await query.where("status", "in", status).get();
if (results.size === 0) {
return [];
}
Expand Down
35 changes: 28 additions & 7 deletions src/db/tradesMeta.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
// These are also mapped all the way to lowercased and sent to alpacaca (as prop "side")
/**
* These are also mapped all the way to lowercased and sent to alpacaca
* (as prop "side")
*/
export enum TRADE_SIDE {
BUY = "BUY",
SELL = "SELL",
}

export enum TRADE_STATUS {
READY = "READY", // not even sent to Alpaca yet
ACTIVE = "ACTIVE", // not filled yet
PARTIALLY_FILLED = "PARTIALLY_FILLED", // not totally filled yet
FILLED = "FILLED", // "buy" or "sell" type process, should now be concidered done
/** not even sent to Alpaca yet */
READY = "READY",

/** not filled yet; can be cancelled or dead for some other reason in Alpaca */
ACTIVE = "ACTIVE",

/** not totally filled yet */
PARTIALLY_FILLED = "PARTIALLY_FILLED",

/** "buy" or "sell" type process, should now be concidered done */
FILLED = "FILLED",
OPEN = "OPEN",
CLOSED = "CLOSED",
CANCELLED = "CANCELLED",
TAKE_PROFIT = "TAKE PROFIT", // order is filled and later resulted in a take-profit order.

/** order is filled and later resulted in a take-profit order. */
TAKE_PROFIT = "TAKE PROFIT",

// TODO: use these
/** order is filled and later resulted in a stop-loss (1) order. */
STOP_LOSS_1 = "STOP_LOSS_1",
/** order is filled and later resulted in a stop-loss (2) order. */
STOP_LOSS_2 = "STOP_LOSS_2",
/** order is filled and later resulted in a take partial profit order. */
TAKE_PARTIAL_PROFIT = "TAKE_PARTIAL_PROFIT",
}

export interface TradesDataType {
Expand All @@ -22,7 +42,8 @@ export interface TradesDataType {
price: number;
quantity: number;
created: number;
breakoutRef: string; // Important! Used as _ref
/** Important! Used as _ref */
breakoutRef: string;
alpacaOrderId?: string;
userRef?: string;
}
Expand Down
9 changes: 9 additions & 0 deletions src/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,12 @@ export const getNewRunId = () => {
nowHours,
)}${addZero(nowMinutes)}${addZero(nowSeconds)}`;
};

export function isValidSymbol(symbol: string): boolean {
return Boolean(
symbol &&
typeof symbol === "string" &&
symbol.length >= 1 &&
symbol.length <= 5,
);
}
Loading

0 comments on commit ae12b52

Please sign in to comment.