Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ dist
.vscode
logs
.idea/
docker-compose-local-MINE.yml
8 changes: 5 additions & 3 deletions index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ console.log(' -> Database URI ' + hiddenDatabaseURI)
let tradenoteDatabase = process.env.TRADENOTE_DATABASE

var app = express();
app.use(express.json());
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));

const port = process.env.TRADENOTE_PORT;
const PROXY_PORT = 39482;
Expand Down Expand Up @@ -339,7 +340,8 @@ const setupApiRoutes = (app) => {



app.use(express.json());
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ limit: '50mb', extended: true }));

let allUsers
const getAllUsers = async () => {
Expand Down Expand Up @@ -498,7 +500,7 @@ const startIndex = async () => {
resolve();
} else {
// In production, handle API routes normally
app.use('/api/*', express.json(), (req, res, next) => {
app.use('/api/*', express.json({ limit: '50mb' }), express.urlencoded({ limit: '50mb', extended: true }), (req, res, next) => {
//console.log(`Received API request: ${req.method} ${req.url}`);
next(); // Pass control to specific API handlers
});
Expand Down
60 changes: 60 additions & 0 deletions patch-timezones.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from pathlib import Path
import re

file_path = Path("src/stores/globals.js")

main_timezones = [
"America/New_York",
"America/Los_Angeles",
"America/Chicago",
"America/Denver",
"America/Phoenix",
"America/Anchorage",
"Pacific/Honolulu",
"America/Toronto",
"America/Vancouver",
"America/Mexico_City",
"America/Sao_Paulo",
"UTC",
"Europe/London",
"Europe/Dublin",
"Europe/Brussels",
"Europe/Paris",
"Europe/Berlin",
"Europe/Madrid",
"Europe/Rome",
"Europe/Amsterdam",
"Europe/Zurich",
"Europe/Stockholm",
"Europe/Warsaw",
"Europe/Moscow",
"Asia/Riyadh",
"Asia/Dubai",
"Asia/Kolkata",
"Asia/Bangkok",
"Asia/Singapore",
"Asia/Shanghai",
"Asia/Hong_Kong",
"Asia/Tokyo",
"Asia/Seoul",
"Australia/Sydney",
"Australia/Melbourne",
"Pacific/Auckland",
]

s = file_path.read_text()

new_line = 'export const timeZones = ref(' + repr(main_timezones).replace("'", '"') + ')'

s2, n = re.subn(
r'export const timeZones = ref\(\[[^\]]*\]\)',
new_line,
s,
count=1,
)

if n != 1:
raise SystemExit("Could not find timeZones array in src/stores/globals.js")

file_path.write_text(s2)
print("Updated timeZones in", file_path)
2 changes: 1 addition & 1 deletion src/stores/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const registerOff = ref(false)
export const parseId = ref()
export const pageId = ref()
export const currentUser = ref()
export const timeZones = ref(["America/New_York", "Asia/Shanghai", "Europe/Brussels", "Asia/Tokyo", "Asia/Hong_Kong", "Asia/Kolkata", "Europe/London", "Asia/Riyadh"])
export const timeZones = ref(["America/New_York", "America/Los_Angeles", "America/Chicago", "America/Denver", "America/Phoenix", "America/Anchorage", "Pacific/Honolulu", "America/Toronto", "America/Vancouver", "America/Mexico_City", "America/Sao_Paulo", "UTC", "Europe/London", "Europe/Dublin", "Europe/Brussels", "Europe/Paris", "Europe/Berlin", "Europe/Madrid", "Europe/Rome", "Europe/Amsterdam", "Europe/Zurich", "Europe/Stockholm", "Europe/Warsaw", "Europe/Moscow", "Asia/Riyadh", "Asia/Dubai", "Asia/Kolkata", "Asia/Bangkok", "Asia/Singapore", "Asia/Shanghai", "Asia/Hong_Kong", "Asia/Tokyo", "Asia/Seoul", "Australia/Sydney", "Australia/Melbourne", "Pacific/Auckland"])
export const timeZoneTrade = ref()
export const queryLimit = ref(10000000)
export const queryLimitExistingTrades = ref(50)
Expand Down
8 changes: 4 additions & 4 deletions src/utils/daily.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ export const useUpdateTags = async () => {
query.equalTo("tradeId", tradeTagsId.value)
} else {
//it's the case when changing daily tags, tradeTagsId.value is null (see useTradeTagsChange)
query.equalTo("tradeId", tradeTagsDateUnix.value.toString())
query.equalTo("tradeId", (tradeTagsDateUnix.value || screenshot.dateUnix || screenshot.dateUnixDay || screenshot.name || Date.now()).toString())
}
}
const results = await query.first();
Expand Down Expand Up @@ -578,12 +578,12 @@ export const useUpdateTags = async () => {
}
else {
if (tradeTagsId.value) {
object.set("dateUnix", tradeTagsDateUnix.value)
object.set("dateUnix", tradeTagsDateUnix.value || screenshot.dateUnix || screenshot.dateUnixDay || Date.now())
object.set("tradeId", tradeTagsId.value)
} else {
//it's the case when changing daily tags, tradeTagsId.value is null
object.set("dateUnix", tradeTagsDateUnix.value)
object.set("tradeId", tradeTagsDateUnix.value.toString())
object.set("dateUnix", tradeTagsDateUnix.value || screenshot.dateUnix || screenshot.dateUnixDay || Date.now())
object.set("tradeId", (tradeTagsDateUnix.value || screenshot.dateUnix || screenshot.dateUnixDay || screenshot.name || Date.now()).toString())
}

}
Expand Down
6 changes: 4 additions & 2 deletions src/utils/screenshots.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ async function imgFileReader(param) {
})
}

export async function useSetupImageUpload(event, param1, param2, param3) {
export async function useSetupImageUpload(event, param1, param2, param3, tradeId = null) {
tradeScreenshotChanged.value = true
if (pageId.value == "daily") {
saveButton.value = true
Expand All @@ -191,6 +191,8 @@ export async function useSetupImageUpload(event, param1, param2, param3) {
screenshot.dateUnix = param1
screenshot.symbol = param2
screenshot.side = param3
screenshot.tradeId = tradeId
screenshot.objectId = undefined

}
const file = event.target.files[0];
Expand Down Expand Up @@ -429,7 +431,7 @@ export async function useSaveScreenshot() {
//console.log(" -> dateUnix " + screenshot.dateUnix)


screenshot.side ? screenshot.name = "t" + screenshot.dateUnix + "_" + screenshot.symbol + "_" + screenshot.side : screenshot.name = screenshot.dateUnix + "_" + screenshot.symbol
screenshot.tradeId ? screenshot.name = screenshot.tradeId : (screenshot.side ? screenshot.name = "t" + screenshot.dateUnix + "_" + screenshot.symbol + "_" + screenshot.side : screenshot.name = screenshot.dateUnix + "_" + screenshot.symbol)
//console.log("name " + screenshot.name)


Expand Down
46 changes: 39 additions & 7 deletions src/views/Daily.vue
Original file line number Diff line number Diff line change
Expand Up @@ -212,19 +212,21 @@ async function clickTradesModal(param1, param2, param3) {
await Promise.all([resetExcursion(), useResetTags()])

//For setups I have added setups into filteredTrades. For screenshots and excursions I need to find so I create on each modal page a screenshot and excursion object
let findScreenshot = screenshots.find(obj => obj.name == filteredTradeId)
let findScreenshots = screenshots.filter(obj => obj.name == filteredTradeId)
for (let key in screenshot) delete screenshot[key]
candlestickChartFailureMessage.value = null // to avoid message when screenshot is present

if (findScreenshot) {
if (findScreenshots.length > 0) {
//console.log(" found screenshot")
for (let key in findScreenshot) {
screenshot[key] = findScreenshot[key]
screenshot.multiple = findScreenshots
for (let key in findScreenshots[0]) {
screenshot[key] = findScreenshots[0][key]
}
} else {
//console.log(" did not find any screenshot")
screenshot.side = null
screenshot.type = null
screenshot.multiple = []

/* GET OHLC / CANDLESTICK CHARTS */

Expand Down Expand Up @@ -948,6 +950,9 @@ function getOHLC(date, symbol, type) {
</th>
<th scope="col">Position</th>
<th scope="col">Entry</th>
<th scope="col">Entry Price</th>
<th scope="col">Exit</th>
<th scope="col">Exit Price</th>
<th scope="col">P&L/Sec<i class="ps-1 uil uil-info-circle"
data-bs-toggle="tooltip"
data-bs-title="Profit&Loss per unit of security traded (baught or shorted)"></i>
Expand Down Expand Up @@ -1002,6 +1007,31 @@ function getOHLC(date, symbol, type) {
v-bind:data-bs-title="'Swing trade from ' + useDateCalFormat(trade.entryTime)"></i></span></span>
</td>

<!--Entry Price-->
<td><span v-if="trade.tradesCount == 0"></span><span
v-else-if="trade.type == 'forex'">{{
(trade.entryPrice).toFixed(5)
}}</span><span v-else>{{
useTwoDecCurrencyFormat(trade.entryPrice)
}}<span
v-if="checkDate(trade.td, trade.entryTime) == false"><i
class="ps-1 uil uil-info-circle"
data-bs-toggle="tooltip" data-bs-html="true"
v-bind:data-bs-title="'Swing trade from ' + useDateCalFormat(trade.entryTime)"></i></span></span>
</td>

<!--Exit-->
<td><span v-if="trade.tradesCount == 0"></span><span
v-else>{{ useTimeFormat(trade.exitTime) }}</span></td>

<!--Exit Price-->
<td><span v-if="trade.tradesCount == 0"></span><span
v-else-if="trade.type == 'forex'">{{
(trade.exitPrice).toFixed(5)
}}</span><span v-else>{{
useTwoDecCurrencyFormat(trade.exitPrice)
}}</span></td>

<!--P&L/Vol-->
<td>
<span v-if="trade.tradesCount == 0"></span><span
Expand Down Expand Up @@ -1162,8 +1192,10 @@ function getOHLC(date, symbol, type) {
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div v-if="modalDailyTradeOpen">
<div v-if="screenshot.originalBase64">
<Screenshot :screenshot-data="screenshot" source="dailyModal" />
<div v-if="screenshot.multiple && screenshot.multiple.length > 0">
<div v-for="itemScreenshot in screenshot.multiple" :key="itemScreenshot.objectId">
<Screenshot :screenshot-data="itemScreenshot" source="dailyModal" />
</div>
</div>
<div v-show="!candlestickChartFailureMessage && !screenshot.originalBase64" id="candlestickChart"
class="candlestickClass">
Expand Down Expand Up @@ -1368,7 +1400,7 @@ function getOHLC(date, symbol, type) {
<!-- Forth line -->
<div class="col-12 mt-3" v-show="!spinnerSetups">
<input class="screenshotFile" type="file"
@change="useSetupImageUpload($event, filteredTrades[itemTradeIndex].trades[tradeIndex].entryTime, filteredTrades[itemTradeIndex].trades[tradeIndex].symbol, filteredTrades[itemTradeIndex].trades[tradeIndex].side)" />
@change="useSetupImageUpload($event, filteredTrades[itemTradeIndex].trades[tradeIndex].entryTime, filteredTrades[itemTradeIndex].trades[tradeIndex].symbol, filteredTrades[itemTradeIndex].trades[tradeIndex].side, filteredTrades[itemTradeIndex].trades[tradeIndex].id)" />
</div>


Expand Down
22 changes: 19 additions & 3 deletions src/views/Settings.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup>
import { onBeforeMount, onMounted, reactive, ref } from 'vue';
import { useCheckCurrentUser, useInitTooltip, useGetAPIS, useGetLayoutStyle, useExport } from '../utils/utils';
import { currentUser, renderProfile, availableTags, apis, layoutStyle } from '../stores/globals';
import { currentUser, renderProfile, availableTags, apis, layoutStyle, timeZones } from '../stores/globals';
import { useGetAvailableTags } from '../utils/daily';

/* MODULES */
Expand Down Expand Up @@ -58,17 +58,20 @@ async function updateProfile() {
const query = new Parse.Query(parseObject);
query.equalTo("objectId", currentUser.value.objectId);
const results = await query.first();

if (results) {
if (profileAvatar != null) {
const parseFile = new Parse.File("avatar", profileAvatar);
results.set("avatar", parseFile)
}
await results.save().then(async () => { //very important to have await or else too quick to update

results.set("timeZone", currentUser.value.timeZone)

await results.save().then(async () => {
await useCheckCurrentUser()
await (renderProfile.value += 1)
console.log(" -> Profile updated")
})
//
} else {
alert("Update query did not return any results")
}
Expand Down Expand Up @@ -514,6 +517,19 @@ const updateAPIS = async () => {
</div>
</div>

<div class="row align-items-center mt-3">
<div class="col-12 col-md-4">
Timezone
</div>
<div class="col-12 col-md-8">
<select v-model="currentUser.timeZone" class="form-select">
<option v-for="item in timeZones" :key="item" :value="item">
{{ item }}
</option>
</select>
</div>
</div>

<div class="mt-3 mb-3">
<button type="button" v-on:click="updateProfile" class="btn btn-success">Save</button>
</div>
Expand Down